/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "uPlot.h"

//#ifndef QT_NO_OPENGL
//#include <QGLWidget>
//#endif

#include <QAction>
#include <QComboBox>
#include <QCursor>
//#include <QDebug>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QHBoxLayout>
#include <QLabel>
#include <QMenu>
#include <QMessageBox>
#include <QPushButton>
#include <QSettings>
#include <QSplitter>
#include <QStatusBar>
#include <QStringList>
#include <QTabWidget>
#include <QTimer>
#include <QToolBar>
#include <QToolButton>
#include <QVBoxLayout>
#include <QWidgetAction>

#include "MgQPlotScene.h"
#include "MgQRootItem.h"
#include "MgQSceneItem.h"

#include "ExportDialog.h"

#include "MvQAbout.h"
#include "MvQApplication.h"
#include "MvQCursorDataWidget.h"
#include "MvQDataWidget.h"
#include "MvQKeyProfileTree.h"
#include "MvQLayerModel.h"
#include "MvQLayerWidget.h"
#include "MvQMagnifier.h"
#include "MvQPlaceMarkWidget.h" 
#include "MvQPlotView.h"
#include "MvQProgressBarPanel.h"
#include "MvQProgressManager.h"
#include "MvQStepModel.h"
#include "MvQStepWidget.h"
#include "MvQTreeView.h"
#include "MvQZoomStackWidget.h"

#include "MvKeyProfile.h"

#include "MagPlusService.h"
#include "ObjectList.h"
#include "PlotModView.h"
#include "Root.h"
#include "ShareTargets.h"

void MvQSceneComboBox::hidePopup()
{
	QComboBox::hidePopup();
	emit cursorLeft();
}  


uPlot::uPlot(QWidget *parent) : uPlotBase(parent),
//				progressItem_(0),
				weatherRoom_(false)
{
	setAttribute(Qt::WA_DeleteOnClose);
	
	setWindowTitle("Metview - uPlot");

	//Initial size
	setInitialSize(1200,760);

#ifdef METVIEW_WEATHER_ROOM
   //Check if weather room is enabled	
   if(char *wr=getenv("MV_WEATHER_ROOM"))
   {
      if(strcmp(wr,"1") == 0)
         weatherRoom_=true;
   }
#endif

	//---------------------
	// The view
	//---------------------

	connect(plotView_,SIGNAL(zoomActionStarted(MgQSceneItem*)),
		this,SLOT(slotSetActiveScene(MgQSceneItem*)));	
				
	//-------------------	
	// Frames widget
	//-------------------

	stepWidget_ = new MvQStepWidget;	

    //connect(stepWidget_->view(),SIGNAL(activated(QModelIndex)),
    connect(stepWidget_->view(),SIGNAL(selectionChanged(QModelIndex)),
		this,SLOT(slotStepTo(QModelIndex)));

	connect(stepWidget_,SIGNAL(keyProfileChanged(MvKeyProfile*)),
		plotView_,SLOT(slotFrameProfileChanged(MvKeyProfile*)));

	//-------------------	
	// Layer content swidget
	//-------------------

	layerWidget_ = new MvQLayerWidget(plotScene_,plotView_);
     
	connect(layerWidget_,SIGNAL(layerTransparencyChanged(QString,int)),
                this, SLOT(slotLayerTransparencyChanged(QString,int)));

    connect(layerWidget_,SIGNAL(layerVisibilityChanged(QString,bool)),
                this, SLOT(slotLayerVisibilityChanged(QString,bool)));

    connect(layerWidget_,SIGNAL(layerStackingOrderChanged(QList<QPair<QString,int> >)),
                this, SLOT(slotLayerStackingOrderChanged(QList<QPair<QString,int> >)));

    connect(layerWidget_, SIGNAL(sendDropRequest(MvRequest*)),
        QApplication::instance(), SLOT(processDropRequest(MvRequest* )));

	//-------------------	
	// Layers data widget
	//-------------------
	
	dataWidget_ = new MvQDataWidget(plotScene_,plotView_);
	
	//-------------------------------	
	//
	//
	//-------------------------------
	
	//-------------------	
	// Placemarks widget
	//-------------------
	
	//Create placeMarker model and view	
	placeMarkWidget_ = new MvQPlaceMarkWidget(plotScene_,plotView_);

	plotView_->setPlaceMark(placeMarkWidget_);
		
	//-----------------------------------
	// Control widget
	//-----------------------------------
	
	controlWidget_=new QWidget;
	QVBoxLayout *controlLayout=new QVBoxLayout;
	controlLayout->setContentsMargins(0,0,0,0);
	controlWidget_->setLayout(controlLayout);
		
	// Scene selection	
	sceneWidget_=new QWidget;
	QLabel *label=new QLabel(tr("Active scene:"));
	sceneCb_ = new MvQSceneComboBox;
	
	QHBoxLayout *hb= new QHBoxLayout;
	sceneWidget_->setLayout(hb);
	hb->addWidget(label);
	hb->addWidget(sceneCb_);
	hb->addStretch(1.);
	
	sceneWidget_->hide();
	controlLayout->addWidget(sceneWidget_);
	
	connect(sceneCb_,SIGNAL(activated(int)),
		this,SLOT(slotSetActiveScene(int)));	
	
	connect(sceneCb_,SIGNAL(highlighted(int)),
		this,SLOT(slotHighlightScene(int)));
		
	connect(sceneCb_,SIGNAL(cursorLeft()),
		this,SLOT(slotNotHighlightScene()));

	
	//Control tab containing the widgets defined above
	controlTab_ = new QTabWidget;
	controlLayout->addWidget(controlTab_,1);
		
	controlTab_->addTab(stepWidget_,tr("Frames"));
	controlTab_->addTab(layerWidget_,tr("Layers"));
	controlTab_->addTab(dataWidget_,tr("Data"));

#ifdef PLACEMARK
	controlTab_->addTab(placeMarkWidget_,tr("Placemarks"));
#endif

#ifdef METVIEW_EXPERIMENTAL
	//controlTab_->addTab(cursorWidget_,tr("Cursor Data"));
#endif			
	connect(controlTab_,SIGNAL(currentChanged(int)),
		this,SLOT(slotControlTabChanged(int)));
			
	stepWidget_->init(plotScene_,"");
	//placeMarkerWidget_->init(plotScene_);
	
	//Plot rescale
	connect(this,SIGNAL(plotScaleChanged()),
		this,SLOT(slotPlotScaleChanged()));

	actionContextSelectScene_=0;
	actionContextZoomUp_=0;
	actionContextZoomDown_=0;
		
	//Setup the actions
	setupFileActions();
   setupShareActions();
	setupViewActions();
	setupAnimationActions();
	setupZoomActions();
	setupToolsActions();
	setupHelpActions();
   //setupProgressBarActions();
   setupMenus(menuItems_);
   setupProgressBarActions();
   
	//------------------------------
	// uPlot area
	//------------------------------

	mainSplitter_ = new QSplitter;
	mainSplitter_->setOpaqueResize(false);

	mainSplitter_->addWidget(plotView_);
	mainSplitter_->addWidget(controlWidget_);
	mainSplitter_->setCollapsible(1,false);

	//Set splitter initial size
	int spWidth=mainSplitter_->size().width();
	if(spWidth > 0)
	{
		QList<int> spSize;
		spSize << spWidth*0.75;
		spSize << spWidth-spSize[0];
		mainSplitter_->setSizes(spSize);
	}

	//Define the whole lot as central widget
	setCentralWidget(mainSplitter_);

	//Read qt geometry settings
	readSettings();
}

