#include <string>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <time.h> 
 
using namespace std; 

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Radio_Round_Button.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Spinner.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Select_Browser.H>
#include <FL/Fl_Value_Input.H>
#include <FL/fl_ask.H>

//==========================================================
//	C++ languageONE Interface
//==========================================================
		#include "V3.08/include/interface.ext"

//==========================================================
//	Constants
//==========================================================
		const long long c_Initial					= 0;
		const long long c_A01							= 1;
		const long long c_B01							= 2;
		const long long c_B02							= 3;
		const long long c_B03							= 4;
		const long long c_B04							= 5;
		const long long c_B99							= 99;
			const long long c_B99_GetDate		= 1;
			const long long c_B99_ValidDate	= 2;

		const long long c_Read						= 1;
		const long long c_Write						= 2;
		const	long long c_Start						= 3;
		const long long c_PreviousNext		= 4;
		const long long c_Delete					= 5;
		const long long c_Commit					= 6;
		const long long c_Print						= 7;

		const long long c_Enquire					= 11;

		void L1_INTERFACE();

//==========================================================
//	GLOBAL VARIABLES
//==========================================================

		string			w_financialYear;
		long long		n_financialYear;
		string			w_Title;

		long long		i,j,k,x,y;
		long long		windowNo, fromWindowNo;
		long long		searchNo;

		long long		spinner_acctno, spinner_recno, enq_acctno;
		
		long long		a01_recNo; 
		long long		a01_system_recno;

		long long		b01_recNo; bool b01_AllAccts;
		long long		b02_recNo;
		long long		b99_recNo, b99_startAcctNo;
		
		long long 	direction;

		string	ccyy="",mm="",dd="",hrs="",min="",sec="";	


		string 	str, str1, str2, str3, str4;

		string flag1[]	= {"A ","X ","T ","C ","AB","CA","PA",
											 "BA","PL","DA","AS","TO","TC"};
		string balID[]	=	{"DR","CR"};

		char w_RunningBalance[10];

//	---------------------------------------------------------
//	Needs to be global as every window will use this
//	---------------------------------------------------------
void _windowExit_callback					(Fl_Widget* w, void* data);

//==============================================================
//	Each Window has its definition and the code tat goes with it
//==============================================================
		#include "V3.08/include/l1.cpy"

		#include "V3.08/include/acctselect.cxx"

		#include "V3.08/include/journal.cxx"
		#include "V3.08/include/enquiry.cxx"

		#include "V3.08/include/reports.cxx"
		#include "V3.08/include/chart.cxx"
		#include "V3.08/include/system.cxx"
		#include "V3.08/include/menu2.cxx"
		#include "V3.08/include/menu1.cxx"

//==========================================================
//+--EVENT HANDLER -> Keyboard Capture
//==========================================================
int eventHandler(int e, Fl_Window *w) 
{

	if ( e == FL_KEYDOWN )
	{

		int k = Fl::event_key(); 


		if (k==65307) { e=NULL; } 				// Swallow Escape

		if (k==65472)											// F3
			{	switch (windowNo)
				{
					case 3:
						fromWindowNo=3;
						win3p_sys_StartParameterNo->value(1);
						win3p_sys_EndParameterNo->value(99);
						win3p_sys_StartParameter->value(1);
						win3p_sys_EndParameter->value(99);
						win3p_sys->show();
						break;
					case 4:
						fromWindowNo=4;
						win4p_coa_StartAcctNo->value(1);
						win4p_coa_EndAcctNo->value(99999);
						win4p_coa->show();
						break;
					case 5:
						fromWindowNo=5;
						win5p_gj_start_dd->value("01");
						win5p_gj_start_mm->value("01");
						win5p_gj_start_ccyy->value("1900");
						win5p_gj_end_dd->value("31");
						win5p_gj_end_mm->value("12");
						win5p_gj_end_ccyy->value("2999");
						win5p_gj_details->value(0);
						win5p_gj->show();
						break;
					case 6:
						if (A01_ParameterNo != 2) {break;}
						fromWindowNo=6;
						win6p_enq_StartAcctNo->value(1);
						win6p_enq_EndAcctNo->value(59999);
						win6p_enq_start_dd->value("01");
						win6p_enq_start_mm->value("01");
						win6p_enq_start_ccyy->value("1900");
						win6p_enq_end_dd->value("31");
						win6p_enq_end_mm->value("12");
						win6p_enq_end_ccyy->value("2999");
						win6p_enq_trans->value(0);
						win6p_enq_zero->value(0);
						win6p_enq_newpage->value(0);
						win6p_enq->show();
						break;
				}
			}

		if (k==65474)							 				// F5
		{
			if (w==win3_sys)
				{
					a01_recNo=0;
					if (WIN3_GET_SYS(true)) {selectWin3_sys_details();}
				}

			if (w==win4_coa) 
				{
					b01_recNo=0;
					if (WIN4_GET_ACCT(true)) {selectWin4_coa_details();}
				}

			if (w==win5_gj)
				{
					b02_recNo=0;
					if (WIN5_GET_TRANS(false)) {selectWin5_gj_details();}
				}

			if (w==win6_enq) 
				{
					if (WIN6_GET_KEY())
						{		
							L1_CALL(c_B03,c_Enquire,0,enq_acctno,0);
							WIN6_ENQ_ACCOUNTS();
						}
				}

		}
	}

	return Fl::handle_(e, w);

}

