// This program 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 2 of the License, or
// (at your option) any later version.

// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 

// Copyright Liam Girdwood 2003

#include "sky_flat.hh"
#include <libgnomecanvasmm/line.h>

/*! \namespace Vega
* \brief Nova Virtual Sky Engine
*/
namespace Vega
{

/*! \fn SkyFlat::SkyFlat(double x_size, double y_size)
* \param x_size Virtual sky x size
* \param y_size Virtual sky y size
*
* Constructor
*/
SkyFlat::SkyFlat()
{	
	m_spherical = false;
}

/*! \fn SkyFlat::~SkyFlat()
* Destructor
*/
SkyFlat::~SkyFlat()
{
}

void SkyFlat::render_planets()
{
	struct ln_equ_posn equ;
	double ra, dec;
	double ra_offset;
	
	// calc offset
	if (m_is_ra_over)
		ra_offset = MIN_RA;
	else
		ra_offset = m_ra_offset;
	
	if (m_mercury.get_mag(m_JD) < m_clip_mag_max) { 
		m_mercury.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_mercury.set_render_jd(m_JD);
		m_mercury.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
	}		
	
	if (m_venus.get_mag(m_JD) < m_clip_mag_max) { 
		m_venus.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_venus.set_render_jd(m_JD);
		m_venus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
	}
	
	if (m_mars.get_mag(m_JD) < m_clip_mag_max) { 
		m_mars.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_mars.set_render_jd(m_JD);
		m_mars.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
	}
	
	if (m_jupiter.get_mag(m_JD) < m_clip_mag_max) { 
		m_jupiter.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_jupiter.set_render_jd(m_JD);
		m_jupiter.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
	}
	
	if (m_saturn.get_mag(m_JD) < m_clip_mag_max) { 
		m_saturn.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_saturn.set_render_jd(m_JD);
		m_saturn.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
	}
	
	if (m_uranus.get_mag(m_JD) < m_clip_mag_max) { 
		m_uranus.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_uranus.set_render_jd(m_JD);
		m_uranus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
	}
	
	if (m_neptune.get_mag(m_JD) < m_clip_mag_max) { 
		m_neptune.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_neptune.set_render_jd(m_JD);
		m_neptune.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
	}
	
	if (m_pluto.get_mag(m_JD) < m_clip_mag_max) { 
		m_pluto.get_equ_posn(m_JD, ra, dec);
		transform (ra, dec, ra_offset);
		m_pluto.set_render_jd(m_JD);
		m_pluto.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
	}	

	if (m_is_ra_over || m_is_ra_under) {
		
		// get ra offset
		if (m_is_ra_under)
			ra_offset = m_ra_offset + MAX_RA; //rhs
		else
			ra_offset = -MAX_RA; //lhs	
		
			if (m_mercury.get_mag(m_JD) < m_clip_mag_max) { 
				m_mercury.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_mercury.set_render_jd(m_JD);
				m_mercury.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
			}		
			
			if (m_venus.get_mag(m_JD) < m_clip_mag_max) { 
				m_venus.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_venus.set_render_jd(m_JD);
				m_venus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
			}
			
			if (m_mars.get_mag(m_JD) < m_clip_mag_max) { 
				m_mars.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_mars.set_render_jd(m_JD);
				m_mars.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
			}
			
			if (m_jupiter.get_mag(m_JD) < m_clip_mag_max) { 
				m_jupiter.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_jupiter.set_render_jd(m_JD);
				m_jupiter.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
			}
			
			if (m_saturn.get_mag(m_JD) < m_clip_mag_max) { 
				m_saturn.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_saturn.set_render_jd(m_JD);
				m_saturn.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
			}
			
			if (m_uranus.get_mag(m_JD) < m_clip_mag_max) { 
				m_uranus.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_uranus.set_render_jd(m_JD);
				m_uranus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
			}
			
			if (m_neptune.get_mag(m_JD) < m_clip_mag_max) { 
				m_neptune.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_neptune.set_render_jd(m_JD);
				m_neptune.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd); 
			}
			
			if (m_pluto.get_mag(m_JD) < m_clip_mag_max) { 
				m_pluto.get_equ_posn(m_JD, ra, dec);
				transform (ra, dec, ra_offset);
				m_pluto.set_render_jd(m_JD);
				m_pluto.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
			}
		}			
}


