#include <CtrlLib/CtrlLib.h>
//tabs example- not very correct but might be usuful for learning...

//Step1 - if you want to use layouts - always include something like this
//#define LAYOUTFILE <tabs/Tab1Layout.lay> //"editmask.lay"
#define LAYOUTFILE "c:\MyApps\tabs\editmask.lay"
#include <CtrlCore/lay.h>

//Step 2 - please check that you have LAYOUT(Tab1Layout, 680, 368)
//personally I find renaming layouts faster in text mode...
// rinomina il layout in file editmask con LAYOUT(Tab1Layout, 680, 368)

//Step 3 - the Tab1 class below is pasted from automatically generated by the Designer
//using Alt_C first option "Dialog class"

class Tab1 : public WithTab1Layout<TopWindow> {
public:

	typedef Tab1 CLASSNAME;

	Tab1();
	void AddPlayer(); //callback from Add_Player  button
	void ModifyPlayer(); //callback from Modify_Player  button
	void MaskDefaultValue(); //callback from Clear button
	void PromptCell();
	void FillFieldsFromRow();
	void SortRecord();
};

Tab1::Tab1()
{
    // set the widths of each coloumn
    // arr.ColumnWidths("25 3 5 12 8 8 2 3 3 3 3");
	CtrlLayout(*this, "");
 	              //id, label, width
	arr.AddColumn("Name", "Name", 19);          //0
	arr.AddColumn("Country", "Fed", 4);         //1
	arr.AddColumn("Birthday", "Birthday", 6);   //2
	arr.AddColumn("Gender", "Gender", 3);       //3
	arr.AddColumn("Title", "Title", 4);         //4
	arr.AddColumn("IDFIDE", "ID FIDE", 8);      //5
	arr.AddColumn("RatFIDE", "Rat FIDE", 8);    //6
	arr.AddColumn("IDNat", "ID Nat", 8);        //7
	arr.AddColumn("RatNat", "Rat Nat", 5);      //8
	arr.AddColumn("K", "K", 3);                 //9
	arr.AddColumn("Avail" "Avail?", 4).Ctrls<Option>();  //10
   
    //arr.WhenLeftClick = THISBACK(PromptCell);
	arr.WhenLeftClick = THISBACK(FillFieldsFromRow);
	arr.WhenLeftDouble = THISBACK(SortRecord);


    // color even rows
    arr.EvenRowColor();
    //avoid two identical row
      //arr.NoDuplicating();  //doesn't work! 

    //drop list widget
    editTitle.Add("1", "WGM");
    editTitle.Add("2", "CM");
    editTitle.Add("3", "AA");

    //set the callback for the Add_Player button
    //btnAdd <<= THISBACK(AddPlayer);
    btnAdd <<= THISBACK(AddPlayer);
    btnModify <<= THISBACK(ModifyPlayer);
    btnClear <<= THISBACK(MaskDefaultValue);
    
    //fill with default value
    MaskDefaultValue();
}

void Tab1::SortRecord() // body of the callback 
{ int i;
  i = arr.GetClickColumn();     
  arr.Sort( i );
}

void Tab1::AddPlayer() // body of the callback 
{
    if ( (~editName) == Null) {
       PromptOK("The Name field cannot be empty!");
       return;
    }
	arr.Add(~editName, ~editCountry, ~editBirth,  ~tsex, ~editTitle,
	        ~editFIDEId, ~editFIDERat, ~editNatId, ~editNatRat, ~kcoeff, true); // True==1
	arr.GoEnd();
//	editName <<= editCountry <<= editBirth <<= tsex <<= editTitle <<= editFIDEId <<=
//	        editFIDERat <<= editNatId <<= editNatRat <<=kcoeff <<= Null;
	ActiveFocus(editName);
	MaskDefaultValue();
	
//////////////////////////// This is the problem /////
	App.UpdateInfo(" from tab1!");          //////////
//////////////////////////////////////////////////////
}

void Tab1::ModifyPlayer() // body of the callback 
{   int i;
	int int_row;
	int_row=arr.GetCursor();
    if (int_row < 0) return; // prevent the crash of the application when int_row = -1)
    if ( (~editName) == Null) {
       Exclamation("The Name field cannot be empty!");
       return;
    }
	arr.Set( int_row, 0, ~editName);
	arr.Set( int_row, 1, ~editCountry);
	arr.Set( int_row, 2, ~editBirth);
	arr.Set( int_row, 3, ~tsex);
	arr.Set( int_row, 4, ~editTitle);
	arr.Set( int_row, 5, ~editFIDEId);
	arr.Set( int_row, 6, ~editFIDERat);
	arr.Set( int_row, 7, ~editNatId);
	arr.Set( int_row, 8, ~editNatRat);
	arr.Set( int_row, 9, ~kcoeff);
	
	ActiveFocus(editName);
	MaskDefaultValue();
}


void Tab1::MaskDefaultValue() // body of the callback
{
	editName <<= Null;
	editCountry <<= "--";
	editBirth <<= "00.00.00";
	tsex <<= 1;
	editTitle <<= "GM";
	editFIDEId <<= editFIDERat <<= editNatId <<= editNatRat <<= 0;
	kcoeff <<= 30;
	ActiveFocus(editName);
}