//==========================================================
//+--MAINLINE
//==========================================================
int main(int argc, char **argv){

		Fl::event_dispatch(eventHandler);

//	------------------
//	Get Financial Year
//	------------------
		if (argc == 1)
		{		L1_CALL(c_B99,c_B99_GetDate,0,0,0);
				str="";for (j=0; j<4; j++) {str = str + w_Date[j];}
				w_financialYear = str;
		}
		else
		{
				w_financialYear = argv[1];
		}
		n_financialYear = atoi(w_financialYear.c_str());
		w_Title=w_financialYear+ " System";
 
//	------------------
//	Initialize
//	------------------
		Fl::scheme("base");
		Fl::background(225,225,225);
		FL_NORMAL_SIZE = 11; 

		L1_INTERFACE(); 
		window1();
		window2();
		window3();	window3p();
		window4();	window4p();
		window5();	window5p();
		window6();	window6p();
		window7p();
		window99();

//	---------
//	and Do it
//	---------
		windowNo=1; men1->show();
		return Fl::run();

}

//==========================================================
//+--L1_INTERFACE
//	 calls languageONE to initialise
//==========================================================
void L1_INTERFACE()
{

		L1_CALL(0,c_Initial,n_financialYear,0,0);

		if (RETURN_CODE!=0)
			{fl_alert("Missing/Full file system");}
		else
			{
				a01_recNo=A01_Record_NO;
				a01_system_recno=A01_Record_NO;
			}

}

