/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/SPAUSER.CPP   1.2.1.4   17 Apr 1997 16:00:16   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/SPAUSER.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 16:00:16   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:33:10   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:42:42   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:21:24   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:25:36   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:35:32   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:50:02   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 12:59:22   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.4   09 Sep 1996 13:18:06   ZJRD
** EasyPack/SLD Version 1.9f
** 
**    Rev 1.7.1.3   05 Sep 1996 11:29:38   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 09:56:42   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:52:30   ZJRD
** EasyPack/SLD Version 1.9b
** 
**    Rev 1.7.1.0   12 Aug 1996 10:55:58   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.7   11 Jun 1996 10:26:18   ZJRD
** EasyPack/SLD Version 1.97
** 
**    Rev 1.5   05 Jun 1996 14:54:06   ZJRD
** EasyPack/SLD Version 1.96
** 
**    Rev 1.4   29 May 1996 09:29:34   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.3   16 May 1996 09:06:50   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:09:50   ZJRD
** EasyPack/SLD Version 1.93
** 
**    Rev 1.1   02 May 1996 10:26:28   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.1   18 Apr 1996 12:54:20   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.0   12 Apr 1996 10:36:22   Shirley
** Initial revision.
** 
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name: SPAUSER.CPP
//
//  Description: The implementation file fore class: CSpaUserDefineDlg.
//
//  Author: Chen Jun
//
//  Date: 03/21/96
//
//  Modification:
//      1. 03/21/96, Initial version of the class: CSpaUserDefineDlg.
//		2. 05/08/96, According to Fax: 960502-M1, I changed all the related
//					 codes. We would refer to V1.92 from PVCS if we should
//				     recover to the old version. It would include *.RES, 
//					 resource.h & spauser.*.
//
//  Copyright (C) 1996 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"

#include "spagrp.h"
#include "spauser.h"
#include "spabrow.h"
#include <direct.h>
#include <ctype.h>

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// External variables.
extern char szAppPath[_MAX_PATH+1];

int SrcIsLoaded(void);

/////////////////////////////////////////////////////////////////////////////
// CSpaUserDefineDlg dialog

CSpaUserDefineDlg::CSpaUserDefineDlg(CSpaGroupSheet* pSheet, CWnd* pParent /*=NULL*/)
	: CDialog(CSpaUserDefineDlg::IDD, pParent),
	m_bShowBrowse(TRUE), m_bShowAdd(TRUE), m_bShowDelete(TRUE), m_bShowModify(TRUE),
	m_nRangeSelect(entryRange), m_pSheet(pSheet)
{
	//{{AFX_DATA_INIT(CSpaUserDefineDlg)
	m_nSelect = 0;
	m_strStart = "";
	m_strEnd = "";
	m_strDefine = "";
	//}}AFX_DATA_INIT

	pSheet->m_nErrorID = pSheet->errOK;
}

void CSpaUserDefineDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSpaUserDefineDlg)
	DDX_Control(pDX, IDC_BUTTON_SPA_USER_ADD, m_btnAdd);
	DDX_Control(pDX, IDC_BUTTON_SPA_USER_MODIFY, m_btnModify);
	DDX_Control(pDX, IDC_BUTTON_SPA_USER_DELETE, m_btnDelete);
	DDX_Control(pDX, IDC_BUTTON_SPA_USER_BROWSE, m_btnBrowse);
	DDX_Control(pDX, IDC_STATIC_END, m_staticEnd);
	DDX_Control(pDX, IDC_EDIT_SPA_END, m_editEnd);
	DDX_Control(pDX, IDC_LIST_SPA_RANGE, m_listRange);
	DDX_LBIndex(pDX, IDC_LIST_SPA_RANGE, m_nSelect);
	DDX_Text(pDX, IDC_EDIT_SPA_START, m_strStart);
	DDV_MaxChars(pDX, m_strStart, 80);
	DDX_Text(pDX, IDC_EDIT_SPA_END, m_strEnd);
	DDV_MaxChars(pDX, m_strEnd, 80);
	DDX_Text(pDX, IDC_EDIT_SPA_USER, m_strDefine);
	DDV_MaxChars(pDX, m_strDefine, 80);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSpaUserDefineDlg, CDialog)
	//{{AFX_MSG_MAP(CSpaUserDefineDlg)
	ON_BN_CLICKED(IDC_BUTTON_SPA_USER_ADD, OnButtonSpaUserAdd)
	ON_BN_CLICKED(IDC_BUTTON_SPA_USER_DELETE, OnButtonSpaUserDelete)
	ON_BN_CLICKED(IDC_BUTTON_SPA_USER_MODIFY, OnButtonSpaUserModify)
	ON_LBN_SELCHANGE(IDC_LIST_SPA_RANGE, OnSelchangeListSpaRange)
	ON_BN_CLICKED(IDC_BUTTON_SPA_USER_BROWSE, OnButtonSpaUserBrowse)
	ON_EN_CHANGE(IDC_EDIT_SPA_USER, OnChangeEditSpaUser)
	ON_EN_CHANGE(IDC_EDIT_SPA_START, OnChangeEditSpaStart)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CSpaUserDefineDlg common routines

void CSpaUserDefineDlg::CheckInputSyntax(int nWhichButton)
{
	// No any error now.
	ASSERT(m_pSheet->errOK == m_pSheet->m_nErrorID);
	
	// Check DEFINE input.
	m_strDefine.TrimLeft();
	m_strDefine.TrimRight();
	if ( m_strDefine.IsEmpty() || m_strDefine.GetLength() > 80 ) {
		m_pSheet->m_nErrorID = m_pSheet->errInput;
		return;
	}

/*
	if ( !iscsymf(m_strDefine[0]) ) {
		m_pSheet->m_nErrorID = m_pSheet->errInput;
		return;
	}
*/

	for ( int i(0); i < m_strDefine.GetLength(); i++ ) {
		if ( !iscsym(m_strDefine[i]) ) {
			m_pSheet->m_nErrorID = m_pSheet->errInput;
			return;
		}
	}
	
	if ( btnOnlyName == nWhichButton ) {
		return;
	}

	if ( btnAdd == nWhichButton ) {
		int nCount = m_listRange.GetCount();
		if ( nCount > 0 ) {
			for ( int i(0); i < nCount; i++ ) {
				CString strExist;
				m_listRange.GetText(i, strExist);
				strExist = strExist.Left(strExist.Find(' '));
				if ( m_strDefine == strExist ) {
					m_pSheet->m_nErrorID = m_pSheet->errExist;
					return;
				}
			}
		}
	}
	
	// Check START address.
	m_strStart.TrimLeft();
	m_strStart.TrimRight();
	if ( !m_pSheet->IsValidAddr(m_strStart) ) {
		m_pSheet->m_nErrorID = m_pSheet->errInput;
		return;
	}
	
	// Check END address.
	m_strEnd.TrimLeft();
	m_strEnd.TrimRight();
	if ( !m_strEnd.IsEmpty() ) {
		if ( !m_pSheet->IsValidAddr(m_strEnd) ) {
			m_pSheet->m_nErrorID = m_pSheet->errInput;
			return;
		}
	
		// In the same range
		::ADDRESS Addr1, Addr2;
		if ( ::ADR_OK != ::AdrShellToAddr(m_strStart, Addr1, ::SPACE_PROGRAME) ) {
			m_pSheet->m_nErrorID = m_pSheet->errInput;
			return;
		}
		if ( ::ADR_OK != ::AdrShellToAddr(m_strEnd, Addr2, ::SPACE_PROGRAME) ) {
			m_pSheet->m_nErrorID = m_pSheet->errInput;
			return;
		}
		
		if ( Addr1.adrSpace != Addr2.adrSpace ) {
			m_pSheet->m_nErrorID = m_pSheet->errInput;
			return;
		}

		// Check address range.
		if ( ::ADR_OK != ::AdrCheck2Addr(m_strStart, m_strEnd) ) {
			m_pSheet->m_nErrorID = m_pSheet->errInput;
			return;
		}
	}
}