/*! \fn void SkyFlat::render_grid()
* 
* Render grid on virtual sky.
*/
void SkyFlat::render_grid()
{
	std::vector<Grid::GridLine> ra_points, ra_overlap_points;
	std::vector<Grid::GridLine> dec_points, dec_overlap_points;
	std::vector<Grid::GridLine>::iterator ra;
	std::vector<Grid::GridLine>::iterator dec;
	Gnome::Canvas::Line* line;
	double ra_offset;
	
	// clip and get lines
	m_grid.clip(m_clip_ra_min, m_clip_dec_min, m_clip_ra_max, m_clip_dec_max);
	std::cout << " ra lines " << m_grid.get_ra_lines(ra_points) << std::endl;
	std::cout << " dec lines " << m_grid.get_dec_lines(dec_points) << std::endl;
	
	// are we overlapping
	if (m_is_ra_over || m_is_ra_under) {
		m_grid.clip(m_clip_ra_min_overlap, m_clip_dec_min, m_clip_ra_max_overlap, m_clip_dec_max);
		m_grid.get_ra_lines(ra_overlap_points, true);
		m_grid.get_dec_lines(dec_overlap_points);
	}
	
	// calc offset
	if (m_is_ra_over)
		ra_offset = MIN_RA;
	else
		ra_offset = m_ra_offset;
	
	// now render ra grid
	for (ra = ra_points.begin(); ra != ra_points.end(); ra++) {
		Gnome::Canvas::Points line_points;

		transform((*ra).x1, (*ra).y1, ra_offset);
		transform((*ra).x2, (*ra).y2, ra_offset);
		line_points.push_back(Gnome::Art::Point((*ra).x1, (*ra).y1));
		line_points.push_back(Gnome::Art::Point((*ra).x2, (*ra).y2));
		line = Gtk::manage(new Gnome::Canvas::Line(*m_grid_group, line_points));
		*line << Gnome::Canvas::Properties::fill_color("grey");		
	}
	
	// render dec grid
	for (dec = dec_points.begin(); dec != dec_points.end(); dec++) {
		Gnome::Canvas::Points line_points;

		transform((*dec).x1, (*dec).y1, ra_offset);
		transform((*dec).x2, (*dec).y2, ra_offset);
		line_points.push_back(Gnome::Art::Point((*dec).x1, (*dec).y1));
		line_points.push_back(Gnome::Art::Point((*dec).x2, (*dec).y2));
		line = Gtk::manage(new Gnome::Canvas::Line(*m_grid_group, line_points));
		*line << Gnome::Canvas::Properties::fill_color("grey");		
	}
	
	if (m_is_ra_over || m_is_ra_under) {
		
		// get ra offset
		if (m_is_ra_under)
			ra_offset = m_ra_offset + MAX_RA; //rhs
		else
			ra_offset = -MAX_RA; //lhs
		
		// now render ra grid
		for (ra = ra_overlap_points.begin(); ra != ra_overlap_points.end(); ra++) {
			Gnome::Canvas::Points line_points;

			transform((*ra).x1, (*ra).y1, ra_offset);
			transform((*ra).x2, (*ra).y2, ra_offset);
			line_points.push_back(Gnome::Art::Point((*ra).x1, (*ra).y1));
			line_points.push_back(Gnome::Art::Point((*ra).x2, (*ra).y2));
			line = Gtk::manage(new Gnome::Canvas::Line(*m_grid_group, line_points));
			*line << Gnome::Canvas::Properties::fill_color("grey");		
		}
		
		// render dec grid
		for (dec = dec_overlap_points.begin(); dec != dec_overlap_points.end(); dec++) {
			Gnome::Canvas::Points line_points;
	
			transform((*dec).x1, (*dec).y1, ra_offset);
			transform((*dec).x2, (*dec).y2, ra_offset);
			line_points.push_back(Gnome::Art::Point((*dec).x1, (*dec).y1));
			line_points.push_back(Gnome::Art::Point((*dec).x2, (*dec).y2));
			line = Gtk::manage(new Gnome::Canvas::Line(*m_grid_group, line_points));
			*line << Gnome::Canvas::Properties::fill_color("grey");		
		}
	}
}