//----------------------------------------------------------
//+--Common Function - ACCOUNT SPINNERS
//----------------------------------------------------------
void fACCT_SPINNER_CALLBACK(Fl_Widget* w, void* data){

//	----------------
//	Get the Field Id
//	----------------
		str=(char*)data; x=stoi(str); bool b_AllAccts;

//	-----------------
//	Set the direction
//	-----------------
		if (x>0) {direction=+1;}
		else		 {direction=-1;}

//	------------------
//	Get the account no
//	------------------
		switch (x)
		{
			case  41:
			case -41:
				spinner_acctno=win4_coa_key_acctno->value();
				b01_AllAccts=true;
				break;
			case  42:
			case -42:
				spinner_acctno=win4_coa_details_cntlacctno->value();
				b01_AllAccts=true;
				break;
			case  51:
			case -51:
				spinner_acctno=win5_gj_details_dracctno->value();
				b01_AllAccts=false;
				break;
			case  52:
			case -52:
				spinner_acctno=win5_gj_details_cracctno->value();
				b01_AllAccts=false;
				break;
			case  53:
			case -53:
				spinner_acctno=win5_gj_details_invacctno->value();
				b01_AllAccts=false;
				break;
			case  61:
			case -61:
				spinner_acctno=win6_enq_key_acctno->value();
				b01_AllAccts=false;
				break;
		}

//	-----------------
//	Get the record no
//	-----------------
		spinner_recno=l1_findAcct(spinner_acctno);

//	-----------------------------
//	Find the Next/Previous record
//	-----------------------------
		if (spinner_acctno==0)
		{		L1_CALL(c_B01,c_Start,1,0,b01_AllAccts);}
		else
		{		spinner_recno=l1_findAcct(spinner_acctno);
				if (spinner_recno==99999)
				{ return; }
				else
				{		L1_CALL(c_B01,c_PreviousNext,direction,0,b01_AllAccts);
						if (RETURN_CODE!=0){return;}
				}
		}

//	-------------------------
//	string up the description
//	-------------------------
		str="";for (i=0; i<30; i++) {str = str + B01_Description[i];}

//	-------------------------------------
//	Display the account no and description
//	-------------------------------------
		switch (x)
		{
			case  41:
			case -41:
				win4_coa_key_acctno->value(B01_AcctNo);
				win4_coa_key_acctdesc->value(str.c_str());
				win4_coa->redraw();
				break;
			case  42:
			case -42:
				win4_coa_details_cntlacctno->value(B01_AcctNo);
				win4_coa_details_cntlacctdesc->value(str.c_str());
				win4_coa->redraw();
				break;
			case  51:
			case -51:
				win5_gj_details_dracctno->value(B01_AcctNo);
				win5_gj_details_dracctdesc->value(str.c_str());
				win5_gj->redraw();
				break;
			case  52:
			case -52:
				win5_gj_details_cracctno->value(B01_AcctNo);
				win5_gj_details_cracctdesc->value(str.c_str());
				win5_gj->redraw();
				break;
			case  53:
			case -53:
				win5_gj_details_invacctno->value(B01_AcctNo);
				win5_gj_details_invacctdesc->value(str.c_str());
				win5_gj->redraw();
				break;
			case  61:
			case -61:
				win6_enq_key_acctno->value(B01_AcctNo);
				win6_enq_key_acctdesc->value(str.c_str());
				win6_enq->redraw();
				break;
		}

}

//----------------------------------------------------------
//+--Common Function - REQUEST SEARCH
//----------------------------------------------------------
void fACCT_SEARCH_CALLBACK(Fl_Widget* w, void* data){

//	----------------
//	Get the Field Id
//	----------------
		str=(char*)data; x=stoi(str);

//	-------------------
//	Starting Account No
//	-------------------
		switch (x)
		{
			case 42:
				searchNo=1;
				b99_startAcctNo=win4_coa_details_cntlacctno->value();
				b01_AllAccts=true;
				break;
			case 51:
				searchNo=2;
				b99_startAcctNo=win5_gj_details_dracctno->value();
				b01_AllAccts=false;
				break;
			case 52:
				searchNo=3;
				b99_startAcctNo=win5_gj_details_cracctno->value();
				b01_AllAccts=false;
				break;
			case 53:
				searchNo=4;
				b99_startAcctNo=win5_gj_details_invacctno->value();
				b01_AllAccts=false;
				break;
			case 61:
				searchNo=5;
				b99_startAcctNo=win6_enq_key_acctno->value();
				b01_AllAccts=false;
				break;
		}

		WIN99_ALL_ACCOUNTS();

}

//==========================================================
//		+--
//		+--WINDOW 99 - ACCT SEARCH SELECTION
//==========================================================

//----------------------------------------------------------
//			+--window 99 - populate browser
//----------------------------------------------------------
void WIN99_ALL_ACCOUNTS(){

	x=2, y=0;

	win99_acctselect_browser->clear();

	static int widths[] = { 65, 300 };
	win99_acctselect_browser->column_widths(widths);
	win99_acctselect_browser->column_char('\t');
	i=0;win99Depth=0;

	L1_CALL(c_B01,c_Start,0,0,b01_AllAccts);
	if (RETURN_CODE!=0){return;}

	i=0;
	while (1==1)
	{

		L1_CALL(c_B01,c_PreviousNext,1,0,b01_AllAccts);
		if (RETURN_CODE!=0) {break;}

		if (B01_AcctNo >= b99_startAcctNo)
		{

			i++;

			if (win99Depth<375){win99Depth=win99Depth+15;}

			str1=to_string(B01_AcctNo).c_str();
			str2="";for (j=0; j<30; j++) {str2 = str2 + B01_Description[j];}

			y = remainder(i, x);
			if (y==0)	{str = "@B52@r " + str1 + "\t@B52" + str2;}
			else		{str = "@r " + str1 + "\t" + str2;}
			win99_acctselect_browser->insert(i,str.c_str(),(long long*)B01_Record_NO);
		}
	}
	
	switch (searchNo)
		{
			case 1: x=270; y=270; break;
			case 2: x=270; y=250; break;
			case 3: x=270; y=280; break;
			case 4: x=270; y=270; break;
			case 5: x=270; y=270; break;
		}

	win99_acctselect->resize(x,y,365,win99Depth+75);
	win99_grp->resize(5,50,355,win99Depth);

	win99_acctselect->redraw();
	windowNo=99; win99_acctselect->show();

}

