/* -*- 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 "viewervbox.hh"

#include <viewit/event.hh>

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

#include "../pixmaps/viewit_movie_recording.xpm"
#include "../pixmaps/viewit_movie_stop.xpm"

extern CEventQueue	*pending_events;

TViewerVBox::TViewerVBox()
{
	m_pixbuf_recording	= Gdk::Pixbuf::create_from_xpm_data(viewit_movie_recording_xpm);
	m_pixbuf_stop		= Gdk::Pixbuf::create_from_xpm_data(viewit_movie_stop_xpm);

	event_t event;
	event.what = event_t::ev_command; 
	TGLViewerEventInfo *info = new TGLViewerEventInfo(EV_GLVIEWER_GET_STATE); 
	event.info.reset(info);
	pending_events->push(event);
	pending_events->handle_events();

	add_views_options();
	add_snapshot_options(info->get_snapper_available(), info->get_moviemode_enabled());
	add_rotation_options(info->get_rotation_enabled() ? info->get_rotation_speed() : 0.0);
	add_brightness_options(info->get_background_brightness());
}

void TViewerVBox::add_views_options()
{
	m_next_view = Gtk::manage(new class Gtk::Button("next view"));
	m_next_view->set_flags(Gtk::CAN_FOCUS);
	m_next_view->set_border_width(6);
	m_next_view->set_relief(Gtk::RELIEF_NORMAL);

	m_save_view = Gtk::manage(new class Gtk::Button("save view"));
	m_save_view->set_flags(Gtk::CAN_FOCUS);
	m_save_view->set_border_width(6);
	m_save_view->set_relief(Gtk::RELIEF_NORMAL);

	m_save_all_views = Gtk::manage(new class Gtk::Button("save all views"));
	m_save_all_views->set_flags(Gtk::CAN_FOCUS);
	m_save_all_views->set_border_width(6);
	m_save_all_views->set_relief(Gtk::RELIEF_NORMAL);
   
	Gtk::HBox *views_hbox = Gtk::manage(new class Gtk::HBox(false, 0));
	views_hbox->pack_start(*m_next_view, Gtk::PACK_EXPAND_PADDING, 0);
	views_hbox->pack_start(*m_save_view, Gtk::PACK_EXPAND_PADDING, 0);
	views_hbox->pack_start(*m_save_all_views, Gtk::PACK_EXPAND_PADDING, 0);

	Gtk::Label *views_frame_label = Gtk::manage(new class Gtk::Label("Views"));
	views_frame_label->set_alignment(0.5,0.5);
	views_frame_label->set_padding(0,0);
	views_frame_label->set_justify(Gtk::JUSTIFY_LEFT);
	views_frame_label->set_line_wrap(false);
	views_frame_label->set_use_markup(false);
	views_frame_label->set_selectable(false);

	Gtk::Frame *views_frame = Gtk::manage(new class Gtk::Frame());
	views_frame->set_border_width(10);
	views_frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
	views_frame->set_label_align(0,0.5);
	views_frame->add(*views_hbox);
	views_frame->set_label_widget(*views_frame_label);

	m_next_view->show();
	m_save_view->show();
	m_save_all_views->show();
	views_hbox->show();
	views_frame_label->show();
	views_frame->show();

	this->pack_start(*views_frame);
	
	m_next_view->signal_clicked().connect(sigc::mem_fun(*this,&TViewerVBox::on_m_next_view_clicked));
	m_save_view->signal_clicked().connect(sigc::mem_fun(*this,&TViewerVBox::on_m_save_view_clicked));
	m_save_all_views->signal_clicked().connect(sigc::mem_fun(*this,&TViewerVBox::on_m_save_all_views_clicked));
}

void TViewerVBox::add_snapshot_options(bool snapshot_available, bool in_moviemode)
{
	// snapshot button - for the selected view
	m_snapshot = Gtk::manage(new class Gtk::Button("This view"));
	m_snapshot->set_flags(Gtk::CAN_FOCUS);
	m_snapshot->set_border_width(6);
	m_snapshot->set_relief(Gtk::RELIEF_NORMAL);
	m_snapshot->set_sensitive(snapshot_available);
	
	// snapshot button - for all predefined views
	m_snapshot_all_views = Gtk::manage(new class Gtk::Button("All views"));
	m_snapshot_all_views->set_flags(Gtk::CAN_FOCUS);
	m_snapshot_all_views->set_border_width(6);
	m_snapshot_all_views->set_relief(Gtk::RELIEF_NORMAL);
	m_snapshot_all_views->set_sensitive(snapshot_available);
	
	// snapshot button - to create a series of images
	Gtk::Label *movie_label = Gtk::manage(new class Gtk::Label("Movie"));
	movie_label->set_alignment(0.5,0.5);
	movie_label->set_padding(0,0);
	movie_label->set_justify(Gtk::JUSTIFY_LEFT);
	movie_label->set_line_wrap(false);
	movie_label->set_use_markup(false);
	movie_label->set_selectable(false);

	m_movie_image = Gtk::manage(new class Gtk::Image);
	m_movie_image->set_alignment(0.5,0.5);
	m_movie_image->set_padding(0,0);
	m_movie_image->set( in_moviemode ? m_pixbuf_recording : m_pixbuf_stop );
			    
	Gtk::HBox *movie_hbox = Gtk::manage(new class Gtk::HBox(false, 2));
	movie_hbox->pack_start(*m_movie_image, Gtk::PACK_SHRINK, 0);
	movie_hbox->pack_start(*movie_label, Gtk::PACK_SHRINK, 0);
	
	Gtk::Alignment *movie_alignment = Gtk::manage(new class Gtk::Alignment(0.5, 0.5, 0, 0));
	movie_alignment->add(*movie_hbox);

	m_toggle_movie = Gtk::manage(new class Gtk::ToggleButton());
	m_toggle_movie->set_flags(Gtk::CAN_FOCUS);
	m_toggle_movie->set_border_width(6);
	m_toggle_movie->set_relief(Gtk::RELIEF_NORMAL);
	m_toggle_movie->set_active(false);
	m_toggle_movie->set_active(in_moviemode);
	m_toggle_movie->add(*movie_alignment);
	m_toggle_movie->set_sensitive(snapshot_available);
	
	// snapshot hbox - holding the threee snapshot buttons
	
	Gtk::HBox *snapshot_hbox = Gtk::manage(new class Gtk::HBox(false, 0));
	snapshot_hbox->pack_start(*m_snapshot, Gtk::PACK_EXPAND_PADDING, 0);
	snapshot_hbox->pack_start(*m_snapshot_all_views, Gtk::PACK_EXPAND_PADDING, 0);
	snapshot_hbox->pack_start(*m_toggle_movie, Gtk::PACK_EXPAND_PADDING, 0);

	Gtk::Label *snapshots_frame_label = Gtk::manage(new class Gtk::Label("Snapshots"));
	snapshots_frame_label->set_alignment(0.5,0.5);
	snapshots_frame_label->set_padding(0,0);
	snapshots_frame_label->set_justify(Gtk::JUSTIFY_LEFT);
	snapshots_frame_label->set_line_wrap(false);
	snapshots_frame_label->set_use_markup(false);
	snapshots_frame_label->set_selectable(false);

        Gtk::Frame *snapshots_frame = Gtk::manage(new class Gtk::Frame());
	snapshots_frame->set_border_width(10);
	snapshots_frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
	snapshots_frame->set_label_align(0,0.5);
	snapshots_frame->add(*snapshot_hbox);
	snapshots_frame->set_label_widget(*snapshots_frame_label);

	m_toggle_movie->show();
	movie_label->show();
	m_movie_image->show();
	movie_hbox->show();
	movie_alignment->show();
	
	m_snapshot->show();
	m_snapshot_all_views->show();
	
	
	snapshot_hbox->show();
	snapshots_frame_label->show();
	snapshots_frame->show();

	m_snapshot->signal_clicked().connect(sigc::mem_fun(*this,&TViewerVBox::on_m_snapshot_clicked));	
	m_snapshot_all_views->signal_clicked().connect(sigc::mem_fun(*this,&TViewerVBox::on_m_snapshot_all_views_clicked));	
	m_toggle_movie->signal_toggled().connect(sigc::mem_fun(*this, &TViewerVBox::on_m_toggle_movie_clicked) );
	
	this->pack_start(*snapshots_frame);
}

void TViewerVBox::add_rotation_options(float speed)
{
	Gtk::Adjustment *m_rotation_adj = Gtk::manage(new class Gtk::Adjustment(speed, 0, 1.0, 0.05, 0.2, 0.0));
	m_rotation = Gtk::manage(new class Gtk::HScale(*m_rotation_adj));
	m_rotation->set_flags(Gtk::CAN_FOCUS);
	m_rotation->set_update_policy(Gtk::UPDATE_CONTINUOUS);
	m_rotation->set_digits(2);
	m_rotation->set_draw_value(true);
	m_rotation->set_value_pos(Gtk::POS_TOP);

	Gtk::Label *rotation_frame_label = Gtk::manage(new class Gtk::Label("Rotation speed"));
	rotation_frame_label->set_alignment(0.5,0.5);
	rotation_frame_label->set_padding(0,0);
	rotation_frame_label->set_justify(Gtk::JUSTIFY_LEFT);
	rotation_frame_label->set_line_wrap(false);
	rotation_frame_label->set_use_markup(false);
	rotation_frame_label->set_selectable(false);

	Gtk::Frame *rotation_frame = Gtk::manage(new class Gtk::Frame());
	rotation_frame->set_border_width(10);
	rotation_frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
	rotation_frame->set_label_align(0,0.5);
	rotation_frame->add(*m_rotation);
	rotation_frame->set_label_widget(*rotation_frame_label);

	m_rotation->show();
	rotation_frame_label->show();
	rotation_frame->show();

	m_rotation->signal_value_changed().connect(sigc::mem_fun(*this,&TViewerVBox::on_m_rotation_value_changed));
	
	this->pack_start(*rotation_frame);
}

void TViewerVBox::add_brightness_options(float brightness)
{
	Gtk::Adjustment *m_brightness_adj = Gtk::manage(new class Gtk::Adjustment(brightness, 0, 1.0, 0.05, 0.2, 0.0));

	m_brightness = Gtk::manage(new class Gtk::HScale(*m_brightness_adj));
	m_brightness->set_flags(Gtk::CAN_FOCUS);
	m_brightness->set_update_policy(Gtk::UPDATE_CONTINUOUS);
	m_brightness->set_digits(2);
	m_brightness->set_draw_value(true);
	m_brightness->set_value_pos(Gtk::POS_TOP);
   
	Gtk::Label *brightness_frame_label = Gtk::manage(new class Gtk::Label("Background brightness"));
	brightness_frame_label->set_alignment(0.5,0.5);
	brightness_frame_label->set_padding(0,0);
	brightness_frame_label->set_justify(Gtk::JUSTIFY_LEFT);
	brightness_frame_label->set_line_wrap(false);
	brightness_frame_label->set_use_markup(false);
	brightness_frame_label->set_selectable(false);
	
	Gtk::Frame *brightness_frame = Gtk::manage(new class Gtk::Frame());
	brightness_frame->set_border_width(10);
	brightness_frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
	brightness_frame->set_label_align(0,0.5);
	brightness_frame->add(*m_brightness);
	brightness_frame->set_label_widget(*brightness_frame_label);

	m_brightness->show();
	brightness_frame_label->show();
	brightness_frame->show();
		
	m_brightness->signal_value_changed().connect(sigc::mem_fun(*this,&TViewerVBox::on_m_brightness_value_changed));
		
	this->pack_start(*brightness_frame);
}

void TViewerVBox::on_m_next_view_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(EV_GLVIEWER_VIEW_NEXT));
	pending_events->push(event);
}

void TViewerVBox::on_m_save_view_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(EV_GLVIEWER_VIEW_SAVE_THIS));
	pending_events->push(event);
}

void TViewerVBox::on_m_save_all_views_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(EV_GLVIEWER_VIEW_SAVE_ALL));
	pending_events->push(event);
}

void TViewerVBox::on_m_snapshot_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(EV_GLVIEWER_SNAP_THIS));
	pending_events->push(event);
}

void TViewerVBox::on_m_snapshot_all_views_clicked()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(EV_GLVIEWER_SNAP_ALL));
	pending_events->push(event);	
}

void TViewerVBox::on_m_toggle_movie_clicked()
{
	m_movie_image->set( m_toggle_movie->get_active() ? m_pixbuf_recording : m_pixbuf_stop );
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new CEventInfo(EV_GLVIEWER_TOGGLE_MOVIEMODE));
	pending_events->push(event);	
}

void TViewerVBox::on_m_rotation_value_changed()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new TGLViewerEventInfo(EV_GLVIEWER_SET_ROTATION_SPEED,0,m_rotation->get_value(),true,false,false));
	pending_events->push(event);	
}

void TViewerVBox::on_m_brightness_value_changed()
{
	event_t event;
	event.what = event_t::ev_command; 
	event.info = PEventInfo(new TGLViewerEventInfo(EV_GLVIEWER_SET_BG_BRIGHTNESS, m_brightness->get_value(), 0.0, true,false,false));
	pending_events->push(event);	
}


void TViewerVBox::reset() {
	m_rotation->set_value(0.0);
}
