/*
         
    main.cpp Main implementation file
    Copyright (C) 2011 Enas Giovanni <gio.enas@alice.it>
 
    This file is part of Nautic.

    Nautic is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Nautic is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Nautic.  If not, see <http://www.gnu.org/licenses/>.

 */

#include "main.h"

#define TIMER_ID 1000

// initialize the application
IMPLEMENT_APP(MainApp);

	long iVal;


    #define RADEG       (180.0/PI)
    #define DEGRAD      (PI/180.0)
    #define sind(x)     sin((x)*DEGRAD)
    #define cosd(x)     cos((x)*DEGRAD)
    #define tand(x)     tan((x)*DEGRAD)
    #define asind(x)    (RADEG*asin(x))
    #define acosd(x)    (RADEG*acos(x))
    #define atand(x)    (RADEG*atan(x))
    #define atan2d(y,x) (RADEG*atan2((y),(x)))
////////////////////////////////////////////////////////////////////////////////
// application class implementation
////////////////////////////////////////////////////////////////////////////////

bool MainApp::OnInit()
{
	/*MainDialog * m_dlg = new MainDialog(NULL);
	m_dlg->Show();*/
	SetTopWindow( new MainDialog( NULL ) );
	GetTopWindow()->Show();

	// true = enter the main loop
	return true;
}

////////////////////////////////////////////////////////////////////////////////
// main application frame implementation
////////////////////////////////////////////////////////////////////////////////



BEGIN_EVENT_TABLE(MainDialog, MainDialogBase)
  EVT_TIMER    (wxEVT_TIMER, MainDialog::OnTimer)
  EVT_CHAR_HOOK (MainDialog::OnCharHook)
END_EVENT_TABLE()

/*BEGIN_EVENT_TABLE(MainFrame,MainFrameBase)
    EVT_TIMER(TIMER_ID, MainFrame::OnTimer)
END_EVENT_TABLE()*/


MainDialog::MainDialog(wxWindow *parent) : MainDialogBase( parent )
{

//connect

m_comboBox31->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( MainDialog::OnComboPlan ), NULL, this );
m_comboBox3->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( MainDialog::OnComboStar ), NULL, this );

	bInsertNum = false;
	bUpperLimb = false;
	bSun = false;
	bMoon = false;
	bPlanet = false;
	bStar = false;
	iCount =0;
	ihourval=0;
	iminval=0;
	isecval=0;
	declination=0;
	CoArect=0;
	Tm=0;
	Ts=0;
	truelat = 0;
	truelong = 0;
	parlax = 0;
	smdiam = 0;
	azimuth = 2;
	iYear = 0;
	iMonth = 0;
	iDay = 0;
	iHour = 0;
	iMinute = 0;
	iSeconds = 0;
	isStar = false;
	isPlanet = false;
	m_timer = new wxTimer(this,wxEVT_TIMER);
	m_timer->Stop();
	latitude = 0;
	longitude = 0;

	InitDialog();
}


void MainDialog::InitDialog()
{
	///////////////////formattazione della data////////////////////////////////////////

	time = wxDateTime::Now();
	year = time.GetYear();
	month= time.GetMonth();
	day = time.GetDay();
	wxString strWeekDay =time.Format();
	wxString strWeek=strWeekDay.Left(3);

	if (strWeek==_("lun"))
		strWeek=_("Mon");
	if (strWeek==_("mar"))
		strWeek=_("Tue");
	if (strWeek==_("mer"))
		strWeek=_("Wed");
	if (strWeek==_("gio"))
		strWeek=_("Thu");
	if (strWeek==_("ven"))
		strWeek=_("Fri");
	if (strWeek==_("sab"))
		strWeek=_("Sat");
	if (strWeek==_("dom"))
		strWeek=_("Sun");

	wxString strYear = wxString::Format(_("%d"),year);
	wxString strMonth;
	wxString strDay = wxString::Format(_("%d"),day);
	month = month + 1;
	switch (month)
	{
		case 1:
		strMonth= _("Jan");
		break;

		case 2:
		strMonth= _("Feb");
		break;

		case 3:
		strMonth= _("Mar");
		break;

		case 4:
		strMonth= _("Apr");
		break;

		case 5:
		strMonth= _("May");
		break;

		case 6:
		strMonth= _("Jun");
		break;

		case 7:
		strMonth= _("Jul");
		break;

		case 8:
		strMonth= _("Ago");
		break;

		case 9:
		strMonth= _("Sep");
		break;

		case 10:
		strMonth= _("Oct");
		break;

		case 11:
		strMonth= _("Nov");
		break;

		case 12:
		strMonth= _("Dec");
		break;

	}

	m_choice3->SetStringSelection(strWeek);
	m_choice4->SetStringSelection(strDay);
	m_choice5->SetStringSelection(strMonth);
	m_choice6->SetStringSelection(strYear);
	//////////////////////formattazione ora UTC/////////////////////////////////
	//////////////////leggo file per index error//////////////////////////////
	
	wxFileName dirname;
	const wxChar * pth;
	wxString path;
	wxString buff = wxT("0,0");
	wxCharBuffer buffer(4);

	dirname.AssignHomeDir();
	path = dirname.GetPath(wxPATH_GET_SEPARATOR,wxPATH_UNIX);
	wxString filename = wxT("/inderr");

	wxString my_dir_name = wxT("Index");
	wxString dir_path = path + my_dir_name;

	wxFileName my_dir(dir_path);

label:
	my_dir.Mkdir(dir_path,0777,wxPATH_MKDIR_FULL);

	if(!my_dir.DirExists())
		goto	label;

	filepath = dir_path + filename;
	pth = filepath.c_str();

	wxFile file;
	if(!file.Exists(pth))
		file.Create(pth,false,wxS_IRUSR | wxS_IWUSR);
	if(!file.Exists(pth))
			wxMessageBox(wxT("couldn't create file"),wxT("Error"));
	if(!file.IsOpened())
		file.Open(pth,wxFile::read_write);
	if(!file.IsOpened()){
			wxMessageBox(wxT("couldn't open file"),wxT("Error"));
			goto end;
	}
	else
	{
		if(file.Length()<=0){
			file.Write(buff);
			indxerr = 0.0;
		}
		else{
			int a = file.Length();
			file.SeekEnd(-a);
			file.Read(buffer.data(),a);
			indxerr = atof((const char *)buffer);
		}
	}

	file.Close();
end:
	wxString pos = wxString::Format(_("%2.1f"),indxerr);
	m_textCtrl2421->SetValue(pos);
	return;
}