//----------------------------------------------------------
//			+--window 99 - browser selection 
//----------------------------------------------------------
void fWin99_browser_callback(Fl_Widget* w, void* data){

		x=win99_acctselect_browser->value();if (x==0){return;}

		b99_recNo=(long long)win99_acctselect_browser->data(x);

		L1_CALL(c_B01,c_Read,b99_recNo,0,b01_AllAccts);

		str="";for (i=0; i<30; i++) {str = str + B01_Description[i];}

		switch (searchNo)
		{
			case 1:
				win4_coa_details_cntlacctno->value(B01_AcctNo);
				win4_coa_details_cntlacctdesc->value(str.c_str());
				win4_coa->redraw();
				windowNo=4;
				break;

			case 2:
				win5_gj_details_dracctno->value(B01_AcctNo);
				win5_gj_details_dracctdesc->value(str.c_str());
				windowNo=5;
				win5_gj->redraw();
				break;

			case 3:
				win5_gj_details_cracctno->value(B01_AcctNo);
				win5_gj_details_cracctdesc->value(str.c_str());
				windowNo=5;
				win5_gj->redraw();
				break;

			case 4:
				win5_gj_details_invacctno->value(B01_AcctNo);
				win5_gj_details_invacctdesc->value(str.c_str());
				windowNo=5;
				win5_gj->redraw();
				break;

			case 5:
				win6_enq_key_acctno->value(B01_AcctNo);
				win6_enq_key_acctdesc->value(str.c_str());
				windowNo=6;
				win6_enq->redraw();
				break;

		}

		win99_acctselect->hide();

}

//----------------------------------------------------------
//		+--All windows - exit
//----------------------------------------------------------
void _windowExit_callback(Fl_Widget* w, void* data){

		switch (windowNo)
		{
			case 1:	if (fl_choice("Commit changes to database ?","Cancel","No","Yes"))
							{
								if (i==2) {L1_CALL (0,c_Commit,0,0,0);}
								men1->hide();
							}
							break;

			case 2:		men2->hide();
								windowNo=1;
								break;

			case 3: 	if (fromWindowNo==3)
								{
									win3p_sys->hide();
									fromWindowNo=1;
								}
								else
								{	
									win3_sys->hide();	
									fromWindowNo=0; windowNo=1;
								}
									break;

			case 4:		if (fromWindowNo==4)
								{
									win4p_coa->hide();
									fromWindowNo=2;
								}
								else
								{
									if (A01_ParameterNo==3)
									{
										win4p_coa->hide();
										fromWindowNo=1; windowNo=2;
									}
									else
									{
									win4_coa->hide();
									fromWindowNo=1; windowNo=2;
									}
								}
								break;

			case 5: 	if (fromWindowNo==5)
								{
									win5p_gj->hide();
									fromWindowNo=2;
								}
								else
								{
									win5_gj->hide();
									if (fromWindowNo==6)
										{
											L1_CALL(c_B03,c_Enquire,0,enq_acctno,0);
											WIN6_ENQ_ACCOUNTS();
											fromWindowNo=2; windowNo=6;
										}
										else
										{
											fromWindowNo=1; windowNo=2;
										}
								}		
								break;

			case 6:		if (fromWindowNo==6)
								{
									win6p_enq->hide();
									fromWindowNo=2; windowNo=6;
								}
								else
								{	
									win6_enq->hide();	
									fromWindowNo=1; windowNo=2;
								}
									break;

			case 7:		win7p_rep->hide();
								fromWindowNo=1; windowNo=2;
								break;

			case 99:	win99_acctselect->hide();
								switch (searchNo) {
									case 1: windowNo=4; break;
									case 2:
									case 3: 
									case 4: windowNo=5; break; 
									case 5: windowNo=6; break;
								}
								break;

		}

}