void Tab1::FillFieldsFromRow(){
	int int_row;
	int_row=arr.GetCursor();
    if (int_row < 0) return; // prevent the crash of the application when int_row = -1)
	editName    <<= arr.Get(int_row, "Name");      //0
	editCountry <<= arr.Get(int_row, "Country");   //1
	editBirth   <<= arr.Get(int_row, "Birthday");  //2
	tsex        <<= arr.Get(int_row, "Gender");    //3
	editTitle   <<= arr.Get(int_row, "Title");     //4
	editFIDEId  <<= arr.Get(int_row, "IDFIDE");    //5
	editFIDERat <<= arr.Get(int_row, "RatFIDE");   //6
	editNatId   <<= arr.Get(int_row, "IDNat");     //7
	editNatRat  <<= arr.Get(int_row, "RatNat");    //8
	kcoeff      <<= arr.Get(int_row, "K");         //9
	//optAvail    <<= arr.Get(int_row, 10);     //10 "Avail" doesn't work? ArrayCtrl.cpp line 198 assertion failed
}


void Tab1::PromptCell(){
	String s;
	if (arr.GetCursor()) {
	s=AsString(arr.ReadRow(arr.GetCursor())[arr.GetClickColumn()]);	
	PromptOK(s);
  }
}


//personalized tab (1 child) widget
class LuigiTab : public ParentCtrl {
	Button btn;
	DocEdit doc;
public:

typedef LuigiTab CLASSNAME;
	LuigiTab();
	~LuigiTab(){;}
};

LuigiTab::LuigiTab() {
	btn.SetLabel("Just Button");
	btn.SetRect(20,20,100,25);
	Add(btn);
	//I strongly recommend to learn positioning from Designer- use Ctrl-T!
	doc.LeftPosZ(30, 500).TopPosZ(50, 300);
	Add(doc);

}

//personalized tabs (many -container) widget
class LuigiTabs : public TabCtrl {
	Tab1 tab1;  //Step 4 - this is your new tab!!!
	LuigiTab tab2,tab3; //tab1 removed 
public:

	typedef LuigiTabs CLASSNAME;
	LuigiTabs();
	~LuigiTabs(){;}
};


LuigiTabs::LuigiTabs() {
	tab1.SizePos();
	tab2.SizePos();
	tab3.SizePos();

	Add(tab1,"one");
	Add(tab2,"two");
	Add(tab3,"three");
}

//you can keep this (and more like this) class declarations in one yourApp.h file
class App : public TopWindow {
private:
	bool numbers_enabled;
	//prepare to add your widgets by declaring below...
	MenuBar      menu;
	LuigiTabs    tabs;  //inserted declaration of personalized... - see class
	StatusBar    status;
	InfoCtrl     info1;
public:
	void Exit() {Close();}

	void EnableNumbers()     {numbers_enabled = !numbers_enabled;}
	void ShowNumber(int n)   {UpdateInfo(AsString(n));} //{PromptOK(AsString(n));}
	void TestEdit()          {PromptOK("fromEdit");}  //added  No3 - your func
	void Dummy()             {PromptOK("your function needs to be implemented!");}
	void UpdateInfo(String s)  { info1 = s;}
	//useful to have one dummy function while work in progress...
	//...to fill calling "gaps"
	//add here more funcs to call from menus,,,

	//bar declarations
	void SubSubMenu(Bar& bar);
	void FileMenu(Bar& bar);
	void EditMenu(Bar& bar);
	void HelpMenu(Bar& bar);
	void TopMenus(Bar& bar);
	
	typedef App CLASSNAME;
	
	App();
};

//while all implementations below you can keep in one or more *.cpp files (split by classes) 
void App::SubSubMenu(Bar& bar) {
	for(int i = 0; i < 10; i++)
		bar.Add(AsString(i), THISBACK1(ShowNumber, i));
}


void App::FileMenu(Bar& bar) { //confusing name changed from "Menu" to "File"...
	bar.Add("Enable numbers", THISBACK(EnableNumbers)).Check(numbers_enabled);
	bar.Add(numbers_enabled, "Numbers", THISBACK(SubSubMenu));
	bar.Add("Exit", THISBACK(Exit)).Key(K_CTRL_E);
}


//added No2 - your extra menu item and subItems 
void App::EditMenu(Bar& bar) {
	bar.Add("EditMy_1", THISBACK(TestEdit)).Key(K_CTRL_D);
	bar.Add("Copy", THISBACK(Dummy)).Key(K_CTRL_C);
	bar.Add("Cut", THISBACK(Dummy)).Key(K_CTRL_X);
	bar.Add("Paste", THISBACK(Dummy)).Key(K_CTRL_V);
	//add more items here...
}

void App::HelpMenu(Bar& bar)
{
	bar.Add("Help", THISBACK(Dummy)).Key(K_F1);
	bar.Add("About...", THISBACK(Dummy));
}


void App::TopMenus(Bar& bar){  //row of top menu "labels" - what you see without opening menus...
	bar.Add("File", THISBACK(FileMenu));
	bar.Add("Edit", THISBACK(EditMenu));  //added Step1 - extra menu item on Main & callback
	bar.Add("Help", THISBACK(HelpMenu));
}


App::App()
{
	//initialize your members on App creation (constructor)
	numbers_enabled = true;
	AddFrame(menu);
	menu.Set(THISBACK(TopMenus));

	//use Add not AddFrame -in most cases. use Assistant to see the return values 
	Add(tabs.SizePos());
	
	//status stuff
	status.AddFrame(info1.Width(250));
	AddFrame(status.Height(25));
	info1="info1: Welcome to the Ultimate++ !";
}


GUI_APP_MAIN
{   
  App().Title("Forlano Menu, Tabs and Status -v1").Zoomable().Sizeable().Run();
}