void CSpaUserDefineDlg::MakeRecordDirectory(void)
{
	// Create the sub-directory.
	m_strPath = ::szAppPath;
	m_strPath += "SPA";
	mkdir(m_strPath);
}

void CSpaUserDefineDlg::ReadRecord(void)
{
	// Read from the record file.
	switch ( m_nRangeSelect ) {
//		case executionRange:
//			m_strFile = m_strPath + "\\execute.dbf";
//			break;
		case entryRange:
			m_strFile = m_strPath + "\\entry.dbf";
			break;
		default:
			ASSERT(FALSE);
			return;
	}

	// Assign the open flag.
    CFileStatus status;
	if ( !CFile::GetStatus(m_strFile, status) ) {
		return;
	}

	TRY {
		// Open the record file.
		UINT nOpenFlag = CFile::modeRead | CFile::typeText;
		CStdioFile* fp = new CStdioFile(m_strFile, nOpenFlag);
	
		// Read from the record file.
		int nMax = defineLen+startLen+endLen;
		char* pszLine = new char[nMax+4];
		while ( fp->ReadString(pszLine, nMax) ) {
			// Split string.
			char* p = pszLine;
			while ( *p ) {
				if ( '\n' == *p ) {
					*p = NULL;
					break;
				}
				p++;
			}
			m_pSheet->EmptyBuffer();
			m_pSheet->SplitRecord(CString(pszLine));
			TransferData();
			CString str(m_strDefine+' '+m_strStart+' '+m_strEnd);
			m_listRange.AddString(str);
		}
		delete []pszLine;
		
		// Close the record file.
		fp->Close();
		delete fp;
	}
	CATCH(CFileException, e) {
		m_pSheet->m_nErrorID = m_pSheet->errFile;
		m_pSheet->DisplayErrorMessage();
	}
	AND_CATCH(CMemoryException, e) {
		m_pSheet->m_nErrorID = m_pSheet->errMemory;
		m_pSheet->DisplayErrorMessage();
	}
	END_CATCH
}

BOOL CSpaUserDefineDlg::WriteRecord(void)
{
	// Read from the list box.
	int nCount = m_listRange.GetCount();
	if ( nCount <= 0 ) {
//		m_pSheet->m_nErrorID = m_pSheet->errNoDelimit;
//		m_pSheet->DisplayErrorMessage();
		AfxMessageBox("No any range setting added");
		return FALSE;
	}

	// Write the record file.
	switch ( m_nRangeSelect ) {
//		case executionRange:
//			m_strFile = m_strPath + "\\execute.dbf";
//			break;
		case entryRange:
			m_strFile = m_strPath + "\\entry.dbf";
			break;
		default:
			ASSERT(FALSE);
			return FALSE;
	}
	
	// Remove the record file.
	if ( 0 == nCount ) {
		TRY {
			CFile::Remove(m_strFile);
		}
		CATCH(CFileException, e) {
			m_pSheet->m_nErrorID = m_pSheet->errFile;
			m_pSheet->DisplayErrorMessage();
		}
		END_CATCH

		return FALSE;
	}

	// Open the record file.
	TRY {
		UINT nOpenFlag = CFile::modeWrite | CFile::modeCreate | CFile::typeText;
		CStdioFile* fp = new CStdioFile(m_strFile, nOpenFlag);
		
		// Write to the record file.
		for ( int i(0); i < nCount; i++ ) {
			CString str;
			m_listRange.GetText(i, str);
			m_pSheet->EmptyBuffer();
			m_pSheet->BindRecord(str);
			TransferData();
			if ( m_strEnd.IsEmpty() ) {
				str = m_strDefine + ';' + m_strStart + '\n';
			}
			else {
				str = m_strDefine + ';' + m_strStart + ';' + m_strEnd + '\n';
			}
			if ( str.IsEmpty() ) {
				m_pSheet->m_nErrorID = m_pSheet->errEmpty;
				m_pSheet->DisplayErrorMessage();
				continue;
			}
			fp->WriteString(str);
		}
	
		// Close the record file.
		fp->Close();
		delete fp;
	}
	CATCH(CFileException, e) {
		m_pSheet->m_nErrorID = m_pSheet->errFile;
		m_pSheet->DisplayErrorMessage();
		return FALSE;
	}
	AND_CATCH(CMemoryException, e) {
		m_pSheet->m_nErrorID = m_pSheet->errMemory;
		m_pSheet->DisplayErrorMessage();
		return FALSE;
	}
	END_CATCH

	return TRUE;
}