uPlot::~uPlot()
{
	//Save qt geometry settings
	writeSettings();
}

void uPlot::setupFileActions()
{
	//Print
	QAction *actionPrint = new QAction(this);
        actionPrint->setObjectName(QString::fromUtf8("actionPrint"));
        QIcon icon;
        icon.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/print.svg")), QIcon::Normal, QIcon::Off);
        actionPrint->setIcon(icon); 
	actionPrint->setText(tr("&Print"));
        actionPrint->setShortcut(tr("Ctrl+P"));

	//Export
	QAction *actionExport = new QAction(this);
        actionExport->setObjectName(QString::fromUtf8("actionExport"));
        QIcon icon1;
        icon1.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/filesaveas.svg")), QIcon::Normal, QIcon::Off);
	actionExport->setIcon(icon1); 
	actionExport->setText(tr("&Export"));
        actionExport->setShortcut(tr("Ctrl+S"));

	//Generate Macro
	QAction *actionMacro = new QAction(this);
        actionMacro->setObjectName(QString::fromUtf8("actionMacro"));
        QIcon icon2;
        icon2.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/macro.svg")), QIcon::Normal, QIcon::Off);
        actionMacro->setIcon(icon2); 
	actionMacro->setText(tr("Generate &Macro"));
        actionMacro->setShortcut(tr("Ctrl+M"));

	//Exit
	/*QAction* actionExit = new QAction(this);
        actionExit->setObjectName(QString::fromUtf8("actionExit"));
	actionExit->setText(tr("Exit"));
	fileActions_.push_back(actionExit);*/
	
	connect(actionExport,SIGNAL(triggered()),
		this,SLOT(slotLoadExportDialog()));

	connect(actionPrint,SIGNAL(triggered()),
		this,SLOT(slotLoadPrintDialog()));

	connect(actionMacro,SIGNAL(triggered()),
		this,SLOT(slotGenerateMacro()));

	MvQMainWindow::MenuType menuType=MvQMainWindow::FileMenu;	
		
	menuItems_[menuType].push_back(new MvQMenuItem(actionExport));
	menuItems_[menuType].push_back(new MvQMenuItem(actionPrint));
	menuItems_[menuType].push_back(new MvQMenuItem(actionMacro));
}

