/*
 =======================================================================================
  Name        : DlgObtai.cpp
 
  Author      : vincent lhullier            Date :28/08/97
 
  Description : implementation file for obtain dialog box
 =======================================================================================
  Modification -> Author :                  Date :
  Description :
 =======================================================================================
 */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#include "stdafx.h"
#include "mngdata5.h"
#include "DlgObtai.h"
#include "IniData.h"
#include "modiflst.h"
#include "majdata.h"

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
 =======================================================================================
	CBatchObtainDlg dialog	 
 =======================================================================================
 =======================================================================================
 */



/*
 ----------------------------------------------------------------------------------------
  Description   : constructor
 ----------------------------------------------------------------------------------------
 */
CBatchObtainDlg::CBatchObtainDlg(CWnd* pParent) : CDialog(CBatchObtainDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBatchObtainDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT

	/*
	 * load bitmap for digit and separation
	 */
	m_a_oDigit[0].LoadBitmap( IDB_BITMAP_DIGIT0 );
	m_a_oDigit[1].LoadBitmap( IDB_BITMAP_DIGIT1 );
	m_a_oDigit[2].LoadBitmap( IDB_BITMAP_DIGIT2 );
	m_a_oDigit[3].LoadBitmap( IDB_BITMAP_DIGIT3 );
	m_a_oDigit[4].LoadBitmap( IDB_BITMAP_DIGIT4 );
	m_a_oDigit[5].LoadBitmap( IDB_BITMAP_DIGIT5 );
	m_a_oDigit[6].LoadBitmap( IDB_BITMAP_DIGIT6 );
	m_a_oDigit[7].LoadBitmap( IDB_BITMAP_DIGIT7 );
	m_a_oDigit[8].LoadBitmap( IDB_BITMAP_DIGIT8 );
	m_a_oDigit[9].LoadBitmap( IDB_BITMAP_DIGIT9 );
	m_oSeparator.LoadBitmap( IDB_BITMAP_SEPAR );

	m_bObtain = FALSE;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : destructor
 ----------------------------------------------------------------------------------------
 */
CBatchObtainDlg::~CBatchObtainDlg()
{
	char cBitmap;
	for (cBitmap = 0; cBitmap < 10; cBitmap ++)
		m_a_oDigit[ cBitmap ].DeleteObject();
	m_oSeparator.DeleteObject();
}


/*
 ----------------------------------------------------------------------------------------
  Description   : message map
 ----------------------------------------------------------------------------------------
 */
BEGIN_MESSAGE_MAP(CBatchObtainDlg, CDialog)
	//{{AFX_MSG_MAP(CBatchObtainDlg)
	ON_WM_DRAWITEM()
	ON_BN_CLICKED(IDC_CHECK_WAIT, OnCheckWait)
	ON_EN_KILLFOCUS(IDC_EDIT_SECONDS, OnKillfocusEditSeconds)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_TIME, OnDeltaposSpinTime)
	ON_BN_CLICKED(IDC_CHECK_USETIMER, OnCheckUsetimer)
	ON_WM_TIMER()
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SECONDS, OnDeltaposSpinSeconds)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/*
 ----------------------------------------------------------------------------------------
  Description   : BN_CLICKED on IDCANCEL button
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnCancel() 
{
	CDialog::OnCancel();
}

/*
 =======================================================================================
	Specific functions
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : compute elapse time before next try to obtain
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::fn_vComputeElapseTime()
{
	time_t		xTimer;
	struct tm	*p_stTime;
	long		lSecondsLeft;
	div_t		stDiv;

	time ( &xTimer );
	
	if (m_bUseTimer)
	{
		p_stTime = localtime( &xTimer );

		m_cHours = g_stWinPref.cHour - p_stTime->tm_hour;
		m_cMinutes = g_stWinPref.cMinute - p_stTime->tm_min;
		m_cSeconds = - p_stTime->tm_sec;

		m_lSeconds = m_cSeconds + m_cMinutes * 60 + m_cHours * 3600;
		m_lSeconds += g_stWinPref.cRelativeDay * 24*3600;

		if (m_lSeconds <= 0)
		{
			m_lSeconds = m_cHours = m_cMinutes = m_cSeconds = 0;
			m_bUseTimer = FALSE;
			m_bTry = TRUE;
		}
		else
		{
			stDiv = div( m_lSeconds, 3600);
			m_cHours = stDiv.quot;
			lSecondsLeft = stDiv.rem;
			stDiv = div (lSecondsLeft, 60 );
			m_cMinutes = stDiv.quot;
			m_cSeconds = stDiv.rem;
		}
	}
	else
	{
		m_lSeconds = m_xNextTry - xTimer;
		if (m_lSeconds <= 0)
		{
			m_lSeconds = m_cHours = m_cMinutes = m_cSeconds = 0;
			m_bTry = TRUE;
		}
		stDiv = div(m_lSeconds, 60 );
		m_cMinutes = stDiv.quot;
		m_cSeconds = stDiv.rem;
	}
}

/*
 =======================================================================================
	Message handlers 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : WM_INITDIALOG
 ----------------------------------------------------------------------------------------
 */
