/*
 *  This file is part of RawTherapee.
 *
 *  Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
 *
 *  RawTherapee 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.
 * 
 *  RawTherapee 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 RawTherapee.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <rtwindow.h>
#include <options.h>
#include <preferences.h>
#include <cursormanager.h>

RTWindow::RTWindow () {

    cacheMgr->init ();

#ifdef GLIBMM_EXCEPTIONS_ENABLED
		try { set_default_icon_from_file (argv0+"/images/logoicon16.png");
		} catch(Glib::Exception& ex) {		printf ("%s\n", ex.what().c_str());	}
#else
 	  {		std::auto_ptr<Glib::Error> error;
				set_default_icon_from_file (argv0+"/images/logoicon16.png", error);
		}
#endif //GLIBMM_EXCEPTIONS_ENABLED

    set_title("RawTherapee "+versionString);
    property_allow_shrink() = true;
    set_default_size(options.windowWidth, options.windowHeight);
    set_modal(false);
    set_resizable(true);
    if (options.windowMaximized)
    	maximize();
    else
    	unmaximize();
    property_destroy_with_parent().set_value(false);
    signal_window_state_event().connect( sigc::mem_fun(*this, &RTWindow::on_window_state_event) );

    mainNB = Gtk::manage (new Gtk::Notebook ());
    mainNB->set_scrollable (true);
    mainNB->signal_switch_page().connect_notify( sigc::mem_fun(*this, &RTWindow::on_mainNB_switch_page) );

    fpanel = new FilePanel ();
    fpanel->setParent (this);

    // decorate tab
    Gtk::HBox* hbf = Gtk::manage (new Gtk::HBox ());
    hbf->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::DIRECTORY, Gtk::ICON_SIZE_MENU)));
    hbf->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_FILEBROWSER"))));
    hbf->set_spacing (2);
    hbf->show_all ();
    mainNB->append_page (*fpanel, *hbf);
    fpanel->signal_expose_event().connect( sigc::mem_fun(*this, &RTWindow::on_expose_event_fpanel) );

    bpanel = new BatchQueuePanel ();
    bpanel->setParent (this);

    // decorate tab
    Gtk::HBox* hbb = Gtk::manage (new Gtk::HBox ());
    hbb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU)));
    hbb->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_BATCHQUEUE"))));
    hbb->set_spacing (2);
    hbb->show_all ();
    mainNB->append_page (*bpanel, *hbb);
    
    
    epanel = new EditorPanel (fpanel);
    epanel->setParent (this);
    // decorate tab
    Gtk::HBox* hbe = Gtk::manage (new Gtk::HBox ());
    hbe->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU)));
    hbe->pack_start (*Gtk::manage (new Gtk::Label("Editor")));
    hbe->set_spacing (2);
    hbe->show_all ();
    mainNB->append_page (*epanel, *hbe);
    mainNB->set_current_page (mainNB->page_num (*fpanel));
    epanel->signal_expose_event().connect( sigc::mem_fun(*this, &RTWindow::on_expose_event_epanel) );


    signal_key_press_event().connect( sigc::mem_fun(*this, &RTWindow::keyPressed) );

    Gtk::VBox* mainBox = Gtk::manage (new Gtk::VBox ());
    mainBox->pack_start (*mainNB);   
    Gtk::HBox* bottomBox = Gtk::manage (new Gtk::HBox ());
    mainBox->pack_start (*bottomBox, Gtk::PACK_SHRINK, 1);

    // filling bottom box
    Gtk::LinkButton* rtWeb = Gtk::manage (new Gtk::LinkButton ("http://rawtherapee.com"));
    Gtk::Button* preferences = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_PREFERENCES")+"..."));
    preferences->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-preferences"), Gtk::ICON_SIZE_BUTTON)));
    preferences->signal_clicked().connect( sigc::mem_fun(*this, &RTWindow::showPreferences) );
    is_fullscreen = false;
    btn_fullscreen = Gtk::manage( new Gtk::Button(M("MAIN_BUTTON_FULLSCREEN")));
    btn_fullscreen->signal_clicked().connect( sigc::mem_fun(*this, &RTWindow::toggle_fullscreen) );
    bottomBox->pack_start (*preferences, Gtk::PACK_SHRINK, 0);
    bottomBox->pack_end (*btn_fullscreen, Gtk::PACK_SHRINK, 4);
    bottomBox->pack_start (*rtWeb, Gtk::PACK_SHRINK, 4);
    bottomBox->pack_start (prLabel );
    prLabel.set_alignment(Gtk::ALIGN_RIGHT);
    bottomBox->pack_start (prProgBar, Gtk::PACK_SHRINK, 4);
    pldBridge = new PLDBridge(&prLabel,&prProgBar);

    Glib::RefPtr<Gtk::RcStyle> style = Gtk::RcStyle::create ();
    style->set_xthickness (0);
    style->set_ythickness (0);    
    rtWeb->modify_style (style);

    add (*mainBox);
    show_all ();

    if(options.tabbedUI)
        epanel->hide_all();
}

void RTWindow::on_realize () {

    Gtk::Window::on_realize ();

    fpanel->setAspect();

    cursorManager.init (get_window());
}

bool RTWindow::on_window_state_event(GdkEventWindowState* event) {
	if (!event->new_window_state) {
		// Window mode
		options.windowMaximized = false;
	}
	else if (event->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) {
		// Fullscreen mode
		options.windowMaximized = true;
	}
	return true;
}

void RTWindow::on_mainNB_switch_page(GtkNotebookPage* page, guint page_num) {
	if (page_num > 1) {
		EditorPanel *ep = (EditorPanel *)mainNB->get_nth_page(page_num);
		ep->setAspect();
	}
}

void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) {

    ep->setParent (this);

    // construct closeable tab for the image
    Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
    hb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::FILE, Gtk::ICON_SIZE_MENU)));
    hb->pack_start (*Gtk::manage (new Gtk::Label (name)));
    Gtk::Button* closeb = Gtk::manage (new Gtk::Button ());
    closeb->set_image (*Gtk::manage(new Gtk::Image (Gtk::Stock::CLOSE, Gtk::ICON_SIZE_MENU)));
    closeb->set_relief (Gtk::RELIEF_NONE);
    closeb->set_focus_on_click (false);
    // make the button as small as possible
    Glib::RefPtr<Gtk::RcStyle> style = Gtk::RcStyle::create ();
    style->set_xthickness (0);
    style->set_ythickness (0);    

    closeb->modify_style (style);
    closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &RTWindow::remEditorPanel) , ep));
    hb->pack_end (*closeb);
    hb->set_spacing (2);
    hb->show_all ();

    mainNB->append_page (*ep, *hb);
    //ep->setAspect ();
    mainNB->set_current_page (mainNB->page_num (*ep));
    mainNB->set_tab_reorderable (*ep, true);

    epanels[ name ] = ep;
    filesEdited.insert ( name );
    fpanel->refreshEditedState (filesEdited);    
}

void RTWindow::remEditorPanel (EditorPanel* ep) {

	//ep->saveOptions ();
	epanels.erase (ep->getFileName());
	filesEdited.erase (ep->getFileName ());
	fpanel->refreshEditedState (filesEdited);

	mainNB->remove_page (*ep);

	if (mainNB->get_current_page () == mainNB->page_num (*bpanel))
		mainNB->set_current_page (mainNB->page_num (*fpanel));
    // TODO: ask what to do: close & apply, close & apply selection, close & revert, cancel
}

bool RTWindow::keyPressed (GdkEventKey* event) {
    if(event->keyval == GDK_F11) {
        toggle_fullscreen();
    }

    if (mainNB->get_current_page() == mainNB->page_num(*fpanel)) {
        return fpanel->handleShortcutKey (event);
    }
    else if (mainNB->get_current_page() == mainNB->page_num(*bpanel)) {
        return false;
    }
    else {
        EditorPanel* ep = (EditorPanel*)mainNB->get_nth_page (mainNB->get_current_page());
        return ep->handleShortcutKey (event);
    }
    return false;
}

void RTWindow::imageDeveloped (Glib::ustring fname) {

//    fpanel->refreshThumbnail (fname);
}

void RTWindow::addBatchQueueJob (BatchQueueEntry* bqe, bool head) {

	std::vector<BatchQueueEntry*> entries;
	entries.push_back(bqe);
    bpanel->addBatchQueueJobs (entries, head);
    fpanel->queue_draw ();
}

void RTWindow::addBatchQueueJobs (std::vector<BatchQueueEntry*> &entries) {

    bpanel->addBatchQueueJobs (entries, false);
    fpanel->queue_draw ();
}

bool RTWindow::on_delete_event(GdkEventAny* event) {


    fpanel->saveOptions ();
    bpanel->saveOptions ();
  //  epanel->saveOptions();

/*    if (fileBrowser->getFileCatalog()->getBatchQueue()->hasJobs()) {
        Gtk::MessageDialog msgd (M("MAIN_MSG_EXITJOBSINQUEUEQUEST"), false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
        msgd.set_secondary_text (M("MAIN_MSG_EXITJOBSINQUEUEINFO"));
        int response = msgd.run ();
        if (response==Gtk::RESPONSE_NO)
            return true;
    }

    editCoord->close ();

    if (options.startupDir==STARTUPDIR_LAST && fileBrowser->lastSelectedDir ()!="")
        options.startupPath = fileBrowser->lastSelectedDir ();
    fileBrowser->close ();
    cacheMgr->closeCache ();
        
      
    options.lastScale = editorPanel->zoomBar->getScale ();
    options.lastCropSize = editorPanel->zoomBar->getCropSize ();
    if (options.showFilePanelState==0 || options.showFilePanelState==2)
        options.fileBrowserHeight = fileBrowser->get_height ();
    options.historyPanelWidth = ppaned->get_position ();
    options.toolPanelWidth = vboxright->get_width();//hpaned->get_width() - hpaned->get_position ();
    options.showHistory  = editorPanel->hidehp->get_active ();
    options.showInfo = editorPanel->info->get_active ();
    options.showClippedHighlights = editorPanel->indclippedh->get_active ();
    options.showClippedShadows = editorPanel->indclippeds->get_active ();
    options.bgcolor = editorPanel->iarea->imageArea->getBGColor ();
    options.lastSaveAsPath = saveAsDialog->getDirectory ();
    options.procQueueEnabled = fileBrowser->getFileCatalog()->getBatchQueue()->isEnabled();
    options.fbArrangement = fileBrowser->getFileCatalog()->getArrangement ();
    options.firstRun = false;
*/
    if (!options.windowMaximized) {
		options.windowWidth = get_width();
		options.windowHeight = get_height();
    }

    Options::save ();
    hide();
    return true;
}