void uPlot::setupShareActions()
{
   MvQMainWindow::MenuType menuType=MvQMainWindow::ShareMenu;

#ifdef METVIEW_WEATHER_ROOM
   //Weather room connection
   if(weatherRoom_)
   {
      // Add video wall export action
      QAction *actionWroom = new QAction(this);
      actionWroom->setObjectName(QString::fromUtf8("actionWroom"));
      actionWroom->setIcon(QPixmap(QString::fromUtf8(":/uPlot/videowall.svg")));
      actionWroom->setText(tr("Export to video wall"));

      connect(actionWroom,SIGNAL(triggered()),
              this,SLOT(slotLoadWeatherRoomDialog()));

      menuItems_[menuType].push_back(new MvQMenuItem(actionWroom,MvQMenuItem::MenuTarget));

      // Add video wall synchronisation action
      QAction *actionWroomSync = new QAction(this);
      actionWroomSync->setObjectName(QString::fromUtf8("actionWroomSync"));
      actionWroomSync->setCheckable(true);
      actionWroomSync->setChecked(false);
      QIcon icon;
      icon.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/videowall_sync.svg")), QIcon::Normal, QIcon::Off);
      actionWroomSync->setIcon(icon);
      actionWroomSync->setText(tr("Synchronise to video wall"));

      connect(actionWroomSync,SIGNAL(toggled(bool)),
              this,SLOT(slotEnableWroomSync(bool)));

      menuItems_[menuType].push_back(new MvQMenuItem(actionWroomSync,MvQMenuItem::MenuTarget));
   }
#endif

#ifdef METVIEW_SHARE_PLOT
   ShareTargetManager* sts = ShareTargetManager::instance();

   // Add a separator
   if ( sts->size() > 0 )
   {
      QAction *actionSt = new QAction(this);
      actionSt->setSeparator(true);
      menuItems_[menuType].push_back(new MvQMenuItem(actionSt,MvQMenuItem::MenuTarget));
   }

   // Add share icons to the ui
   for (size_t i = 0; i < sts->size(); i++)
   {
      ShareTarget* st = sts->at(i);

      // Add action
      QAction *actionSt = new QAction(this);
      actionSt->setObjectName(QString::fromUtf8(st->name().c_str()));
      std::string iconname = ":/uPlot/" + st->icon();
      actionSt->setIcon(QPixmap(QString::fromUtf8(iconname.c_str())));
      actionSt->setText(tr(st->name().c_str()));
      actionSt->setData((int)i);

      connect(actionSt,SIGNAL(triggered()),
              this,SLOT(slotShareTarget()));

      menuItems_[menuType].push_back(new MvQMenuItem(actionSt,MvQMenuItem::MenuTarget));
   }
#endif

   // Metview-ecCharts connection
   if( getenv("METVIEW_ECCHARTS") )
   {
      // Generate ecCharts layer
      QAction *actionEcCharts = new QAction(this);
      actionEcCharts->setObjectName(QString::fromUtf8("actionEcCharts"));
      QIcon icon3;
      icon3.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/videowall.svg")), QIcon::Normal, QIcon::Off);
      actionEcCharts->setIcon(icon3); 
      actionEcCharts->setText(tr("&Export ecCharts"));
      actionEcCharts->setShortcut(tr("Ctrl+E"));

      connect( actionEcCharts,SIGNAL(triggered()),
               this,SLOT(slotLoadEcChartsDialog()) );

      menuItems_[menuType].push_back(new MvQMenuItem(actionEcCharts));
   }
}

void uPlot::setupToolsActions()
{
	//Antialias
        actionAntialias_ = new QAction(this);
        actionAntialias_->setObjectName(QString::fromUtf8("actionAntialias"));
        actionAntialias_->setCheckable(true);
        actionAntialias_->setChecked(false);
        QIcon icon2;
        icon2.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/antialias.svg")), QIcon::Normal, QIcon::Off);
        actionAntialias_->setIcon(icon2);
 	actionAntialias_->setText(tr("Antialias"));
        actionAntialias_->setShortcut(tr("Ctrl+L"));	
	//controlActions_.push_back(actionAntialias_);

	//Magnfier
	QAction *actionMagnifier = new QAction(this);
        actionMagnifier->setObjectName(QString::fromUtf8("actionMagnifier"));
        actionMagnifier->setCheckable(true);
        QIcon icon3;
        icon3.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/magnifier.svg")), QIcon::Normal, QIcon::Off);
        actionMagnifier->setIcon(icon3);
	actionMagnifier->setText(tr("&Magnifier"));

	//Cursor data
        QAction *actionCursorData = new QAction(this);
        actionCursorData->setObjectName(QString::fromUtf8("actionCursorData"));
        actionCursorData->setCheckable(true);  
	QIcon icon1;
        icon1.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/gunsight.svg")), QIcon::Normal, QIcon::Off);
        actionCursorData->setIcon(icon1);
	actionCursorData->setText(tr("&Cursor data"));	
	
	//OpenGL
        QAction *actionOpenGL = new QAction(this);
        actionOpenGL->setObjectName(QString::fromUtf8("actionOpenGL"));
        actionOpenGL->setCheckable(true);
        actionOpenGL->setEnabled(true);
        //QIcon icon2;
        //icon2.addPixmap(QPixmap(QString::fromUtf8(":/new/prefix1/image/antialias.svg")), QIcon::Normal, QIcon::Off);
        //actionAntialias->setIcon(icon2);
 	actionOpenGL->setText(tr("OpenGL"));
        //actionAntialias->setShortcut(tr("Ctrl+L"));	
	//controlActions_.push_back(actionAntialias);

	//Placemark
        QAction *actionPlaceMark = new QAction(this);
        actionPlaceMark->setObjectName(QString::fromUtf8("actionPlaceMark"));
        //actionPlaceMark->setCheckable(true);
        //QIcon icon4;
        //icon4.addPixmap(QPixmap(QString::fromUtf8(":/new/prefix1/image/zoom.svg")), QIcon::Normal, QIcon::Off);
        //actionPlaceMark->setIcon(icon4);
	actionPlaceMark->setText(tr("Placemark"));
	//actionPlaceMark->setEnabled(false);
	
//#ifndef QT_NO_OPENGL
//     	actionOpenGL->setEnabled(QGLFormat::hasOpenGL());
//#else
//     	actionOpenGL->setEnabled(false);
//#endif	

	actionOpenGL->setEnabled(false);

	//Magnifier 
	connect(actionMagnifier, SIGNAL(toggled(bool)),
		plotView_, SLOT(slotSetEnableMagnifier(bool)));

	connect(plotView_,SIGNAL(magnifierIsEnabledProgramatically(bool)),
		actionMagnifier, SLOT(setChecked(bool)));

	//Cursor data 
	connect(actionCursorData, SIGNAL(toggled(bool)),
		plotView_,SLOT(slotSetEnableCursorData(bool)));
		
	//OpenGL button
	connect(actionOpenGL, SIGNAL(toggled(bool)),
		this, SLOT(slotEnableOpenGL(bool)));

	connect(actionPlaceMark, SIGNAL(triggered()),
		plotView_,SLOT(slotCreatePlaceMark()));

	connect(actionAntialias_, SIGNAL(toggled(bool)),
		this,SLOT(slotEnableAntialias(bool)));

	MvQMainWindow::MenuType menuType=MvQMainWindow::ToolsMenu;
	
	menuItems_[menuType].push_back(new MvQMenuItem(actionMagnifier));	
	menuItems_[menuType].push_back(new MvQMenuItem(actionAntialias_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionCursorData));
	//menuItems_["controls"].push_back(new MvQMenuItem(actionOpenGL));
#ifdef PLACEMARK
	menuItems_[menuType].push_back(new MvQMenuItem(actionPlaceMark));
#endif	
}