BOOL CBatchObtainDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

	CComboBox			*p_oCB;
	CSpinButtonCtrl		*p_oSpin;
	char				szValue[10];

	/*
	 * set elapse time and spin to that data
	 */
	//GetDlgItem( IDC_EDIT_TIME )->SetWindowText( itoa( g_stWinPref.lElapseTime, szValue, 10 ) );
	p_oSpin = (CSpinButtonCtrl *) GetDlgItem( IDC_SPIN_TIME );
	p_oSpin->SetRange( 10, 600 );
	p_oSpin->SetPos( g_stWinPref.lElapseTime );
	GetDlgItem( IDC_EDIT_SECONDS )->SetWindowText( itoa( g_stWinPref.lElapseTime, szValue, 10 ) );

	/*
	 * set use timer check
	 */
	((CButton *) GetDlgItem( IDC_CHECK_USETIMER))->SetCheck( g_stWinPref.bUseTimer ? 1 : 0 );
	
	/*
	 * set relative day
	 */
	p_oCB = (CComboBox *) GetDlgItem( IDC_COMBO_DAY );
	p_oCB->SetCurSel( g_stWinPref.cRelativeDay );

	/*
	 * set date
	 */
	sprintf( szValue, "%02d:%02d", g_stWinPref.cHour, g_stWinPref.cMinute );
	GetDlgItem( IDC_EDIT_TIME )->SetWindowText( szValue );

	/*
	 * set check for wait to be alone
	 */
	((CButton *) GetDlgItem( IDC_CHECK_NOBODYELSE))->SetCheck( g_stWinPref.bWaitToBeAlone ? 1 : 0 );

	OnCheckUsetimer();

	return TRUE;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : WM_DRAWITEM
 ----------------------------------------------------------------------------------------
 */
#define C_xLightColor	RGB(255,0,0)
#define C_xMiddleColor	RGB(192,0,0)
#define C_xDarkColor	RGB(128,0,0)

void CBatchObtainDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDIS) 
{
	div_t	stDiv;
	CPoint	oPos( 10, 10);
	CSize	oDigitSize( 15, 30 );
	CSize	oSeparSize(  5, 30 );
	CBrush	oBrush( C_xMiddleColor );

	if (nIDCtl == IDC_BUTTON_TIME)
	{
		CDC		*p_oDC = CDC::FromHandle( lpDIS->hDC );
		
		p_oDC->Draw3dRect( &lpDIS->rcItem, C_xLightColor, C_xDarkColor );
		lpDIS->rcItem.left++; lpDIS->rcItem.top++; lpDIS->rcItem.bottom--; lpDIS->rcItem.right--;
		p_oDC->FrameRect( &lpDIS->rcItem, &oBrush );
		lpDIS->rcItem.left++; lpDIS->rcItem.top++; lpDIS->rcItem.bottom--; lpDIS->rcItem.right--;
		p_oDC->FrameRect( &lpDIS->rcItem, &oBrush );
		lpDIS->rcItem.left++; lpDIS->rcItem.top++; lpDIS->rcItem.bottom--; lpDIS->rcItem.right--;
		p_oDC->Draw3dRect( &lpDIS->rcItem, C_xDarkColor, C_xLightColor );
		lpDIS->rcItem.left++; lpDIS->rcItem.top++; lpDIS->rcItem.bottom--; lpDIS->rcItem.right--;
		p_oDC->FillSolidRect( &lpDIS->rcItem, RGB( 0,0,0 ) );

		/* hour */
		stDiv = div( m_cHours, 10);
		p_oDC->DrawState( oPos, oDigitSize, &m_a_oDigit[ stDiv.quot ], DST_BITMAP );
		oPos.x += 16;
		p_oDC->DrawState( oPos, oDigitSize, &m_a_oDigit[ stDiv.rem ], DST_BITMAP );
		oPos.x += 16;
		p_oDC->DrawState( oPos, oDigitSize, &m_oSeparator, DST_BITMAP );
		oPos.x += 6;

		/* minute */
		stDiv = div( m_cMinutes, 10);
		p_oDC->DrawState( oPos, oDigitSize, &m_a_oDigit[ stDiv.quot ], DST_BITMAP );
		oPos.x += 16;
		p_oDC->DrawState( oPos, oDigitSize, &m_a_oDigit[ stDiv.rem ], DST_BITMAP );
		oPos.x += 16;
		p_oDC->DrawState( oPos, oDigitSize, &m_oSeparator, DST_BITMAP );
		oPos.x += 6;

		/* seconds */
		stDiv = div( m_cSeconds, 10);
		p_oDC->DrawState( oPos, oDigitSize, &m_a_oDigit[ stDiv.quot ], DST_BITMAP );
		oPos.x += 16;
		p_oDC->DrawState( oPos, oDigitSize, &m_a_oDigit[ stDiv.rem ], DST_BITMAP );
	}
	CDialog::OnDrawItem(nIDCtl, lpDIS);
}


