/* -*- mia-c++ -*-
 *
 * This file is part of viewitgui - a library and program for the
 * visualization of 3D data sets. 
 *
 * Copyright (c) Leipzig, Madrid 1999-2013 Mirco Hellmann, Gert Wollny
 *
 * viewitgui 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.
 *
 * viewitgui 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 viewitgui; if not, see <http://www.gnu.org/licenses/>.
 */


#include "options_drawable.hh"

#include <viewit/event.hh>

#include <gtkmm/frame.h>
#include <gtkmm/adjustment.h>
#include <gtkmm/label.h>

extern CEventQueue *pending_events;

GUI_Drawable::GUI_Drawable(Gtk::VBox *box) 
	: m_transparency(NULL), m_clipxy(NULL), m_clipxz(NULL), m_clipyz(NULL)
{
	event_t event;
	event.what = event_t::ev_command; 
	TDrawableEventInfo *info  = new TDrawableEventInfo(EV_DRAWABLE_GET_STATE);
	event.info.reset(info);
	pending_events->push(event);
	pending_events->handle_events();

	add_transparency_options(info->get_transparency());
	add_clipping_options(info->get_clipxy(), info->get_clipxz(), info->get_clipyz(), info->get_clipfree());
	box->pack_start(dynamic_cast<Gtk::Widget&>(*this));
}
	
GUI_Drawable::GUI_Drawable(Gtk::VBox *box, bool has_clipping, bool has_transparency) 
	: m_transparency(NULL), m_clipxy(NULL), m_clipxz(NULL), m_clipyz(NULL), m_clipfree(NULL)
{
	event_t event;
	event.what = event_t::ev_command; 
	TDrawableEventInfo *info = new TDrawableEventInfo(EV_DRAWABLE_GET_STATE);
	event.info.reset(info);
	pending_events->push(event);
	pending_events->handle_events();
	
	if (has_transparency) add_transparency_options(info->get_transparency());
	if (has_clipping) add_clipping_options(info->get_clipxy(), info->get_clipxz(), info->get_clipyz(), info->get_clipfree());
	box->pack_start(* dynamic_cast<Gtk::Widget *>(this));
}

float GUI_Drawable::get_transparency()
{
	return m_transparency->get_value();
}

void GUI_Drawable::add_transparency_options(float transparency)
{
	Gtk::Adjustment *transparency_adj = Gtk::manage(new class Gtk::Adjustment(transparency, 0.0, 1.0, 0.05, 0.1, 0.0));
	m_transparency = Gtk::manage(new class Gtk::HScale(*transparency_adj));
	m_transparency->set_flags(Gtk::CAN_FOCUS);
	m_transparency->set_update_policy(Gtk::UPDATE_CONTINUOUS);
	m_transparency->set_digits(2);
	m_transparency->set_draw_value(true);
	m_transparency->set_value_pos(Gtk::POS_TOP);
	
	Gtk::Label *transparency_frame_label = Gtk::manage(new class Gtk::Label("Transparency"));
	transparency_frame_label->set_alignment(0.5,0.5);
	transparency_frame_label->set_padding(0,0);
	transparency_frame_label->set_justify(Gtk::JUSTIFY_LEFT);
	transparency_frame_label->set_line_wrap(false);
	transparency_frame_label->set_use_markup(false);
	transparency_frame_label->set_selectable(false);
	
	Gtk::Frame *transparency_frame = Gtk::manage(new class Gtk::Frame());
	transparency_frame->set_border_width(10);
	transparency_frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
	transparency_frame->set_label_align(0,0.5);
	transparency_frame->add(*m_transparency);
	transparency_frame->set_label_widget(*transparency_frame_label);

	m_transparency->show();
	transparency_frame_label->show();
	transparency_frame->show();
	this->pack_start(*transparency_frame);
	
	m_transparency->signal_value_changed().connect(sigc::mem_fun(*this, &GUI_Drawable::on_m_transparency_value_changed));
}