void uPlot::setupViewActions()
{
	QAction* action;

	//Sidebar
	actionControlPanel_ = new QAction(this);
        actionControlPanel_->setObjectName(QString::fromUtf8("actionControlPanel"));
        actionControlPanel_->setCheckable(true);
	actionControlPanel_->setChecked(true); //!!!
	actionControlPanel_->setText(tr("&Sidebar"));
	QIcon icon2;
        icon2.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/sidebar.svg")), QIcon::Normal, QIcon::Off);
        actionControlPanel_->setIcon(icon2);
	
	//Active scene highlight
        action = new QAction(this);
        action->setObjectName(QString::fromUtf8("actionHighlightScene"));
        QIcon icon4;
        icon4.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/highlight_scene.svg")), QIcon::Normal, QIcon::Off);
        action->setIcon(icon4); 
	action->setText(tr("&Highlight active scene"));  
	action->setCheckable(true);
    action->setChecked(false); //!!!
	actionHighlightScene_=action;
		
	connect(actionControlPanel_,SIGNAL(toggled(bool)),
		this,SLOT(slotShowControlPanel(bool)));

	connect(actionHighlightScene_,SIGNAL(toggled(bool)),
		this,SLOT(slotHighlightActiveScene(bool)));	
			
	QAction *sep=new QAction(this);	
	sep->setSeparator(true);
		
	MvQMainWindow::MenuType menuType=MvQMainWindow::ViewMenu;	
	
	menuItems_[menuType].push_back(new MvQMenuItem(actionControlPanel_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionHighlightScene_));
	menuItems_[menuType].push_back(new MvQMenuItem(sep));
	
	uPlotBase::setupViewActions();
}