void CSpaUserDefineDlg::UpdateRecord(void)
{
	// Update record data.
    BeginWaitCursor();

	m_listRange.ResetContent();
	m_strDefine = m_strStart = m_strEnd = "";

    ReadRecord();

	int nCount = m_listRange.GetCount();
    if ( nCount > 0 ) {
		m_bShowDelete = TRUE;
		m_bShowModify = TRUE;
		m_bShowAdd = TRUE;
		m_bShowBrowse = (0==::SrcIsLoaded()) ? TRUE : FALSE;

		CString str;
		m_listRange.GetText(0, str);
		m_nSelect = 0;
		m_pSheet->BindRecord(str);
		TransferData();
	}
	else {
		m_bShowDelete = FALSE;
		m_bShowModify = FALSE;
		m_bShowAdd = FALSE;
		m_bShowBrowse = FALSE;
	}
	DisableControl();

    EndWaitCursor();
}

void CSpaUserDefineDlg::TransferData(void)
{
	// Transfer data from SPA sheet.
	m_strDefine = m_pSheet->m_strDefine;
	m_strStart = m_pSheet->m_strStart;
	m_strEnd = m_pSheet->m_strEnd;
}

void CSpaUserDefineDlg::DisableControl(void)
{
	// Disable the buttons.
	m_btnBrowse.EnableWindow(m_bShowBrowse);
	m_btnAdd.EnableWindow(m_bShowAdd);
	m_btnDelete.EnableWindow(m_bShowDelete);
	m_btnModify.EnableWindow(m_bShowModify);
}


/////////////////////////////////////////////////////////////////////////////
// CSpaUserDefineDlg message handlers

BOOL CSpaUserDefineDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	
    // Centering dialog box.
    CenterWindow();
    m_listRange.SetHorizontalExtent(400);

    HFONT hFont = (HFONT)::GetStockObject(ANSI_FIXED_FONT);
    CFont font;
	m_listRange.SetFont(font.FromHandle(hFont));
	
	// Update record data.
	MakeRecordDirectory();
	UpdateRecord();
    UpdateData(FALSE);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSpaUserDefineDlg::OnCancel()
{
	// TODO: Add extra cleanup here
	
	CDialog::OnCancel();
}

void CSpaUserDefineDlg::OnOK() 
{
	// TODO: Add extra validation here
	
	// Write to the default record file.
	UpdateData();

	if ( !WriteRecord() ) {
		return;
	}

	CDialog::OnOK();
}

void CSpaUserDefineDlg::OnButtonSpaUserAdd()
{
	// TODO: Add your control notification handler code here

    // Add to the list box.
    UpdateData();

	CheckInputSyntax(btnAdd);
	if ( m_pSheet->errOK != m_pSheet->m_nErrorID ) {
		m_pSheet->DisplayErrorMessage();
		return;
	}

    CString str;
	str = m_strDefine + ' ' + m_strStart + ' ' + m_strEnd;
    m_listRange.AddString(str);

    int nLast = m_listRange.GetCount()-1;
	if ( nLast >= 0 ) {
		m_listRange.SetCurSel(nLast);
		m_bShowDelete = TRUE;
		m_bShowModify = TRUE;
		DisableControl();
	}
}