void RTWindow::showPreferences () {

  Preferences *pref = new Preferences (this);
  pref->run ();
  delete pref;
  
  fpanel->optionsChanged ();
}
void RTWindow::setProgress (double p){
	prProgBar.set_fraction (p);
}
void RTWindow::setProgressStr (Glib::ustring str){
	prLabel.set_text ( str );
}
void RTWindow::setProgressState (int state){
	if(state){
		prProgBar.show();
		prLabel.show();
	}else{
		prProgBar.hide();
		prLabel.hide();
	}
}
		
void RTWindow::toggle_fullscreen () {
    if(is_fullscreen){
        unfullscreen();
        is_fullscreen = false;
        btn_fullscreen->set_label(M("MAIN_BUTTON_FULLSCREEN"));
    }
    else {
        fullscreen();
        is_fullscreen = true;
        btn_fullscreen->set_label(M("MAIN_BUTTON_UNFULLSCREEN"));
    }
}

void RTWindow::error (Glib::ustring descr){
	prLabel.set_text ( descr );
}

void RTWindow::SetEditorCurrent()
{
  mainNB->set_current_page (mainNB->page_num (*epanel));
}

void RTWindow::SetMainCurrent()
{
  mainNB->set_current_page (mainNB->page_num (*fpanel));
}

void RTWindow::MoveFileBrowserToMain()
{
    if( fpanel->ribbonPane->get_children().size() ==0)
    {
        FileCatalog *fCatalog = fpanel->fileCatalog;
        epanel->catalogPane->remove(*fCatalog);
        fpanel->ribbonPane->add(*fCatalog);
        fCatalog->enableTabMode(false);
    }
}

void RTWindow::MoveFileBrowserToEditor()
{
    if(epanel->catalogPane->get_children().size() ==0 )
    {
        FileCatalog *fCatalog = fpanel->fileCatalog;
        fpanel->ribbonPane->remove(*fCatalog);
        epanel->catalogPane->add(*fCatalog);
        fCatalog->enableTabMode(true);
        fCatalog->refreshHeight();
    }
}

bool RTWindow::on_expose_event_epanel(GdkEventExpose* event)
{
    if(!options.tabbedUI)
        MoveFileBrowserToEditor();
   return  false;  // Gtk::VBox::on_expose_event(event);
}


bool RTWindow::on_expose_event_fpanel(GdkEventExpose* event)
{
    if(!options.tabbedUI)
        MoveFileBrowserToMain();
   return false; // Gtk::HPaned::on_expose_event(event);
}