void uPlot::setupAnimationActions()
{
	//Play
        actionPlay_ = new QAction(this);
        actionPlay_->setObjectName(QString::fromUtf8("actionPlay"));
        QIcon icon5;
        icon5.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/player_play.svg")), QIcon::Normal, QIcon::Off);
        actionPlay_->setIcon(icon5); 
	actionPlay_->setText(tr("&Play"));
	//animationActions_.push_back(actionPlay_);

	//Stop
        actionStop_ = new QAction(this);
        actionStop_->setObjectName(QString::fromUtf8("actionStop"));
        QIcon icon6;
        icon6.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/player_stop.svg")), QIcon::Normal, QIcon::Off);
        actionStop_->setIcon(icon6);
	actionStop_->setText(tr("&Stop"));
	//animationActions_.push_back(actionStop_);

	//Prev
        actionPrevious_ = new QAction(this);
        actionPrevious_->setObjectName(QString::fromUtf8("actionPrevious"));
        QIcon icon8;
        icon8.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/player_prev.svg")), QIcon::Normal, QIcon::Off);
        actionPrevious_->setIcon(icon8);
	actionPrevious_->setText(tr("P&revious"));
        actionPrevious_->setShortcut(tr("Left"));
	//animationActions_.push_back(actionPrevious_);

	//Next
        actionNext_ = new QAction(this);
        actionNext_->setObjectName(QString::fromUtf8("actionNext"));
        QIcon icon7;
        icon7.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/player_next.svg")), QIcon::Normal, QIcon::Off);
        actionNext_->setIcon(icon7); 
	actionNext_->setText(tr("&Next"));
        actionNext_->setShortcut(tr("Right"));
	//animationActions_.push_back(actionNext_);

	//First
        actionFirst_ = new QAction(this);
        actionFirst_->setObjectName(QString::fromUtf8("actionFirst"));
        QIcon icon9;
        icon9.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/player_start.svg")), QIcon::Normal, QIcon::Off);
        actionFirst_->setIcon(icon9);
	actionFirst_->setText(tr("&First"));
        actionFirst_->setShortcut(tr("Home"));
	//animationActions_.push_back(actionFirst_);

	//Last
        actionLast_ = new QAction(this);
        actionLast_->setObjectName(QString::fromUtf8("actionLast"));
        QIcon icon10;
        icon10.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/player_end.svg")), QIcon::Normal, QIcon::Off);
        actionLast_->setIcon(icon10);
	actionLast_->setText(tr("&Last"));
        actionLast_->setShortcut(tr("End"));
	//animationActions_.push_back(actionLast_);


	connect(actionPlay_, SIGNAL(triggered()),
		this, SLOT(slotPlay()));
	
	connect(actionStop_, SIGNAL(triggered()),
		this,SLOT(slotStop()));

	connect(actionNext_, SIGNAL(triggered()),
		this, SLOT(slotToNext()));
	
	connect(actionPrevious_, SIGNAL(triggered()),
		this, SLOT(slotToPrev()));
	
	connect(actionFirst_, SIGNAL(triggered()),
		this, SLOT(slotToFirst()));
	
	connect(actionLast_, SIGNAL(triggered()),
		this, SLOT(slotToLast()));


	//Animation speed
	float fval[]={0.5,0.7,1,1.5,2,3,4,5,10};
	for(int i=0; i< 9; i++)
	{
		speed_.push_back(fval[i]);
	}

	actSpeedIndex_=2;

	timer_= new QTimer(this);
	timer_->setInterval(1000./speed_[actSpeedIndex_]);
	connect(timer_, SIGNAL(timeout()), this, SLOT(slotToNext()) );

	QPushButton *speedPb = new QPushButton;

	speedPb->setText(tr("Speed"));
	speedPb->setObjectName("speedPb");

	QMenu *menuSpeed = new QMenu("&Animation");

	speedPb->setMenu(menuSpeed);
	
	speedSlider_ = new QSlider(Qt::Vertical);
	speedSlider_->setMaximumWidth(100);
	speedSlider_->setMinimum(0);
	speedSlider_->setMaximum(speed_.size()-1);
	speedSlider_->setSliderPosition(actSpeedIndex_);
 	speedSlider_->setSingleStep(1);
	speedSlider_->setPageStep(1);
	speedSlider_->setTickInterval(1);
	speedSlider_->setTickPosition(QSlider::TicksBelow);
	speedSlider_->setToolTip("Animation speed");

	speedLabel_=new QLabel;
	speedLabel_->setText("Speed: 1 fr/s");
	//toolBarAnimation->addWidget(speedLabel_);
	
	//QVBoxLayout *vl = new QVBoxLayout;
	//vl->addWidget(speedSlider_);
	//vl->addWidget(speedLabel_);

	QWidgetAction *wa = new QWidgetAction(menuSpeed);
	wa->setDefaultWidget(speedSlider_);
	menuSpeed->addAction(wa);

	wa = new QWidgetAction(menuSpeed);
	wa->setDefaultWidget(speedLabel_);
	menuSpeed->addAction(wa);
	

	connect(speedSlider_, SIGNAL(valueChanged(int)), this, SLOT(slotSetSpeed(int)) );

	
	//Active scene highlight
        QAction* action = new QAction(this);
        action->setObjectName(QString::fromUtf8("actionAnimatedScenes"));
        QIcon icon4;
        icon4.addPixmap(QPixmap(QString::fromUtf8(":/uPlot/connectAnimations.svg")), QIcon::Normal, QIcon::Off);
        action->setIcon(icon4); 
	action->setText(tr("&Animate all scenes"));  
	action->setCheckable(true);
    action->setChecked(true);
	actionAnimatedScenes_=action;

	//
	actionPlay_->setEnabled(false);
	actionStop_->setEnabled(false);
	actionFirst_->setEnabled(false);
	actionNext_->setEnabled(false);
	actionPrevious_->setEnabled(false);
	actionLast_->setEnabled(false);

    connect(actionAnimatedScenes_, SIGNAL(toggled(bool)),
        this, SLOT(slotAnimatedScenes(bool)));

	MvQMainWindow::MenuType menuType=MvQMainWindow::AnimationMenu;
	
	menuItems_[menuType].push_back(new MvQMenuItem(actionPlay_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionStop_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionPrevious_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionNext_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionFirst_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionLast_));	
	menuItems_[menuType].push_back(new MvQMenuItem(speedPb));	
	menuItems_[menuType].push_back(new MvQMenuItem(actionAnimatedScenes_,MvQMenuItem::MenuTarget));

}

void uPlot::setupProgressBarActions()
{
   // Create a toolbar to handle the progress bar
   QToolBar* progressToolbar = new QToolBar("ptbar",this);
   addToolBar(progressToolbar);

   // Create a progress bar
   progressBar_ = new MvQProgressBarPanel(progressToolbar);
}

bool uPlot::setDropTarget(QPoint globalPos)
{
	MgQSceneItem *item=0;
	
	QPointF scenePos = plotView_->mapToScene(plotView_->mapFromGlobal(globalPos));
	
	/*if(layerWidget_->layerAtGlobalPos(globalPos) != -1)
	{
		return false;
	}
	else
	{  	
		if(activeScene_)
		{
	  		if(activeScene_->sceneBoundingRect().contains(scenePos))
				return true; 
		}			
	}*/
	
	if(activeScene_)
	{
	  	if(activeScene_->sceneBoundingRect().contains(scenePos))
			return true; 
	}
		
	item = plotScene_->findSceneItem(scenePos);
	if(item || plotScene_->sceneItems().count() == 0)
	{  
			slotSetActiveScene(item);
			return true;
	}
	else
	{	
		return false;
	}
	
	return false;
}	
	
bool uPlot::setDropTargetInView(QPoint pos)
{
	MgQSceneItem *item=0;
	
	QPointF scenePos = plotView_->mapToScene(pos);
		
	if(activeScene_)
	{
		if(activeScene_->sceneBoundingRect().contains(scenePos))
			return true; 				
	}

	item = plotScene_->findSceneItem(scenePos);
	if(item || plotScene_->sceneItems().count() == 0)
	{  
			slotSetActiveScene(item);
			return true;
	}
	else
	{	
		return false;
	}
	
	return false;
}  