void GUI_Drawable::add_clipping_options(bool clip_xy, bool clip_xz, bool clip_yz, bool clip_free)
{
	m_clipxy = Gtk::manage(new class Gtk::ToggleButton("XY"));
	m_clipxy->set_flags(Gtk::CAN_FOCUS);
	m_clipxy->set_relief(Gtk::RELIEF_NORMAL);
	m_clipxy->set_active(clip_xy);

	m_clipxz = Gtk::manage(new class Gtk::ToggleButton("XZ"));
	m_clipxz->set_flags(Gtk::CAN_FOCUS);
	m_clipxz->set_relief(Gtk::RELIEF_NORMAL);
	m_clipxz->set_active(clip_xz);

	m_clipyz = Gtk::manage(new class Gtk::ToggleButton("YZ"));
	m_clipyz->set_flags(Gtk::CAN_FOCUS);
	m_clipyz->set_relief(Gtk::RELIEF_NORMAL);
	m_clipyz->set_active(clip_yz);

	m_clipfree = Gtk::manage(new class Gtk::ToggleButton("Free"));
	m_clipfree->set_flags(Gtk::CAN_FOCUS);
	m_clipfree->set_relief(Gtk::RELIEF_NORMAL);
	m_clipfree->set_active(clip_free);

	Gtk::HBox  *clipping_box = Gtk::manage(new class Gtk::HBox(false, 0));
	clipping_box->set_border_width(8);
	clipping_box->pack_start(*m_clipxy, Gtk::PACK_SHRINK, 4);
	clipping_box->pack_start(*m_clipxz, Gtk::PACK_SHRINK, 4);
	clipping_box->pack_start(*m_clipyz, Gtk::PACK_SHRINK, 4);
	clipping_box->pack_start(*m_clipfree, Gtk::PACK_SHRINK, 4);
	
	Gtk::Label *clipping_frame_label = Gtk::manage(new class Gtk::Label("Clipping"));
	clipping_frame_label->set_alignment(0.5,0.5);
	clipping_frame_label->set_padding(0,0);
	clipping_frame_label->set_justify(Gtk::JUSTIFY_LEFT);
	clipping_frame_label->set_line_wrap(false);
	clipping_frame_label->set_use_markup(false);
	clipping_frame_label->set_selectable(false);
	
	Gtk::Frame *clipping_frame	 = Gtk::manage(new class Gtk::Frame());
	clipping_frame->set_border_width(10);
	clipping_frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
	clipping_frame->set_label_align(0,0.5);
	clipping_frame->add(*clipping_box);
	clipping_frame->set_label_widget(*clipping_frame_label);

	m_clipxy->show();
	m_clipxz->show();
	m_clipyz->show();
	clipping_box->show();
	clipping_frame_label->show();
	clipping_frame->show();
	
	this->pack_start(*clipping_frame);
	
	m_clipxy->signal_toggled().connect(sigc::mem_fun(*this, &GUI_Drawable::on_m_clipxy_clicked) );
	m_clipxz->signal_toggled().connect(sigc::mem_fun(*this, &GUI_Drawable::on_m_clipxz_clicked) );
	m_clipyz->signal_toggled().connect(sigc::mem_fun(*this, &GUI_Drawable::on_m_clipyz_clicked) );
	m_clipfree->signal_toggled().connect(sigc::mem_fun(*this, &GUI_Drawable::on_m_clipfree_clicked) );
}

void GUI_Drawable::on_m_transparency_value_changed()
{
	event_t event;
	event.what = event_t::ev_command; 
	auto info = new TDrawableEventInfo(EV_DRAWABLE_SET_TRANSPARENCY); 
	event.info.reset(info);
	info->set_transparency(m_transparency->get_value());
	pending_events->push(event);
}

void GUI_Drawable::on_m_clipxy_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(m_clipxy->get_active() ? EV_DRAWABLE_XYCLIP_ON : EV_DRAWABLE_XYCLIP_OFF));
	pending_events->push(event);
}

void GUI_Drawable::on_m_clipxz_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(m_clipxz->get_active() ? EV_DRAWABLE_XZCLIP_ON : EV_DRAWABLE_XZCLIP_OFF));
	pending_events->push(event);
}

void GUI_Drawable::on_m_clipyz_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(m_clipyz->get_active() ? EV_DRAWABLE_YZCLIP_ON : EV_DRAWABLE_YZCLIP_OFF));
	pending_events->push(event);
}

void GUI_Drawable::on_m_clipfree_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(m_clipfree->get_active() ? EV_DRAWABLE_FREECLIP_ON : EV_DRAWABLE_FREECLIP_OFF));
	pending_events->push(event);
}

void GUI_Drawable::reset()
{
	if (m_transparency) m_transparency->set_value(1.0);

	if(m_clipxy) {
		m_clipxy->set_active(false);
		m_clipxz->set_active(false);
		m_clipyz->set_active(false);
	}
}