/*
 ----------------------------------------------------------------------------------------
  Description   : BN_CLICKED on IDC_BUTTON_WAIT
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnCheckWait() 
{
	BOOL bWait= ((CButton *) GetDlgItem( IDC_CHECK_WAIT ))->GetCheck() == 1;
	BOOL bContinue = TRUE;

	GetDlgItem( IDC_STATIC_SECONDS )->ShowWindow( !bWait );
	GetDlgItem( IDC_EDIT_SECONDS )->ShowWindow( !bWait );
	GetDlgItem( IDC_SPIN_SECONDS )->ShowWindow( !bWait );
	GetDlgItem( IDC_STATIC_SECONDS2 )->ShowWindow( !bWait );
	GetDlgItem( IDC_CHECK_USETIMER )->ShowWindow( !bWait );
	GetDlgItem( IDC_STATIC_TIMER )->ShowWindow( !bWait );
	GetDlgItem( IDC_STATIC_DAY )->ShowWindow( !bWait && g_stWinPref.bUseTimer );
	GetDlgItem( IDC_COMBO_DAY )->ShowWindow( !bWait && g_stWinPref.bUseTimer );
	GetDlgItem( IDC_STATIC_TIME )->ShowWindow( !bWait && g_stWinPref.bUseTimer );
	GetDlgItem( IDC_EDIT_TIME )->ShowWindow( !bWait && g_stWinPref.bUseTimer );
	GetDlgItem( IDC_SPIN_TIME )->ShowWindow( !bWait && g_stWinPref.bUseTimer );
	GetDlgItem( IDC_STATIC_TIME2 )->ShowWindow( !bWait && g_stWinPref.bUseTimer );
	GetDlgItem( IDC_CHECK_NOBODYELSE )->ShowWindow( !bWait );
	GetDlgItem( IDCANCEL )->ShowWindow( !bWait );
	GetDlgItem( IDC_STATIC_WAIT )->ShowWindow( bWait );
	GetDlgItem( IDC_BUTTON_TIME )->ShowWindow( bWait );
	GetDlgItem( IDC_STATIC_RESULT )->ShowWindow( bWait );

	if ( bWait )
	{
		g_stWinPref.cRelativeDay = ((CComboBox *) GetDlgItem( IDC_COMBO_DAY ))->GetCurSel();
		g_stWinPref.bWaitToBeAlone = ((CButton *) GetDlgItem( IDC_CHECK_NOBODYELSE ))->GetCheck() == 1;

		/* 
		 * display what we are waiting
		 */
		char szMessage[1024], *p_szMessage = szMessage;
		char szDay[ 40 ];

		m_bUseTimer = g_stWinPref.bUseTimer;
		if (g_stWinPref.bUseTimer)
		{
			((CComboBox *) GetDlgItem( IDC_COMBO_DAY) )->GetLBText( g_stWinPref.cRelativeDay, szDay );
			p_szMessage += sprintf( p_szMessage, "Wait %s %02d:%02d and then\r\n", szDay, g_stWinPref.cHour, g_stWinPref.cMinute );
		}
		p_szMessage += sprintf( p_szMessage, "Try to obtain every %d seconds\r\n", g_stWinPref.lElapseTime );
		if (g_stWinPref.bWaitToBeAlone)
			p_szMessage += sprintf( p_szMessage, "Obtain only if database is unoccupied" );
		else
			p_szMessage += sprintf( p_szMessage, "Obtain even if another one is obtaining data" );
		
		GetDlgItem( IDC_STATIC_WAIT )->SetWindowText( szMessage );
		GetDlgItem( IDC_STATIC_RESULT )->SetWindowText( "" );

		m_lTryCount = 0;

		time ( &m_xNextTry );
		m_bTry = FALSE;

		fn_vComputeElapseTime();
		GetDlgItem( IDC_BUTTON_TIME)->Invalidate();
		m_uiTimer = SetTimer( 1, 1000, NULL );
	}
	else
	{
		KillTimer( m_uiTimer );
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : EM_KILLFOCUS on IDC_EDIT_SECONDS
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnKillfocusEditSeconds() 
{
	char	szValue[10];

	GetDlgItem( IDC_EDIT_SECONDS )->GetWindowText( szValue, 9 );
	g_stWinPref.lElapseTime = atoi( szValue );
	if (g_stWinPref.lElapseTime < 10)
		g_stWinPref.lElapseTime = 10;
	else if (g_stWinPref.lElapseTime > 600)
		g_stWinPref.lElapseTime = 600;

	GetDlgItem( IDC_EDIT_SECONDS )->SetWindowText( itoa( g_stWinPref.lElapseTime, szValue, 10 ) );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : UDN_DELTAPOS on IDC_SPIN_TIME
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnDeltaposSpinTime(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN*	pNMUpDown = (NM_UPDOWN*)pNMHDR;
	int			iDelta;
	char		szTime[10];
	
	iDelta = pNMUpDown->iDelta;

	if ( (GetKeyState( VK_SHIFT ) & 0x8000) == 0)
	{
		g_stWinPref.cMinute += iDelta;
		if (g_stWinPref.cMinute < 0)
		{
			g_stWinPref.cMinute = 59;
			iDelta = -1;
		}
		else if (g_stWinPref.cMinute > 59)
		{
			g_stWinPref.cMinute = 0;
			iDelta = 1;
		}
		else
			iDelta = 0;
	}

	if (iDelta)
	{
		g_stWinPref.cHour += iDelta;
		if (g_stWinPref.cHour < 0)
			g_stWinPref.cHour = 23;
		else if (g_stWinPref.cHour > 23)
			g_stWinPref.cHour = 0;
	}

	sprintf( szTime, "%02d:%02d", g_stWinPref.cHour, g_stWinPref.cMinute );
	GetDlgItem( IDC_EDIT_TIME )->SetWindowText( szTime );
	
	*pResult = 1;
}



/*
 ----------------------------------------------------------------------------------------
  Description   : BN_CLICKED on IDC_USE_TIMER
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnCheckUsetimer() 
{
	g_stWinPref.bUseTimer = ((CButton *) GetDlgItem( IDC_CHECK_USETIMER ))->GetCheck() == 1;

	GetDlgItem( IDC_STATIC_DAY )->ShowWindow( g_stWinPref.bUseTimer );
	GetDlgItem( IDC_COMBO_DAY )->ShowWindow( g_stWinPref.bUseTimer );
	GetDlgItem( IDC_STATIC_TIME )->ShowWindow( g_stWinPref.bUseTimer );
	GetDlgItem( IDC_EDIT_TIME )->ShowWindow( g_stWinPref.bUseTimer );
	GetDlgItem( IDC_SPIN_TIME )->ShowWindow( g_stWinPref.bUseTimer );
	GetDlgItem( IDC_STATIC_TIME2 )->ShowWindow( g_stWinPref.bUseTimer );
}


/*
 ----------------------------------------------------------------------------------------
  Description   : WM_TIMER
  nIDEvent            -> ident of timer
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnTimer(UINT nIDEvent) 
{
	char szMessage[ 256 ], *p_szMessage;

	if (nIDEvent == m_uiTimer )
	{
		fn_vComputeElapseTime();
		GetDlgItem( IDC_BUTTON_TIME)->Invalidate();
		if ( m_bTry )
		{
			/*
			 * try to obtain
			 */
			p_szMessage = szMessage + sprintf( szMessage, "%d ->", ++m_lTryCount );
			if (g_stWinPref.bWaitToBeAlone && fn_bSomeoneObtain( FALSE ))
			{			
				if (g_cNbUsers)
					sprintf( p_szMessage, "Can't obtain cause %s is obtaining\r\n", g_a_szUserName[0] );
				else
					sprintf( p_szMessage, "Can't access server" );
			}
			else
			{
				if (fn_bSomeoneUpdate(FALSE, FALSE))
				{
					if (g_cNbUsers)
						sprintf( p_szMessage, "Can't obtain cause %s is updating\r\n", g_a_szUserName[0] );
					else
						sprintf( p_szMessage, "Can't access server" );
				}
				else
				{
					if (!fn_bBeginObtaining() )
						sprintf( p_szMessage, "Can't access server" );
					else
					{
						m_bObtain = TRUE;
						OnCancel();
					}
				}
			}
			GetDlgItem( IDC_STATIC_RESULT )->SetWindowText( szMessage );

			/*
			 * obtain can not be done
			 */
			time_t xTimer;
			time ( &xTimer );
			m_bTry = FALSE;
			m_xNextTry = xTimer + g_stWinPref.lElapseTime;
		}
	}
	CDialog::OnTimer(nIDEvent);
}

/*
 ----------------------------------------------------------------------------------------
  Description   : UDN_DELTAPOS on IDC_SPIN_TIME
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnDeltaposSpinSeconds(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN*	pNMUpDown = (NM_UPDOWN*)pNMHDR;
	int			iDelta;
	char		szValue[10];
	
	iDelta = -pNMUpDown->iDelta;

	g_stWinPref.lElapseTime += iDelta;
	if (g_stWinPref.lElapseTime < 10)
		g_stWinPref.lElapseTime = 10;
	else if (g_stWinPref.lElapseTime > 600)
		g_stWinPref.lElapseTime = 600;
	
	GetDlgItem( IDC_EDIT_SECONDS )->SetWindowText( itoa( g_stWinPref.lElapseTime, szValue, 10 ) );
	
	*pResult = 1;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : WM_DESTROY
 ----------------------------------------------------------------------------------------
 */
void CBatchObtainDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	KillTimer( m_uiTimer );	
}