void uPlot::newRequestForDriversBegin()
{
	plotScene_->saveStateBeforeNewRequest();

	//Frames
	stepWidget_->stepDataIsAboutToChange();
	
	//Layer contents
	layerWidget_->layersAreAboutToChange();
	
	//Layer data
	dataWidget_->layersAreAboutToChange();

	//Magnifier
	plotView_->resetBegin();
	
	if(activeScene_)
	{
	 	prevActiveSceneId_=activeScene_->layout().id();
		if(prevActiveSceneId_.empty())
		{
		  	MgQLayoutItem *projItem=activeScene_->firstProjectorItem();
			prevActiveSceneId_=projItem->layout().id();
		}	
	}
	else
	{
	  	prevActiveSceneId_.clear();
	} 
	
	activeScene_=0;
	
	controlWidget_->setEnabled(false);
	
	loadStarted();

}


void uPlot::newRequestForDriversEnd()
{	
	controlWidget_->setEnabled(true);
	
	//Select the active scene
	if(!activeScene_)
	{	  
	  	if(!prevActiveSceneId_.empty())
		{
			foreach(MgQSceneItem *item,plotScene_->sceneItems())
			{
			  	MgQLayoutItem *projItem=item->firstProjectorItem();
				if(item->layout().id() == prevActiveSceneId_)
				{
				  	activeScene_=item;
					break;
				}
				else if(item->layout().id().empty() && projItem &&
				        prevActiveSceneId_==projItem->layout().id())
				{
					activeScene_=item;
					break;  
				}	
			}
		}
		
		
		if(!activeScene_ && plotScene_->sceneItems().count() >0)
		{
		  	activeScene_=plotScene_->sceneItems().back();	
		}
	}		

	//Resize without rendering!!
	changeSize(sizeCombo_->itemData(sizeCombo_->currentIndex(),Qt::UserRole).toInt(),false);	
	
	//Load steps/layers and generate layer thumbnails - No rendering at this point!
	//It tries to set the current step for all the scenes!
	//The current step should be correctly set at least for the active scene.
	plotScene_->updateAfterNewRequest();
	
	//Zoom stack - generate thumbnail for the new area
	zoomStackWidget_->reset(activeScene_,false);	
	updateZoomActionState();	
	
	//Layer contents
	layerWidget_->reset(activeScene_);
		
	//Layer data - will set the current step for the data widgets!
	dataWidget_->reset(activeScene_);
			
	//Update scene combobox
	if(plotScene_->sceneItems().count() <= 1)
	{
		sceneWidget_->hide();
		sceneCb_->clear();
	}	
	else
	{ 
  		//Scene combo
		sceneCb_->clear();
		for(int i=0; i < plotScene_->sceneItems().count(); i++)
		{
	  		sceneCb_->addItem(tr("Scene ") + QString::number(i+1));
		}	
		int actIndex=plotScene_->sceneItems().indexOf(activeScene_);
		if(actIndex != -1)
			sceneCb_->setCurrentIndex(actIndex);  
		
		sceneWidget_->show();				
	}
	
	//Generate animated scenes list
	if(plotScene_->sceneItems().count() <=1)
	{
		animatedScenes_.clear();
    }
	else
	{
        actionAnimatedScenes_->setEnabled(true);
		slotAnimatedScenes(actionAnimatedScenes_->isChecked());
	}	

	//Frames - no rendering!!
	//At this point the current step should be correctly set for the active scene!!
	stepWidget_->reset(activeScene_);
	if(activeScene_)
	{
		//Update the view
		stepWidget_->setViewToCurrentStep();
		
		//Set the correct step for the aminated scenes. No rendering involved!
		stepWidget_->updateStepForScenes(animatedScenes_);
	}
	
	//Animation buttons
	updateAnimationActionState();
	
	//NOW RENDER IT! We render the whole scene into the pixmap cache at this point!
	plotScene_->sceneItemChanged();
	
	//Update magnifier, cursordata etc
	plotView_->resetEnd();
	
	//Udate scene selection
	if(plotScene_->sceneItems().count() <=1)
	{
	  	actionHighlightScene_->setEnabled(false);
	}
	else
	{  
		actionHighlightScene_->setEnabled(true);
		slotHighlightActiveScene(actionHighlightScene_->isChecked());
	}	
	
	
	loadFinished();
		
	//Emit a signal that the plot window has been updated
	emit plotWindowUpdated();
}



void uPlot::slotShowControlPanel(bool status)
{
	if(status)
	{
		controlWidget_->show();
	}
	else
	{
		controlWidget_->hide();
	}
}



//===============================================
//
// Animaton
//
//===============================================

void uPlot::slotToPrev()
{
	if(stepWidget_->currentStep() > 0)
	{		
		slotStepTo(stepWidget_->currentStep()-1);
	}
}	

void uPlot::slotToNext()
{	
	if(stepWidget_->currentStep() < stepWidget_->stepNum()-1)
	{
		slotStepTo(stepWidget_->currentStep()+1);		
	}
	else if(timer_->isActive())
	{
		slotToFirst();
	}	
}			

void uPlot::slotToLast()
{
	if(stepWidget_->currentStep() < stepWidget_->stepNum()-1)
	{		
		slotStepTo(stepWidget_->stepNum()-1);
	}
}	

void uPlot::slotToFirst()
{
	if(stepWidget_->currentStep() > 0)
	{		
		slotStepTo(0);
	}
}	

void uPlot::slotPlay()
{	
	timer_->start();
	updateAnimationActionState();
}
	
void uPlot::slotStop()
{
	timer_->stop();
	updateAnimationActionState();
}

void uPlot::slotStepTo(const QModelIndex &index)
{	
	slotStepTo(index.row());
}