void CSpaUserDefineDlg::OnButtonSpaUserDelete()
{
	// TODO: Add your control notification handler code here
	
    // Delete the current selected item.
    UpdateData();

    m_listRange.DeleteString(m_nSelect);
    if ( --m_nSelect >= 0 ) {
    	m_listRange.SetCurSel(m_nSelect);
    }
    else if ( m_listRange.GetCount() >= 1 ) {
		m_listRange.SetCurSel(0);
		m_bShowDelete = TRUE;
		m_bShowModify = TRUE;
		DisableControl();
	}
    else {
		m_bShowDelete = FALSE;
		m_bShowModify = FALSE;
		DisableControl();
    }
}

void CSpaUserDefineDlg::OnButtonSpaUserModify()
{
	// TODO: Add your control notification handler code here
	
    // Delete & insert the current selected item.
    UpdateData();
    
	CheckInputSyntax(btnModify);
	if ( m_pSheet->errOK != m_pSheet->m_nErrorID ) {
		m_pSheet->DisplayErrorMessage();
		return;
	}

    CString str;
	str = m_strDefine + ' ' + m_strStart + ' ' + m_strEnd;

    m_listRange.DeleteString(m_nSelect);
    m_listRange.InsertString(m_nSelect, str);
    if ( m_nSelect >= 0 ) {
    	m_listRange.SetCurSel(m_nSelect);
    }
}

void CSpaUserDefineDlg::OnSelchangeListSpaRange()
{
	// TODO: Add your control notification handler code here
	
    // Copy to the edit box.
    UpdateData();

    CString str;
    m_listRange.GetText(m_nSelect, str);
	m_pSheet->BindRecord(str);
	TransferData();
	
    UpdateData(FALSE);
}

void CSpaUserDefineDlg::OnButtonSpaUserBrowse() 
{
	// TODO: Add your control notification handler code here

	// Get the defined name.
	UpdateData();
	CheckInputSyntax(btnOnlyName);
	if ( m_pSheet->errOK != m_pSheet->m_nErrorID ) {
		m_pSheet->DisplayErrorMessage();
		return;
	}

	// Open the browse dialog to view module & function info.
	CSpaBrowseDlg dlg(m_pSheet, m_strDefine);
	if ( IDOK == dlg.DoModal() ) {
		// Add to the dialog control.
		m_strDefine = dlg.m_strRange;
		m_strStart = dlg.m_strStart;
		m_strEnd = dlg.m_strEnd;
		UpdateData(FALSE);

		// As same as Add button pressed.
		OnButtonSpaUserAdd();
	}
}

void CSpaUserDefineDlg::OnChangeEditSpaUser() 
{
	// TODO: Add your control notification handler code here
	
	// Disable the controls if erasing the input.
	UpdateData();
	
	if ( m_strDefine.IsEmpty() ) {
		m_bShowBrowse = FALSE;
		m_bShowAdd = FALSE;
		m_bShowModify = FALSE;
	}
	else {
		m_bShowBrowse = (0==::SrcIsLoaded()) ? TRUE : FALSE;
		m_bShowAdd = TRUE;
		m_bShowModify = m_listRange.GetCount() > 0 ? TRUE : FALSE;
	}
	DisableControl();
	
	UpdateData(FALSE);
}

void CSpaUserDefineDlg::OnChangeEditSpaStart() 
{
	// TODO: Add your control notification handler code here
	
	// Disable the controls if erasing the input.
	UpdateData();
	
	if ( m_strStart.IsEmpty() ) {
		m_bShowAdd = FALSE;
		m_bShowModify = FALSE;
	}
	else {
		m_bShowAdd = TRUE;
		m_bShowModify = m_listRange.GetCount() > 0 ? TRUE : FALSE;
	}
	DisableControl();
	
	UpdateData(FALSE);
}