void MainDialog::OnTimer(wxTimerEvent& event)
{
	timer.SetOwner(this);
	wxDateTime time= wxDateTime::Now();
	wxDateTime timeUTC = time.ToUTC();
	int iUHour=timeUTC.GetHour();
	int iUMin=timeUTC.GetMinute();
	int iUSec=timeUTC.GetSecond();
	wxString strUHour = wxString::Format(_("%d"),iUHour);
	wxString strUMin = wxString::Format(_("%d"),iUMin);
	wxString strUSec = wxString::Format(_("%d"),iUSec);
	m_textCtrl111->SetValue(strUHour);
	m_textCtrl112->SetValue(strUMin);
	m_textCtrl113->SetValue(strUSec);
}
void MainDialog::OnStartTimer( wxCommandEvent& event )
{
	m_timer->Start(1000);
}
void MainDialog::OnStopTimer( wxCommandEvent& event )
{
	m_timer->Stop();
}

void MainDialog::OnPaint(wxPaintEvent& event)
{
	/*wxPaintDC dc(this);
	wxDC& pdc =dc;
	PrepareDC(dc);
	wxPen pen(wxColour(0,0,0));
	wxBrush brush(wxColour(0,0,0),wxTRANSPARENT);
	dc.SetBrush(brush);
	dc.SetPen(pen);
	dc.GetBackground();
	dc.DrawRectangle(wxRect(10, 85, 570, 75));*/
}
///////////////////////////EVENTI TESTO CASELLE LAT LON////////////////////////////////////////////
void MainDialog::OnChar(wxKeyEvent& event)
{
	formatNum(event);
}
void MainDialog::OnCharDeg( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharSec( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharLon( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharDegLon( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharSecLon( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnHrsUTC( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnMinUTC( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnSecUTC( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharLocalHr( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharLocalMin( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharLocalSec( wxKeyEvent& event )
{
	formatOnlyNum(event);
}

///////////////////////////////INSERIMENTO VALORI CASELLE DI TESTO LAT LON/////////////////////////////////
void MainDialog::OnText_Deg_Lat( wxCommandEvent& event )
{
	
	long iVal = 0;
	wxString value=m_textCtrl11->GetValue();
	value.ToLong(&iVal);
	if (iVal>90)
	{
		wxMessageBox(_("Warning, latitude degrees can not exeed 90°"),_("Error"));
		m_textCtrl11->SetValue(_("90"));
	}

}
void MainDialog::OnText_min_Lat(wxCommandEvent& event)
{
	double iVal = 0;
	double lVal = 0;
	const  char * s;
	int a;
	bInsertNum=true;

	wxString value=m_textCtrl12->GetValue();
	value.ToDouble(&lVal);

	if (lVal>60)
	{
		wxMessageBox(_("Warning, latitude minutes can not exeed 60°"),_("Error"));
		m_textCtrl12->SetValue(_("60,00"));
	}
	wxChar ch=',';
	wxString val = value.AfterFirst(ch);
	s = val.mb_str();
	a = atoi(s);
	//wxMessageBox(wxString::Format(_("%s"),s));

	val.ToDouble(&iVal);
	
	a = a * 60;
	a = a / 10;
	
	val = wxString::Format(_("%d"),a);
	m_textCtrl1->SetValue(val);

}
void MainDialog::OnCheckbox(wxCommandEvent& event)
{
	if(m_checkBox1->GetValue()==true)
		bUpperLimb = true;
	else
		bUpperLimb = false;
}
void MainDialog::OnTextMax( wxCommandEvent& event )
{
	/*wxString val;
	wxString value=m_textCtrl12->GetValue();
	val=value;

	val=val.insert(2,1,',');
	m_textCtrl12->SetValue(val);*/
}
void MainDialog::OnText_Sec_Lat(wxCommandEvent& event)
{
	long iVal = 0;
	wxString value=m_textCtrl1->GetValue();
	value.ToLong(&iVal);
	if (iVal>60)
	{
		wxMessageBox(_("Warning, latitude seconds can not exeed 60°"),_("Error"));
		m_textCtrl1->SetValue(_("60"));
	}
}
void MainDialog::OnTextDegLon(wxCommandEvent& event)
{
	long iVal,timeVal;
	iVal = 0;
	timeVal = 0;
	wxString value=m_textCtrl13->GetValue();
	value.ToLong(&iVal);
	if (iVal>180)
	{
		wxMessageBox(_("Warning, longitude degrees can not exeed 180°"),_("Error"));
		m_textCtrl13->SetValue(_("180"));
	}

}
void MainDialog::OnTextMinLon( wxCommandEvent& event )
{
	double iVal = 0;
	double lVal = 0;
	const  char * s;
	int a;
	bInsertNum = true;

	wxString value=m_textCtrl14->GetValue();
	value.ToDouble(&lVal);

	if (lVal>60)
	{
		wxMessageBox(_("Warning, longitude minutes can not exeed 60°"),_("Error"));
		m_textCtrl14->SetValue(_("60,00"));
	}
	wxChar ch=',';
	wxString val = value.AfterFirst(ch);
	s = val.mb_str();
	a = atoi(s);

	val.ToDouble(&iVal);

	a = a * 60;
	a = a / 10;

	val = wxString::Format(_("%d"),a);
	m_textCtrl15->SetValue(val);
}

void MainDialog::OnTextSecLon( wxCommandEvent& event )
{
	long iVal = 0;
	wxString val=_("60");
	wxString value=m_textCtrl15->GetValue();
	value.ToLong(&iVal);
	if (iVal>60)
	{
		//val=value.insert(2,1,',');
		wxMessageBox(_("Warning, longitude seconds can not exeed 60°"),_("Error"));
		m_textCtrl15->SetValue(val);
	}

}
void MainDialog::OnTextUTChrs( wxCommandEvent& event )
{
	long iVal = 0;
	wxString val=_("0");
	wxString value=m_textCtrl111->GetValue();
	value.ToLong(&iVal);
	if (iVal>24)
	{

		wxMessageBox(_("Warning, hours may not be more then 24"),_("Error"));
		m_textCtrl111->SetValue(val);
	}

}
void MainDialog::OnTextUTCmin( wxCommandEvent& event )
{
	long iVal = 0;
	wxString val=_("0");
	wxString value=m_textCtrl112->GetValue();
	value.ToLong(&iVal);
	if (iVal>60)
	{

		wxMessageBox(_("Warning, minutes may not be more then 60"),_("Error"));
		m_textCtrl112->SetValue(val);
	}
}
void MainDialog::OnTextUTCsecs( wxCommandEvent& event )
{
	long iVal = 0;
	wxString val=_("0");
	wxString value=m_textCtrl113->GetValue();
	value.ToLong(&iVal);
	if (iVal>60)
	{

		wxMessageBox(_("Warning, seconds may not be more then 60"),_("Error"));
		m_textCtrl113->SetValue(val);
	}
}
void MainDialog::OnTextLTHrs( wxCommandEvent& event )
{
	long iVal = 0;
	wxString val=_("0");
	wxString value=m_textCtrl1111->GetValue();
	value.ToLong(&iVal);
	if (iVal>24)
	{

		wxMessageBox(_("Warning, hours may not be more then 24"),_("Error"));
		m_textCtrl1111->SetValue(val);
	}
}
void MainDialog::OnTextLTmins( wxCommandEvent& event )
{
	long iVal = 0;
	wxString val=_("0");
	wxString value=m_textCtrl1112->GetValue();
	value.ToLong(&iVal);
	if (iVal>60)
	{

		wxMessageBox(_("Warning, minutes may not be more then 60"),_("Error"));
		m_textCtrl1112->SetValue(val);
	}
}
void MainDialog::OnTextLTsecs( wxCommandEvent& event )
{
	long iVal = 0;
	wxString val=_("0");
	wxString value=m_textCtrl1113->GetValue();
	value.ToLong(&iVal);
	if (iVal>60)
	{

		wxMessageBox(_("Warning, seconds may not be more then 60"),_("Error"));
		m_textCtrl1113->SetValue(val);
	}

}
void MainDialog::OnEyeHt( wxFocusEvent& event )
{
	HCorrection * hcorr;
	double Deg,min,sec;
	Deg = 0;
	min = 0;
	sec = 0;
	double dAltitude,dObsAlt,rAlt,dAltDiff;

	wxString strAltDeg = m_textCtrl241->GetValue();
	strAltDeg.ToDouble(&Deg);
	wxString strAltMin = m_textCtrl244->GetValue();
	strAltMin.ToDouble(&min);
	wxString strAltSec = m_textCtrl243->GetValue();
	strAltSec.ToDouble(&sec);	

	dAltitude = Deg + (min + sec / 60)/60;
	dObsAlt = dAltitude - indxerr / 60;
	parlax = plan_prlx(P_distance,dObsAlt);

	rAlt = 0;
	wxString strRAlt = m_textCtrl245->GetValue();
	strRAlt.ToDouble(&rAlt);
//	if(bSun == false||bMoon ==false||bStar == false || bPlanet == false)
	dTrueAlt = hcorr->stars_corr(rAlt,dObsAlt);

	int iplan = m_comboBox31->GetSelection();

	switch (iplan)
	{
		case 0:
		bSun = true;
		bMoon =false;
		bStar = false;
		bPlanet = false;
		break;

		case 1:
		bSun = false;
		bMoon =true;
		bStar = false;
		bPlanet = false;
		break;

		case 2:
		bSun = false;
		bMoon =false;
		bStar = false;
		bPlanet = true;
		break;

		case 3:
		bSun = false;
		bMoon =false;
		bStar = false;
		bPlanet = true;
		break;

		case 4:
		bSun = false;
		bMoon =false;
		bStar = false;
		bPlanet = true;
		break;

		case 5:
		bSun = false;
		bMoon =false;
		bStar = false;
		bPlanet = true;
		break;

		default:
		bSun = false;
		bMoon =false;
		bStar = true;
		bPlanet = false;
		break;

	}

	if(bSun){
		dTrueAlt = hcorr->sun_corr(rAlt,dObsAlt,iMonth,bUpperLimb);

			}
	if(bMoon){
		dTrueAlt = hcorr->moon_corr(rAlt,parlax,dObsAlt,bUpperLimb);
	//	bMoon = false;
	}
	if(bStar){
		dTrueAlt = hcorr->stars_corr(rAlt,dObsAlt);
		parlax = 0;
	//	bStar = false;
	}
	if(bPlanet){
		dTrueAlt = hcorr->plan_corr(rAlt,dObsAlt,parlax);
	//	bPlanet = false;
	}

		

	int deg;// mn, sc;
	deg = floor(dTrueAlt);
	double res = (dTrueAlt - deg) * 60;

	dAltDiff = (dTrueAlt - altitude) * 60; ///differenza di altitudine
	wxString strdiff = wxString::Format(_("%2.1f"),dAltDiff);
	m_textCtrl246->SetValue(strdiff);
	wxString str = wxString::Format(_("%d° %2.1f"),deg,res);
	m_textCtrl247->SetValue(str);


}

void MainDialog::OnAzOut(wxFocusEvent& event)
{
	UnKnownStar unknown;
	Sun mysun;
	double SDT, azmt, alt;
	wxString starname;
	GetData();

	/////////////////azimuth///////////////////
	azmt = 0;
	wxString strAz = m_textCtrl242->GetValue();
	strAz.ToDouble(&azmt);
	azimuth = azmt;
	//////////////////altitude////////////////////

	alt = dTrueAlt;
	///////////////////SIderal time////////////////////////////
	mysun.GHAAries(iYear,iMonth,iDay,iHour,iMinute,iSeconds);
	SDT = mysun.Ts;
	/////////////////////trovo nome///////////////////////////////////
	starname = unknown.calc_bounds(alt,azmt,SDT,latitude);
	m_textCtrl24211->SetValue(starname);

}

void MainDialog::OnLocal( wxCommandEvent& event )
{
	SetTextOnLTime();
}
void MainDialog::OnUTC( wxCommandEvent& event )
{
	GetUTCfromLocal();
}

void MainDialog::OnComboPlan(wxCommandEvent& event)
{
	isPlanet = true;
	isStar = false;
	m_comboBox3->SetValue(_(""));
}

void MainDialog::OnComboStar(wxCommandEvent& event)
{
	isStar = true;
	isPlanet = false;
	m_comboBox31->SetValue(_(""));
}

////////////////////////////////////SCELTA DEGLI ASTRI///////////////////////////////////////////////////////////

void MainDialog::OnStarChoice()
{
	
	Sun sun;	
	wxString str= m_comboBox3->GetStringSelection();//recupero nome della stella
	GetData();
	bStar = true;
	Stars star;
	sun.GHAAries(iYear,iMonth,iDay,iHour,iMinute,iSeconds);
	Ts =  sun.Ts;
	
	wxString strSign;
	int a=star.stars.GetCount();

	t = (iHour+(iMinute + (iSeconds/ 60.00)) / 60.00) * 15;
	loctime = t + longitude;
	date = wxString::Format(_("%2.0f - %2.0f - %2.0f"),iDay,iMonth,iYear);
	jul = wxString::Format(_("%lf"),sun.jd);
	
	for(int b=0;b<a;b++)	{
		if (str==star.stars[b])
		{
			star.starname = str;
			star.CalcVariation(iYear,iMonth,iDay,iHour,iMinute,iSeconds);
			RA = star.RA; //star.co_asc_rct[b];
			declination = star.declin; //star.dec[b];
			Tm = Ts + RA;
			Tm = fmod(Tm,360);
			LHA = Tm + longitude;
			LHA = fmod(LHA,360);
			lamda = star.lon;
			beta = star.lat;
			parlax = 0;
			smdiam = 0;
			bodyname = star.starname;
			constell =star.constellation;
		}
		
	}

}
void MainDialog::GetData()
{
	////////////////////posizione////////////////////////////////////////

	long deg,min,sec,deglon,minlon,seclon;
	deg = 0;
	min = 0;
	sec = 0;
	deglon = 0;
	minlon = 0;
	seclon = 0;
	wxString strDeg=m_textCtrl11->GetValue();
	wxString strMin=m_textCtrl12->GetValue();
	wxString strSec=m_textCtrl1->GetValue();
	wxString strDeglon=m_textCtrl13->GetValue();
	wxString strMinlon=m_textCtrl14->GetValue();
	wxString strSeclon=m_textCtrl15->GetValue();
	strDeg.ToLong(&deg);
	strMin.ToLong(&min);
	strSec.ToLong(&sec);
	strDeglon.ToLong(&deglon);
	strMinlon.ToLong(&minlon);
	strSeclon.ToLong(&seclon);
	latitude =  deg+(min+(sec/60.0000))/60.0000;
	longitude =  deglon+(minlon+(seclon/60.0000))/60.0000;


	if(m_choice1->GetSelection()==1)
		latitude=  -latitude;
	else
		latitude= +latitude;
	if(m_choice11->GetSelection()==1)
		longitude= -longitude;
	else
		longitude= +longitude;
	////////////////////////fatto latitudine longitudine/////////////////////////////////////////
	//////////////////////tempo tm e local/////////////////////////////
	///calcolo la data e l'ora utc

	wxString strYear=m_choice6->GetStringSelection();
	strYear.ToDouble(&iYear);
	iMonth=m_choice5->GetSelection()+1;

	wxString strDay=m_choice4->GetStringSelection();
	strDay.ToDouble(&iDay);
	wxString strHour=m_textCtrl111->GetValue();

	strHour.ToDouble(&iHour);
	wxString strMinute=m_textCtrl112->GetValue();
	strMinute.ToDouble(&iMinute);

	wxString strSeconds=m_textCtrl113->GetValue();
	strSeconds.ToDouble(&iSeconds);
}

void MainDialog::OnPlanetChoice()
{
	int e;
	wxString str= m_comboBox31->GetStringSelection();//recupero nome dell'oggetto sistema solare
	GetData();
	
	Sun mysun;
	Stars star;
	

	int iChoice = m_comboBox31->GetSelection();
	mysun.GHAAries(iYear,iMonth,iDay,iHour,iMinute,iSeconds);
	t = (iHour+(iMinute + (iSeconds/ 60.00)) / 60.00) * 15;
	loctime = t + longitude;
	date = wxString::Format(_("%2.0f - %2.0f - %2.0f"),iDay,iMonth,iYear);
	jul = wxString::Format(_("%lf"),mysun.jd);

	if(iChoice==0)
	{
		bSun = true;
		declination = mysun.declination;
		Tm = mysun.GHAsun;
		Tm = fmod(Tm,360);
		LHA = Tm + longitude;
		LHA = fmod(LHA,360);
		Ts = mysun.Ts;
		RA = mysun.RA;
		lamda = mysun.lamda;
		beta = mysun.beta;
		parlax = mysun.prlx;
		bodyname = _("Sun");
		constell = mysun.stConst;
		smdiam = 0;

	}

	if(iChoice==1)
	{
		bMoon = true;
		planet.tlat = latitude;
		planet.tlong = longitude;
		planet.objnum = 0;
		e = planet.mainPlanet(iYear,iMonth,iDay,iHour,iMinute,iSeconds);		
		Ts = mysun.Ts;
		RA = planet.RA;
		Tm = Ts + planet.RA;
		Tm = fmod(Tm,360);
		LHA = Tm + longitude;
		LHA = fmod(LHA,360);
		lamda = planet.mlong;
		beta = planet.mlat;
		parlax = planet.prlx;
		smdiam = planet.sdiam;
		declination = planet.Dec;
		bodyname = _("Moon");
		constell = wxString::FromAscii(planet.constellation);


	}
	if(iChoice==2)
	{

		bPlanet = true;
		planet.objnum = 1;
		e = planet.mainPlanet(iYear,iMonth,iDay,iHour,iMinute,iSeconds);
		Ts = mysun.Ts;
		RA = planet.RA;
		Tm = Ts + planet.RA;
		Tm = fmod(Tm,360);
		declination = planet.Dec;
		LHA = Tm + longitude;
		LHA = fmod(LHA,360);
		lamda = planet.plong;
		beta = planet.plat;
		parlax = 0;
		smdiam = 0;
		P_distance = planet.planet_distance;
		bodyname = wxString::FromAscii(planet.bodyname);
		constell = wxString::FromAscii(planet.constellation);


	}
	if(iChoice==3)
	{

		bPlanet = true;
		planet.objnum = 2;
		e = planet.mainPlanet(iYear,iMonth,iDay,iHour,iMinute,iSeconds);
		Ts = mysun.Ts;
		RA = planet.RA;
		Tm = Ts + planet.RA;
		Tm = fmod(Tm,360);
		declination = planet.Dec;
		LHA = Tm + longitude;
		LHA = fmod(LHA,360);
		lamda = planet.plong;
		beta = planet.plat;
		parlax = 0;
		smdiam = 0;
		P_distance = planet.planet_distance;
		bodyname = wxString::FromAscii(planet.bodyname);
		constell = wxString::FromAscii(planet.constellation);
	}
	if(iChoice==4)
	{
		bStar = true;
		planet.objnum = 3;
		e = planet.mainPlanet(iYear,iMonth,iDay,iHour,iMinute,iSeconds);
		Ts = mysun.Ts;
		RA = planet.RA;
		Tm = Ts + planet.RA;
		Tm = fmod(Tm,360);
		declination = planet.Dec;
		LHA = Tm + longitude;
		LHA = fmod(LHA,360);
		lamda = planet.plong;
		parlax = 0;
		smdiam = 0;
		beta = planet.plat;
		bodyname = wxString::FromAscii(planet.bodyname);
		constell = wxString::FromAscii(planet.constellation);
	}
	if(iChoice==5)
	{
		bStar = true;
		planet.objnum = 4;
		e = planet.mainPlanet(iYear,iMonth,iDay,iHour,iMinute,iSeconds);

		Ts = mysun.Ts;
		RA = planet.RA;
		Tm = Ts + planet.RA;
		Tm = fmod(Tm,360);
		declination = planet.Dec;
		LHA = Tm + longitude;
		LHA = fmod(LHA,360);
		lamda = planet.plong;
		beta = planet.plat;
		parlax = 0;
		smdiam = 0;
		bodyname = wxString::FromAscii(planet.bodyname);
		constell = wxString::FromAscii(planet.constellation);
	}
	if(iChoice>5)
		{

		return;
		}
}

void MainDialog::OnCalcHeitht( wxCommandEvent& event )
{
	CalcAltitude();
}


void MainDialog::CalcAltitude()
{

	double Height;

	if(isPlanet)
		OnPlanetChoice();
	if(isStar)
		OnStarChoice();


	/////////////////////////prova altezza quadratica////////////////////////////////
	double x = cosd(LHA) * cosd(declination);
    double y = sind(LHA) * cosd(declination);
    double z = sind(declination);

	double xhor = x * sind(latitude) - z * cosd(latitude);
    double yhor = y;
    double zhor = x * cosd(latitude) + z * sind(latitude);

	azimuth  = atan2d( yhor, xhor ) + 180;
    Height  = atan2d( zhor, sqrt(xhor*xhor+yhor*yhor) );
	altitude = Height;



	wxString strS;
	if(Height>0)
		strS=_("+ ");
	if(Height<0)
		strS=_("- ");
	wxString str=FormatDegrees(Height);
	wxString strHeight=strS+str;

	m_textCtrl24->SetValue(strHeight);
	m_textCtrl242->SetValue(FormatDegrees(azimuth));
}

void MainDialog::OnTextEnter( wxFocusEvent& event ) //index error
{
	//char s[4];
	//char * res, * st;
	double val,rest;
	val = 0;
	rest = 0;
	wxString str = m_textCtrl2421->GetValue();
	str.ToDouble(&val);
	indxerr = val;
	const wxChar * pth = _("");
	wxFile file;
	pth = filepath.c_str();
	if(!file.Open(pth,wxFile::read_write))
		wxMessageBox(wxString::Format( _("Can't find file %s\n"), _("inderr") ));
	else{
		file.Write(wxString::Format(wxT("%2.1f\n"),indxerr));
		file.Close();

	}
}

void MainDialog::OnFocusOut( wxFocusEvent& event )//////
{
	wxString str = m_textCtrl241->GetValue();
	double val = 0;
	str.ToDouble(&val);
	if(val>90)
	{
		str =_("0");
		wxMessageBox(_("Attention, altitude degrees can't exceede 90°"),_("Error"));
		m_textCtrl241->SetValue(str);
	}
}

void MainDialog::OnAltMin( wxFocusEvent& event )//////altitude minute
{
	wxString str = m_textCtrl244->GetValue();
	//wxChar ch =',';
	double val,rest;
	val = 0;
	rest = 0;
	int integer;
	str.ToDouble(&val);
	int len = str.length();
	if(len == 2 &&val>60)
	{
		str =_("60");
		wxMessageBox(_("Attention, altitude minutes can't exceede 60°"),_("Error"));
		m_textCtrl244->SetValue(str);
	}
	if(len == 3&& val > 100)
	{
		val = val / 10;
		integer = floor(val);
		if(integer > 60)
		{
			str= _("60");
			wxMessageBox(_("Attention, altitude minutes can't exceede 60°"),_("Error"));
			m_textCtrl244->SetValue(str);
		}
		else
		{
		rest = val - integer;
		str = wxString::Format(_("%d'"),integer);
		m_textCtrl244->SetValue(str);
		rest = rest * 60;
		rest = floor(rest);
		m_textCtrl243->SetValue(wxString::Format(_("%f"),rest));

		}
	}
}

void MainDialog::OnAltSec( wxFocusEvent& event )
{
	wxString str = 	m_textCtrl243->GetValue();
	long val = 0;
	str.ToLong(&val);
	if(val>60)
	{
			str= _("60");
			wxMessageBox(_("Attention, altitude seconds can't exceede 60°"),_("Error"));
			m_textCtrl243->SetValue(str);
	}

}

void MainDialog::OnCharDiff( wxKeyEvent& event )
{
	formatNum(event);
}
void MainDialog::OnCharAlt( wxKeyEvent& event )
{
	formatOnlyNum(event);
}

void MainDialog::OnCharAltMin( wxKeyEvent& event )//altitude minutes
{
	formatNum(event);
}

void MainDialog::OnCharAltSec( wxKeyEvent& event )
{
	formatOnlyNum(event);
}

void MainDialog::OnCharEHt( wxKeyEvent& event )//eye height
{
	formatNum(event);
}

void MainDialog::OnTextAlt( wxCommandEvent& event )
{


}
void MainDialog::OnInfo( wxCommandEvent& event )
{
	info();
}

void MainDialog::info()
{	
	InfoDlg dlg(this);
	dlg.decl = declination;
	dlg.RA = RA;
	dlg.CoRect = CoArect;
	dlg.GHAa = Ts;
	dlg.body = bodyname;
	dlg.date = date;
	dlg.t = t;
	dlg.jul = jul;
	dlg.loctime = loctime;
	dlg.lon = lamda;
	dlg.lat = beta;
	dlg.GHA = Tm;
	dlg.LHA = LHA;
	dlg.parlax = parlax;
	dlg.alt = altitude;
	dlg.azth = azimuth;
	dlg.sConst = constell;
	dlg.sdiam = smdiam;
	dlg.ShowModal();
}

void MainDialog::OnSave(wxCommandEvent& event)
{
	save();
}

void MainDialog::save()
{
	
	double az,incpt,lat,lon;
	az = azimuth;
	lat = latitude;
	lon = longitude;
	wxString strInt = m_textCtrl246->GetValue();
	strInt.ToDouble(&incpt);

	const wxChar * pth = _("");
	wxFile file;

	pth = filepath.c_str();
	if(!file.Open(pth,wxFile::write_append))
			wxMessageBox(wxString::Format( _("Can't find file %s\n"), _("inderr") ));
	else{
		file.Write(wxString::Format(wxT("%2.1f %2.1f %2.5f %2.5f\n"),az,incpt,lat,lon));
		file.Close();
	}
	
	
	
}
void MainDialog::OnCalcPos( wxCommandEvent& event )
{
	calc_pos();
}

void MainDialog::calc_pos()
{
	Pos_Dialog dlg(this);
	dlg.stpath = filepath;
	dlg.ShowModal();
	truelat = dlg.latitud;
	truelong = dlg.longitud;
	wxString signlat,signlong;

	if(truelat < 0) signlat = _("S ");
	else signlat =_("N ");
	if(truelong < 0) signlong = _("W ");
	else signlong =_("E ");

	wxString strlat = FormatDegrees(truelat);
	wxString strlon = FormatDegrees(truelong);
	strlat = signlat + strlat;
	strlon = signlong + strlon;
	m_textCtrl2422->SetValue(strlat);
	m_textCtrl24221->SetValue(strlon);
}
void MainDialog::OnCancLines(wxCommandEvent& event)
{
	CancLines();
}

void MainDialog::CancLines()
{
	wxString str = wxString::Format(wxT("%2.1f\n"),indxerr);
	wxFile file;
	const wxChar * pth;
	pth = filepath.c_str();
	file.Open(pth,wxFile::write);
	if (file.IsOpened())
	{
		file.Write(str);
	}
	else
		wxMessageBox(wxT("file couldn't be opened"),wxT("Error"));
	file.Close();
}

void MainDialog::OnMeridian(wxCommandEvent& event)
{

	CalcMeridian();
}

void MainDialog::CalcMeridian()
{

	wxString signlat;
	wxString strlat ;
	double Zdistance = 90 - dTrueAlt;
	double Pdistance = 90 - declination;
	if(azimuth > 179 && azimuth < 181)
	{
		truelat = Zdistance + declination;
			if(truelat < 0) signlat = _("S ");
			else signlat =_("N ");
		strlat = FormatDegrees(truelat);
		strlat = signlat + strlat;
		m_textCtrl2422->SetValue(strlat);
	}
	if((azimuth > 359 && azimuth < 360) || (azimuth > 0 && azimuth < 1))
	{
		if(dTrueAlt <= latitude)
		{
			if(declination < 0) {
				declination = fabs(declination);
				signlat = _("S ");
			}
			else signlat =_("N ");

			truelat = dTrueAlt + Pdistance;
			goto out;
		}

		Zdistance = -Zdistance;
		truelat = Zdistance + declination;
			if(truelat < 0) signlat = _("S ");
			else signlat =_("N ");
	out:
		strlat = FormatDegrees(truelat);
		strlat = signlat + strlat;
		m_textCtrl2422->SetValue(strlat);

	}
	else if((azimuth > 1 && azimuth < 179) || (azimuth > 181 && azimuth < 359))
		wxMessageBox(_("No meridian passage"),_("Error"));
	
}

void MainDialog::OnCharHook(wxKeyEvent& event)
{
	//wxWindow * ctrlWin;
	wxWindow *win = FindFocus ();
	if (win == NULL)
		{
		event.Skip ();
		return;
		}
	int ikey = event.GetKeyCode();
	int id = win->GetId();
	bool backward = event.ShiftDown ();
	if (event.GetKeyCode () == WXK_TAB)
		{
		//wxMessageBox(wxString::Format(wxT("You pressed TAB on win %d and code %d"),id, ikey));
		if (backward){
			if(id>=7)
			FindWindow(id - 1)->SetFocus();
		}
		else{
			if(id<=47)
				FindWindow (id + 1)->SetFocus ();
			
		}

		return;
		}
	event.Skip ();

}

////////////////////////////////////////////CALSS INFO DLG//////////////////////////////////////////////////////
InfoDlg::InfoDlg( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : Info_Dlg( parent, id, title, pos, size, style )
{
	decl = 0;
	RA = 0;
	CoRect = 0;
	GHAa = 0;
	body = _("");
	date = _("");
	t = 0;
	jul = _("");
	loctime = 0;
	lon = 0;
	lat = 0;
	GHA = 0;
	LHA = 0;
	parlax = 0;
	alt = 0;
	azth = 0;
	sConst = _("");
	sdiam = 0;

}

void InfoDlg::OnPaintDlgInfo( wxPaintEvent& event )
{
	
	wxPaintDC dc(this);
	m_staticText1->SetLabel(body);
	m_staticText2->SetLabel(date);


	wxString strtime = hrms(t);
	m_staticText3->SetLabel(strtime);

	wxString strltime = hrms(loctime);
	m_staticText4->SetLabel(strltime);

	m_staticText5->SetLabel(jul);

	wxString strTs = dms(GHAa);
	m_staticText6->SetLabel(strTs);

	wxString strRA = dms(RA);
	m_staticText7->SetLabel(strRA);

	wxString strDecl = FormatDegrees(decl);
	m_staticText8->SetLabel(strDecl);

	wxString strLamda = dms(lon);
	m_staticText9->SetLabel(strLamda);

	wxString strBeta = FormatDegrees(lat);
	m_staticText10->SetLabel(strBeta);

	wxString strGHA = dms(GHA);
	m_staticText11->SetLabel(strGHA);

	wxString strLHA = dms(LHA);
	m_staticText12->SetLabel(strLHA);

	wxString strDiam =dms(sdiam);
	m_staticText13->SetLabel(strDiam);

	wxString strPrlx = dms(parlax);
	m_staticText14->SetLabel(strPrlx);

	wxString strAlt =FormatDegs(alt);
	m_staticText15->SetLabel(strAlt);

	int azt = floor(azth);
	wxString strAz = wxString::Format(_("%03d°"),azt);
	m_staticText16->SetLabel(strAz);

	m_staticText17->SetLabel(sConst);

}

wxString InfoDlg::FormatDegrees(float Degrees)
{
	wxString strSign,result,res;
	if (Degrees<0){
			strSign = _("S");
			Degrees = (-1 * Degrees);
	}
	else
			strSign = _("N");

	int integral =floor(Degrees);
	float rest = Degrees-integral;
	rest=rest*60;
	result=wxString::Format(_(" %02d° %0.2f'"),integral,rest);
	res = strSign +  result;
	return res;
}
wxString InfoDlg::hrms(double x)
{
	int h, m;
	long sint, sfrac;
	double s;

	s = x / 15;


	if( s < 0.0 )
		s += 24.0;
	h = (int) s;
	s -= h;
	s *= 60;
	m = (int) s;
	s -= m;
	s *= 60;
	/* Handle shillings and pence roundoff. */
	sfrac = (long) (1000.0 * s + 0.5);
	if( sfrac >= 60000L )
	  {
		sfrac -= 60000L;
		m += 1;
		if( m >= 60 )
		  {
		m -= 60;
		h += 1;
		  }
	  }
	sint = sfrac / 1000;
	sfrac -= sint * 1000;
	wxString result = wxString::Format(_( "%02dh %02dm %02ld.%03lds "), h, m, sint, sfrac );
	return result;
}

wxString InfoDlg::dms(double x)
{
	double s;
	int d, m;

	s = x ;

	if( s < 0.0 )
		{
				s = -s;
		}
	
	d = (int) s;
	s -= d;
	s *= 60;
	//m = (int) s;
	//s -= m;
	//s *= 60;
	wxString str = wxString::Format(_( "%02d°  %02.2f'  "), d, s );
	return str;
	}
wxString InfoDlg::FormatDegs(float Degrees)
{
	wxString strSign,result,res;
	if (Degrees<0){
			strSign = _("-");
			Degrees=-Degrees;
	}
	else
			strSign = _("");


	int integral =floor(Degrees);
	float rest = Degrees-integral;
	rest=rest*60;
	res = wxString::Format(_("%d° %02.1f"),integral,rest);
	result = strSign + res;
	return result;
}
//////////////////////////////////FUNZIONI OWNER//////////////////////////////////////
int MainDialog::GetMonthfromString(int iMon)
{

}
void MainDialog::SendMessage()
{
	wxString ts ,coast,dec,messg,strSign,tm;
	if(declination<0)
				strSign=_("dec = S ");
			else
				strSign=_("dec = N ");
		coast=FormatDegrees(CoArect);
		dec=FormatDegrees(declination);
		ts=FormatDegrees(Ts);
		tm=FormatDegrees(Tm);
			wxMessageBox(_("Ts =  ")+ts+_("  ascn_rect =  ")+coast+strSign+dec+_("  Tm =  ")+tm);
}
bool MainDialog::isNumber(int num)
{
	bool IsNum=false;
	if (num=='1'||num=='2'||num=='3'||num=='4'||num=='5'||num=='6'||num=='7'||num=='8'||num=='9'||num=='0'||num==','||num== WXK_BACK||
		num==WXK_DELETE||num==WXK_TAB|| num == '-'|| num == '+')
		IsNum=true;

	else
		IsNum=false;
	return IsNum;
}

bool MainDialog::isOnlyNumber(int num)
{
	bool IsNum=false;
	if (num=='1'||num=='2'||num=='3'||num=='4'||num=='5'||num=='6'||num=='7'||num=='8'||num=='9'||num=='0'||num== WXK_BACK||
		num==WXK_DELETE||num==WXK_TAB)
		IsNum=true;
	else
		IsNum=false;
	return IsNum;
}
void MainDialog::formatNum(wxKeyEvent& evt)
{
	wxString str;
	if(isNumber(evt.GetKeyCode())==true)
	{
				evt.Skip();
	}

	else
	{
		wxBell();
	}
}
void MainDialog::formatOnlyNum(wxKeyEvent& evt)
{
	wxString str;
	if(isOnlyNumber(evt.GetKeyCode())==true)
	{
				evt.Skip();
	}

	else
	{
		wxBell();
	}
}

void MainDialog::SetTextOnLTime()
{
	ihourval=0;
	iminval=0;
	isecval=0;
	wxString strHrs=m_textCtrl111->GetValue();
	wxString strmin=m_textCtrl112->GetValue();
	wxString strsecs=m_textCtrl113->GetValue();
	wxString strDeg=m_textCtrl13->GetValue();
	wxString strMin=m_textCtrl14->GetValue();
	wxString strScnd=m_textCtrl15->GetValue();
	long a,b,c,al,bl,cl;
	a = 0;
	b = 0;
	c = 0;
	al = 0;
	bl = 0;
	cl = 0;
	strHrs.ToLong(&a);
	strmin.ToLong(&b);
	strsecs.ToLong(&c);
	strDeg.ToLong(&al);
	strMin.ToLong(&bl);
	strScnd.ToLong(&cl);

	int ilseconds_lon,iseconds_UTC;

	ilseconds_lon=(al*240)+(bl*4)+(cl/15);//secondi di longitune in tempo

	iseconds_UTC=(a*3600)+(b*60)+c;//tempo in secondi

	if(m_choice11->GetSelection()==0)
	{
		isecval=ilseconds_lon+iseconds_UTC;
		if(isecval<0)
			isecval=-1*isecval;
		iminval=isecval/60;
		isecval=isecval%60;
		ihourval=iminval/60;
		iminval=iminval%60;
		ihourval=ihourval%24;
	}
	else
	{
isecval=ilseconds_lon-iseconds_UTC;
		if(isecval<0)
			isecval=-1*isecval;
		iminval=isecval/60;
		isecval=isecval%60;
		ihourval=iminval/60;
		iminval=iminval%60;
		ihourval=ihourval%24;

	}
	m_textCtrl1111->SetValue(wxString::Format(_("%d"),ihourval));
	m_textCtrl1112->SetValue(wxString::Format(_("%d"),iminval));
	m_textCtrl1113->SetValue(wxString::Format(_("%d"),isecval));


}
void MainDialog::GetUTCfromLocal()
{
	ihourval=0;
	iminval=0;
	isecval=0;
	wxString strHrs=m_textCtrl1111->GetValue();
	wxString strmin=m_textCtrl1112->GetValue();
	wxString strsecs=m_textCtrl1113->GetValue();
	wxString strDeg=m_textCtrl13->GetValue();
	wxString strMin=m_textCtrl14->GetValue();
	wxString strScnd=m_textCtrl15->GetValue();
	long a,b,c,al,bl,cl;
	a = 0;
	b = 0;
	c = 0;
	al = 0;
	bl = 0;
	cl = 0;
	strHrs.ToLong(&a);
	strmin.ToLong(&b);
	strsecs.ToLong(&c);
	strDeg.ToLong(&al);
	strMin.ToLong(&bl);
	strScnd.ToLong(&cl);

	int ilseconds_lon,iseconds_UTC;

	ilseconds_lon=(al*240)+(bl*4)+(cl/15);//secondi di longitune in tempo

	iseconds_UTC=(a*3600)+(b*60)+c;//tempo in secondi

	if(m_choice11->GetSelection()==0)
	{
		isecval=ilseconds_lon-iseconds_UTC;
		if(isecval<0)
			isecval=-1*isecval;
		iminval=isecval/60;
		isecval=isecval%60;
		ihourval=iminval/60;
		iminval=iminval%60;
		ihourval=ihourval%24;
	}
	else
	{
	isecval=ilseconds_lon+iseconds_UTC;
		if(isecval<0)
			isecval=-1*isecval;
		iminval=isecval/60;
		isecval=isecval%60;
		ihourval=iminval/60;
		iminval=iminval%60;
		ihourval=ihourval%24;

	}
	m_textCtrl111->SetValue(wxString::Format(_("%d"),ihourval));
	m_textCtrl112->SetValue(wxString::Format(_("%d"),iminval));
	m_textCtrl113->SetValue(wxString::Format(_("%d"),isecval));
}
wxString MainDialog::FormatDegrees(float Degrees)
{
	wxString  strSign;
	if (Degrees<0)
			Degrees=-Degrees;

	int integral =floor(Degrees);
	float rest = Degrees-integral;
	rest=rest*60;
	wxString result=wxString::Format(_("%d° %02.1f"),integral,rest);
	return result;
}

double MainDialog::plan_prlx(double distance, double alt)
{
	double parallax = 0.157 / P_distance;
	parallax = parallax * cosd(alt);
	return parallax;
}
/////////////////////////////////FUNZIONI MENU////////////////////////////////////
void MainDialog::OnMenuSave(wxCommandEvent& event)
{
	save();
}
void MainDialog::OnMenuCancel(wxCommandEvent& event)
{
	CancLines();
}
void MainDialog::OnMenuAlt(wxCommandEvent& event)
{
	CalcAltitude();
}
void MainDialog::OnMenuMeridian(wxCommandEvent& event)
{
	CalcMeridian();
}
void MainDialog::OnMenuPlot(wxCommandEvent& event)
{
	calc_pos();
}
void MainDialog::OnMenuInfo(wxCommandEvent& event)
{
	info();
}
void MainDialog::OnMenuAbout(wxCommandEvent& event)
{
	AboutDialog dlg(this);
	dlg.ShowModal();
}

void MainDialog::OnPlot(wxCommandEvent& event)
{
	GetData();
	Plot_dialog dlg(this);
	dlg.dDay = iDay;
	dlg.dHour = iHour;
	dlg.dMinute = iMinute;
	dlg.dSeconds = iSeconds;
	dlg.dYear = iYear;
	dlg.dMonth = iMonth;
	dlg.latitud = latitude;
	dlg.longitud = longitude;
	dlg.ShowModal();

}
/////////////////////////////////FUNZIONI DI CHIUSURA///////////ATAG/////////////////////////
MainDialog::~MainDialog()
{
	m_comboBox31->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( MainDialog::OnComboPlan ), NULL, this );
	m_comboBox3->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( MainDialog::OnComboStar ), NULL, this );
	dTrueAlt = 0;
	
}

void MainDialog::OnCloseDialog(wxCloseEvent& event)
{

	wxString str = wxString::Format(wxT("%2.1f\n"),indxerr);
	wxFile file;
	const wxChar * pth;

	pth = filepath.c_str();
	file.Open(pth,wxFile::write);
	if (file.IsOpened())
	{
		file.Write(str);
	}
	else
		wxMessageBox(wxT("file couldn't be opened"),wxT("Error"));
	file.Close();
	Destroy();
}