void uPlot::slotStepTo(int fr)
{	
	plotView_->resetBegin();
	
	if(fr == stepWidget_->setCurrentStep(fr,animatedScenes_))
	{
		updateAnimationActionState();		
		stepWidget_->setViewToCurrentStep();			
		layerWidget_->slotFrameChanged();
		dataWidget_->slotFrameChanged();
	}
	
	plotView_->resetEnd();

}

void uPlot::slotSetSpeed(int sp)
{		
	if(actSpeedIndex_ != sp)
	{
		actSpeedIndex_=sp;
		timer_->setInterval(1000./speed_[actSpeedIndex_]);
		
		QString s="Speed: ";
		s.append(QString::number(speed_[actSpeedIndex_]));
		s.append(" fr/s");
		speedLabel_->setText(s);
	}
}

void uPlot::updateAnimationActionState()	
{
	if(stepWidget_->stepNum() < 2)
	{
		actionPlay_->setEnabled(false);
		actionStop_->setEnabled(false);
		actionFirst_->setEnabled(false);
		actionNext_->setEnabled(false);
		actionPrevious_->setEnabled(false);
		actionLast_->setEnabled(false);
		return;
	}
	else
	{
		if(timer_->isActive() == true)
		{
			actionPlay_->setEnabled(false);
			actionStop_->setEnabled(true);
		}
		else
		{
			actionPlay_->setEnabled(true);
			actionStop_->setEnabled(false);
		}

	}

	if(timer_->isActive() == false)
	{
		if(stepWidget_->currentStep()==0)
		{
			actionFirst_->setEnabled(false);
			actionNext_->setEnabled(true);
			actionPrevious_->setEnabled(false);
			actionLast_->setEnabled(true);
		}
		else if(stepWidget_->currentStep()  == stepWidget_->stepNum()-1)
		{
			actionFirst_->setEnabled(true);
			actionNext_->setEnabled(false);
			actionPrevious_->setEnabled(true);
			actionLast_->setEnabled(false);
		}
		else
		{
			actionFirst_->setEnabled(true);
			actionNext_->setEnabled(true);
			actionPrevious_->setEnabled(true);
			actionLast_->setEnabled(true);
		}
	}
	else
	{
		actionFirst_->setEnabled(false);
		actionNext_->setEnabled(false);
		actionPrevious_->setEnabled(false);
		actionLast_->setEnabled(false);
	}
}
int uPlot::currentStep()
{
  	return stepWidget_->currentStep();
}

int uPlot::stepNum()
{
	return stepWidget_->stepNum();
}

//=================================
//
// Active scene selection
//
//=================================

void uPlot::slotSelectActiveScene()
{
	//actionSelectScene_->setEnabled(false);
	//plotView_->slotSelectScene();
}

void uPlot::slotActiveSceneSelected(QPointF /*scenePos*/)
{
 	//MgQSceneItem *item=plotScene_->findSceneItem(scenePos);

	//setActiveScene(item);	
	//identifyScene(item);
	//actionSelectScene_->setEnabled(true);
}

void uPlot::slotHighlightActiveScene(bool bval)
{	
	 plotScene_->highlightSceneItem(activeScene_,bval);	
}	

void uPlot::slotAnimatedScenes(bool bval)
{
	if(bval)
	{
		animatedScenes_=plotScene_->sceneItems();
	}
	else
	{
	  	animatedScenes_.clear();
	}	
}


void uPlot::slotSetActiveScene(int index)
{
	if(index <0 || index >=plotScene_->sceneItems().count() )
		return; 
	
	slotSetActiveScene(plotScene_->sceneItems().at(index));
}

void uPlot::slotSetActiveScene(MgQSceneItem *activeScene)
{
	if(!activeScene)
		return;
	
	if(activeScene_ == activeScene)
		return;
	
	activeScene_=activeScene;
	
	//Zoom stack
	zoomStackWidget_->reset(activeScene_,true);	
	updateZoomActionState();	
	
	layerWidget_->layersAreAboutToChange();
	layerWidget_->reset(activeScene_);

	dataWidget_->layersAreAboutToChange();
	dataWidget_->reset(activeScene_);
	
    //stepWidget_->stepDataIsAboutToChange();
	stepWidget_->reset(activeScene_);	
	
	slotHighlightActiveScene(actionHighlightScene_->isChecked());
	
	//Remove the highlight rectangle activated by the scene combo box!
	slotNotHighlightScene();

	updateAnimationActionState();
	
	sceneCb_->setCurrentIndex(plotScene_->sceneItems().indexOf(activeScene));
	
	//Emit a signal that the plot windows has been updated
	//emit plotWindowUpdated();  ???????????????	
}


void uPlot::slotHighlightScene(int index)
{	
  	if(index <0 || index >=plotScene_->sceneItems().count() )
		return; 
	
	MgQSceneItem *item=plotScene_->sceneItems().at(index);	 
	
	plotScene_->highlightSceneItemForBrief(item,true);	
}	

void uPlot::slotNotHighlightScene()
{
  	plotScene_->highlightSceneItemForBrief(0,false);	
}	



void uPlot::slotLayerUpdate()
{	
	//Notify the scene about the change in the layer status
	//plotScene_->updateLayers(layerWidget_->model()->layers());
	plotScene_->update(); 
}

void uPlot::progressMessage(const string& /*m*/)
{
#ifdef METVIEW_EXPERIMENTAL

#if 0
	if(progressItem_ && progressItem_->isVisible())
	{
		progressItem_->progress();
		QCoreApplication::sendPostedEvents(plotScene_,0);  
	}
#endif
#endif	
}  	

