/*
         
    Pos_dialog.cpp implementation of plotting dialog
    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 "Pos_dialog.h"
	//IMPLEMENT_DYNAMIC_CLASS( Pos_Dialog,wxDialog )
	//BEGIN_EVENT_TABLE( Pos_Dialog, wxDialog )
	//END_EVENT_TABLE()


	#define PIg  3.14159265358979323846


	#define RADEG       (180.0/PIg)
    #define DEGRAD      (PIg/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)))

///////////////////////////////////////////////////////////////////////////
Pos_Dialog::Pos_Dialog()
{

}

Pos_Dialog::Pos_Dialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	//this->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVECAPTION ) );
	this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ) );
	this->Centre( wxBOTH );
	center.x = 325;
	center.y = 300;
	n = 0;//counter
	longitud = 0;
	latitud = 0;
	Dlat = 0;
	Dlon = 0;
	pos_point.x = 0;
	pos_point.y = 0;
	for(int a = 0; a < 10; a++)
	{
		point[a].x = 0;
		point[a].y = 0;
	}
	Lat_d = 0;
	Lon_d = 0;
	
	// Connect Events
	this->Connect( wxEVT_PAINT, wxPaintEventHandler( Pos_Dialog::OnPaint ) );
}

void Pos_Dialog::OnPaint(wxPaintEvent& event)
{

	wxPaintDC dc(this);
	wxColour col(100,100,100);
	wxColour rd(255,0,0);
	wxColour bk(0,0,0);
	wxBrush brush(rd);
	wxPen  pen;
	pen.SetColour(col);
	pen.SetStyle(wxLONG_DASH);

	dc.SetPen(pen);
	dc.DrawLine(wxPoint(60,300),wxPoint(590,300));
	dc.DrawLine(wxPoint(325,60),wxPoint(325,600));
	pen.SetColour(bk);
	pen.SetStyle(wxSOLID);
	dc.SetPen(pen);
	dc.SetBrush(brush);
	DrawIntercept(&dc);
	WritePosition(&dc);


}

void Pos_Dialog::DrawIntercept(wxPaintDC * dc)
{
	double azt,intcpt,iee,Lon,Lat;
	wxPoint pos;
	const wxChar * pth;
	////new//////
	wxCharBuffer buffer(320);
	wxString st_buff, st_rest,st_toc;
	const char * ch;
	int a = 0;

	pth = stpath.c_str();
	
	wxFile file;
	if(!file.Open(pth,wxFile::read))
		wxMessageBox(wxT("Couldn't open file"),wxT("Error"));
	else{
		a = file.Length();
		file.Read(buffer.data(),a-1);
		ch = buffer.data();
		file.Close();
	}
	st_buff = wxString::FromAscii(ch);
	st_buff = st_buff.AfterFirst('\n');

 while(!st_buff.IsEmpty())
	{
		st_rest = st_buff;
		st_toc = st_rest.BeforeFirst(' ');
		st_toc.ToDouble(&azt);
		st_rest = st_rest.AfterFirst(' ');
		st_toc = st_rest.BeforeFirst(' ');
		st_toc.ToDouble(&intcpt);
		st_rest = st_rest.AfterFirst(' ');
		st_toc = st_rest.BeforeFirst(' ');
		st_toc.ToDouble(&Lat);
		st_rest = st_rest.AfterFirst(' ');
		st_toc = st_rest.BeforeFirst('\n');
		st_toc.ToDouble(&Lon);

		pos = CalcPoint(azt,intcpt,Lat);
		dc->DrawLine(center,pos);
		DrawPosLine(dc,azt,intcpt,Lat);

		st_buff = st_buff.AfterFirst('\n');
	}

	pos_point = GetIntPoint();
	Lon_d = Lon;
	Lat_d = Lat;
	if(pos_point.x != 0 && pos_point.y != 0)
	{
			pos_point.x -= center.x;
			pos_point.y -= center.y;

	}
	Dlon = pos_point.x / 6.0;
	longitud = Lon + Dlon / 60;
	Dlat = pos_point.y  / 6.0;
	Dlat = Dlat * cosd(Lat);
	latitud = Lat - Dlat / 60;


}

void Pos_Dialog::DrawPosLine(wxPaintDC* dc, double azt, double intcpt,double Lat)
{

	wxPoint pnt[4];
	wxPoint pos, pline, plin;
	double right, left;
	wxColour bk(0,0,0);
	wxPen  oldpen = dc->GetPen();
	wxPen pen;
	pen.SetColour(bk);
	pen.SetStyle(wxSOLID);
	pen.SetWidth(2);
	dc->SetPen(pen);

	double x,y;
	pos = CalcPoint(azt,intcpt,Lat);
	azt = 90 - azt;

	x = 200 * sind(azt) ;
	y = 200 * cosd(azt) ;
	
	pline.x = pos.x + x;
	pline.y = pos.y + y;
	dc->DrawLine(pos,pline);
	DrawApex(dc,pline,azt,intcpt);

	plin.x = pos.x - x;
	plin.y = pos.y - y;
	dc->DrawLine(pos,plin);
	DrawApex(dc,plin,azt,intcpt);
	dc->SetPen(oldpen);

	pnt[0].x = pline.x - (4 * cosd(azt));
	pnt[0].y = pline.y - (4 * sind(azt));
	pnt[1].x = pline.x + (4 * cosd(azt));
	pnt[1].y = pline.y + (4 * sind(azt));
	pnt[2].x = plin.x + (4 * cosd(azt));
	pnt[2].y = plin.y + (4 * sind(azt));
	pnt[3].x = plin.x - (4 * cosd(azt));
	pnt[3].y = plin.y + (4 * sind(azt));
	
	wxRegion reg(4,pnt);
	n++;
	rgn[n] = reg;


}

wxPoint Pos_Dialog::CalcPoint(double azt, double intcpt,double Lat)
{
	wxPoint pos;
	azt = 90 - azt;
	double x,y;
	pix = intcpt  / cosd(Lat) ;//latitudine crescente
	x = pix * cosd(azt) * 6;
	y = pix * sind(azt) * 6;

	pos.x = center.x + x;
	pos.y = center.y - y;

	return pos;
}

void Pos_Dialog::DrawApex(wxPaintDC* dc, wxPoint pnt, double azt, double intcpt)
{
	wxPoint pos, vertx, vert;
	double x,y,xa,ya;

	x = 15 * cosd(azt) ;
	y = 15 * sind(azt) ;

	pos.x = pnt.x + x;
	pos.y = pnt.y - y;

	xa = 6 * cosd(azt + 30);
	ya = 6 * sind(azt + 30);
	
	vertx.x = pos.x - xa;
	vertx.y = pos.y + ya;

	dc->DrawLine(pnt,pos);
	dc->DrawLine(pos,vertx);

	xa = 6 * cosd(azt - 30);
	ya = 6 * sind(azt - 30);

	vert.x = pos.x - xa;
	vert.y = pos.y + ya;
	dc->DrawLine(pos,vert);
	dc->DrawLine(vert,vertx);
}

wxPoint Pos_Dialog::GetIntPoint()
{
	wxRegion region;
	wxPoint iPoint;
	wxPoint pt;
	wxPoint pl;
	wxPoint cx;
	iPoint.x = 0;
	iPoint.y = 0;
	int b ;
	int c = 1;
	int d = n;
	int a = n - 1;
	double dx = 0;
	double dy = 0;


		while (n > 1)
		{
			region =rgn[d];
			if (region.Intersect(rgn[a])!=0)
			{
				a -= 1;
				d -= 1;
				wxRect rect = region.GetBox();
				pt = rect.GetLeftTop();
				pl = rect.GetBottomRight();

				cx.x = (pl.x + pt.x) / 2;
				cx.y = (pl.y + pt.y) / 2;
					
				point[c].x = cx.x;
				point[c].y = cx.y;

				c++;

			}
				if(a == 0) a = n;
				if(d == 0) goto out;
		}
		out:
			for(b = 1; b < c; b++)
			{
				dx = dx + point[b].x;
				dy = dy + point[b].y;
			}
			if(n > 0)
			{
			dx = dx / n ;
			dy = dy / n ;
			}
			iPoint.x = dx;
			iPoint.y = dy;

			return iPoint;
}

void Pos_Dialog::WritePosition(wxPaintDC* dc)
{
	double lon_d,lat_d,d_min;
	int deg, min, sec;
	wxString strlon, strlat,strcomt;
///longitude
	lon_d = Lon_d;
	if(lon_d < 0)
		lon_d = lon_d * (-1);
	deg = floor(lon_d);
	d_min = (lon_d - deg) * 60;
	min = floor(d_min);
	sec = (d_min - min) * 60;
	if(Lon_d >= 0)
	strlon = wxString::Format(_("E %02d : %02d : %02d"),deg,min,sec);
	if(Lon_d < 0)
	strlon = wxString::Format(_("W %02d : %02d : %02d"),deg,min,sec);

	dc->DrawText(strlon,280,610);
//latitude
	lat_d = Lat_d;
	if(lat_d < 0)
		lat_d = lat_d * (-1);
	deg = floor(lat_d);
	d_min = (lat_d - deg) * 60;
	min = floor(d_min);
	sec = (d_min - min) * 60;
	if(Lat_d >= 0)
	strlon = wxString::Format(_("N %02d : %02d : %02d"),deg,min,sec);
	if(Lat_d < 0)
	strlon = wxString::Format(_("S %02d : %02d : %02d"),deg,min,sec);
	dc->DrawText(strlon,30,280);
	/// position longitude
	lon_d = longitud;
	if(lon_d < 0)
		lon_d = lon_d * (-1);
	deg = floor(lon_d);
	d_min = (lon_d - deg) * 60;
	min = floor(d_min);
	sec = (d_min - min) * 60;
	strcomt = _("Position:");
	if(Lon_d >= 0)
	strlon = wxString::Format(_("Lon: E %02d : %02d : %02d"),deg,min,sec);
	if(Lon_d < 0)
	strlon = wxString::Format(_("Lon: W %02d : %02d : %02d"),deg,min,sec);
	dc->DrawText(strcomt,30,580);
	dc->DrawText(strlon,30,595);
	//latitude position
	
	lat_d = latitud;
	if(lat_d < 0)
		lat_d = lat_d * (-1);
	deg = floor(lat_d);
	d_min = (lat_d - deg) * 60;
	min = floor(d_min);
	sec = (d_min - min) * 60;
	if(Lat_d >= 0)
	strlon = wxString::Format(_("Lat : N %02d : %02d : %02d"),deg,min,sec);
	if(Lat_d < 0)
	strlon = wxString::Format(_("Lat : S %02d : %02d : %02d"),deg,min,sec);
	dc->DrawText(strlon,30,610);


}

Pos_Dialog::~Pos_Dialog()
{
	// Disconnect Events
	this->Disconnect( wxEVT_PAINT, wxPaintEventHandler(Pos_Dialog::OnPaint ) );

}