/*! \fn void SkyFlat::render_const_lines()
*
* Render virtual sky constellation lines.
*/
void SkyFlat::render_const_lines()
{
	std::vector<Constellation::ConstLine> lines, overlap_lines;
	std::vector<Constellation::ConstLine>::iterator i;
	Gnome::Canvas::Line* line;
	double ra_offset;
	
	// clip and get lines
	m_constellation.clip(m_clip_ra_min, m_clip_dec_min, m_clip_ra_max, m_clip_dec_max);
	std::cout << " const lines " << m_constellation.get_lines(lines) << std::endl;
	
	// are we overlapping
	if (m_is_ra_over || m_is_ra_under) {
		m_constellation.clip(m_clip_ra_min_overlap, m_clip_dec_min, m_clip_ra_max_overlap, m_clip_dec_max);
		m_constellation.get_lines(overlap_lines);
	}
	
	// calc offset
	if (m_is_ra_over)
		ra_offset = MIN_RA;
	else
		ra_offset = m_ra_offset;
	
	// now render each line
	for (i = lines.begin(); i != lines.end(); i++) {
		Gnome::Canvas::Points line_points;

		transform((*i).ra1, (*i).dec1, ra_offset);
		transform((*i).ra2, (*i).dec2, ra_offset);
		line_points.push_back(Gnome::Art::Point((*i).ra1, (*i).dec1));
		line_points.push_back(Gnome::Art::Point((*i).ra2, (*i).dec2));
		line = Gtk::manage(new Gnome::Canvas::Line(*m_const_group, line_points));
		*line << Gnome::Canvas::Properties::fill_color("blue");		
	}
	
	if (m_is_ra_over || m_is_ra_under) {
		
		// get ra offset
		if (m_is_ra_under)
			ra_offset = m_ra_offset + MAX_RA; //rhs
		else
			ra_offset = -MAX_RA; //lhs
		
		// now render ra grid
		for (i = overlap_lines.begin(); i != overlap_lines.end(); i++) {
			Gnome::Canvas::Points line_points;
	
			transform((*i).ra1, (*i).dec1, ra_offset);
			transform((*i).ra2, (*i).dec2, ra_offset);
			line_points.push_back(Gnome::Art::Point((*i).ra1, (*i).dec1));
			line_points.push_back(Gnome::Art::Point((*i).ra2, (*i).dec2));
			line = Gtk::manage(new Gnome::Canvas::Line(*m_const_group, line_points));
			*line << Gnome::Canvas::Properties::fill_color("blue");		
		}
	}
}

/*! \fn void SkyFlat::render_const_bounds()
*
* Render virtual sky constellation boundaries
*/
void SkyFlat::render_const_bounds()
{
}

/*! \fn void SkyFlat::render_const_names()
*
* Render virtual sky constellation names.
*/
void SkyFlat::render_const_names()
{
}


/*! \fn void SkyFlat::get_position (double x, double y, double& ra, double& dec);
* \brief get sky ra,dec at x,y coordinates
*/
void SkyFlat::get_position (double x, double y, double& ra, double& dec)
{
	if (m_clip_dec_min <= MIN_DEC) 
		dec = m_clip_dec_max - (y / m_dec_ppd);
	else
		dec = m_clip_dec_min + ((m_canvas_height - y) / m_dec_ppd);
	
	if (dec < MIN_DEC)
		dec = MIN_DEC;
	if (dec > MAX_DEC)
		dec = MAX_DEC;
	
	// is ra overlapping
	if (m_is_ra_over) {
		ra = m_clip_ra_min + ((m_canvas_width - x) / m_ra_ppd);
		
		if (ra < MIN_RA)
			ra = MIN_RA;
		if (ra > MAX_RA)
			ra -= MAX_RA;
		return;
	}
	
	// is ra underlapping
	if (m_is_ra_under) {
		ra = (m_clip_ra_min + m_ra_offset) + ((m_canvas_width - x) / m_ra_ppd);
		
		if (ra < MIN_RA)
			ra += MAX_RA;
		if (ra > MAX_RA)
			ra = MAX_RA;
		return;
	}
	
	ra = m_clip_ra_min + ((m_canvas_width - x) / m_ra_ppd);
	if (ra < MIN_RA)
		ra = MIN_RA;
	if (ra > MAX_RA)
		ra = MAX_RA;
}


/*! \fn void SkyFlat::transform(double& x, double& y, Castor::AstroObject* object)
* \param x X coordinate
* \param y Y coordinate
* \param object Astro object
* \param sector Sky overlap section
*
* Transform the objects RA and DEC into virtual sky coordinates.
*/
void SkyFlat::transform(double& x, double& y, double ra_offset)
{
	x = m_canvas_width - ((x - m_clip_ra_min - ra_offset) * m_ra_ppd);
	y = m_canvas_height - ((y - m_clip_dec_min - m_dec_offset) * m_dec_ppd);
}

/*! \fn virtual bool is_visible(double x, double y) = 0;
* Is the object visible ?
*/
bool SkyFlat::is_visible(double x, double y)
{
	if (x > m_canvas_width || x < 0)
		return false;
	if (y > m_canvas_height || y < 0)
		return false;
	return true;
}

void SkyFlat::render_basic()
{
}

}


syntax highlighted by Code2HTML, v. 0.9.1