void uPlot::loadStarted()
{  
#ifdef METVIEW_EXPERIMENTAL		
#if 0
	if(!progressItem_)
	{
	  	progressItem_=new MvQProgressItem;
		progressItem_->setVisible(false);
		plotScene_->addItem(progressItem_);
	}
	
	progressItem_->setRect(plotScene_->sceneRect());
	progressItem_->startProgress();
	progressItem_->setVisible(true);
#endif			
#endif	

}

void uPlot::loadFinished()
{
#ifdef METVIEW_EXPERIMENTAL	
#if 0
	if(progressItem_)
	{	
		progressItem_->setVisible(false);
	}
#endif	
#endif	
}

void uPlot::slotLayerTransparencyChanged(QString sid, int value)
{
   int id = sid.toInt();
   owner_->UpdateLayerTransparency(id,value);
}

void uPlot::slotLayerVisibilityChanged(QString sid, bool onoff)
{
   int id = sid.toInt();
   owner_->UpdateLayerVisibility(id,onoff);
}

void uPlot::slotLayerStackingOrderChanged(QList<QPair<QString,int> > lorder)
{
   for (int i = 0; i < lorder.size(); i++)
   {
      int id = lorder[i].first.toInt();
      int value = lorder[i].second;
      owner_->UpdateLayerStackingOrder(id,value);
   }
}

void uPlot::slotPlotScaleChanged()
{
	dataWidget_->slotPlotScaleChanged();  
}  

void uPlot::slotControlTabChanged(int index)
{
	if(index==2)
	{
	  	dataWidget_->resetLayerList();
	}	
}  

void uPlot::writeSettings()
{	
	QSettings settings("ECMWF","MV4-uPlot");
	
	//!!
	settings.clear();
	
	settings.beginGroup("main");
	settings.setValue("geometry",saveGeometry());
	settings.setValue("state",saveState());
	settings.setValue("mainSplitter",mainSplitter_->saveState());
	
	settings.setValue("stepKeyProfileName",stepWidget_->currentKeyProfile());
	settings.setValue("currentControlTabIndex",controlTab_->currentIndex()); 
	settings.setValue("antialias",actionAntialias_->isChecked());
	settings.setValue("controlPanel",actionControlPanel_->isChecked());
	settings.setValue("highlightScene",actionHighlightScene_->isChecked());
	settings.setValue("animatedScenes",actionAnimatedScenes_->isChecked());	
	
	settings.setValue("sizeIndex",sizeCombo_->currentIndex());
	int sizeId=sizeCombo_->itemData(sizeCombo_->currentIndex(),Qt::UserRole).toInt();
	settings.setValue("sizeId",sizeId);	
	
	settings.endGroup();
	
	dataWidget_->writeSettings(settings);
}	
	
void uPlot::readSettings()
{
	QSettings settings("ECMWF","MV4-uPlot");
	
	settings.beginGroup("main");
	restoreGeometry(settings.value("geometry").toByteArray());
	restoreState(settings.value("state").toByteArray());
	mainSplitter_->restoreState(settings.value("mainSplitter").toByteArray());
	
	stepWidget_->setCurrentKeyProfile(settings.value("stepKeyProfileName").toString());
	controlTab_->setCurrentIndex(settings.value("currentControlTabIndex").toInt());

	if(settings.value("antialias").isNull())
	{
		actionAntialias_->setChecked(false);
	}
	else
	{
		actionAntialias_->setChecked(settings.value("antialias").toBool());
	}

	if(settings.value("controlPanel").isNull())
	{
		actionControlPanel_->setChecked(true);
	}
	else
	{
		actionControlPanel_->setChecked(settings.value("controlPanel").toBool());
	}
	
	if(settings.value("highlightScene").isNull())
	{
        actionHighlightScene_->setChecked(false);
	}
	else
	{
		actionHighlightScene_->setChecked(settings.value("highlightScene").toBool());
	}
		
	if(settings.value("animatedScenes").isNull())
	{
        actionAnimatedScenes_->setChecked(true);
	}
	else
	{
		actionAnimatedScenes_->setChecked(settings.value("animatedScenes").toBool());
	}

	if(settings.value("sizeIndex").isNull())
	{
		sizeCombo_->setCurrentIndex(5);
	}
	else
	{
		int current=settings.value("sizeIndex").toInt();
		if(current == customSizeItemIndex_)
		{
		  	if(!settings.value("sizeId").isNull())
			{
				int sizeId=settings.value("sizeId").toInt();
				setCustomSize(sizeId);	
			}
			else
			{
				sizeCombo_->setCurrentIndex(0);	

			}
		}	
		else		  
		{ 
			sizeCombo_->setCurrentIndex(settings.value("sizeIndex").toInt());
		}
	}
	
	
	settings.endGroup();
	
	dataWidget_->readSettings(settings);
}

void uPlot::slotShareTarget()
{
#ifdef METVIEW_SHARE_PLOT
   // Get a reference to the icon/button selected by the user
   QAction* ac = static_cast<QAction*>(sender());
   if ( !ac )
      return;

   // Get the specific share target selected by the user
   QVariant qv = ac->data();
   ShareTarget* st = ShareTargetManager::instance()->at(qv.toInt());

   // Create progress manager
   MvQProgressManager* pm = new MvQProgressManager(stepWidget_->stepNum(),progressBar_);

   // Retrieve current plot request without output formats
   MvRequest req;
   owner_->GetAllRequests( req, true );

   // Get extra information from the user interface
   // The plotting function will be performed by the share target
   // ShareTarget class should delete point pm
    st->dialog(req,pm);
#endif
}
