/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2008-2013 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

#include <osgEarthQt/AnnotationToolbar>
#include <osgEarthQt/Common>
#include <osgEarthQt/MultiViewerWidget>
#include <osgEarthQt/DataManager>
#include <osgEarthQt/MapCatalogWidget>
#include <osgEarthQt/TerrainProfileWidget>
#include <osgEarthQt/ViewerWidget>

#include <osgEarthAnnotation/AnnotationNode>
#include <osgEarthAnnotation/PlaceNode>
#include <osgEarthAnnotation/ScaleDecoration>
#include <osgEarthDrivers/gdal/GDALOptions>
#include <osgEarth/GeoData>

#include <QAction>
#include <QDockWidget>
#include <QtGui>
#include <QMainWindow>
#include <QToolBar>


class DemoMainWindow : public QMainWindow
{
    Q_OBJECT

public:

    DemoMainWindow(osgEarth::QtGui::DataManager* manager, osgEarth::MapNode* mapNode, osg::Group* annotationRoot)
        : _manager(manager), _mapNode(mapNode), _annoRoot(annotationRoot), _layerAdded(false), _terrainProfileDock(0L), _viewerWidget(0L), _compositeViewerWidget(0L)
    {
        initUi(); 
    }

    void setViewerWidget(osgEarth::QtGui::ViewerWidget* viewerWidget)
    {
        setCentralWidget(viewerWidget);
        _viewerWidget = viewerWidget;

        _views.clear();
        _viewerWidget->getViews( _views );

        _annotationToolbar->setActiveViews(_views);
    }

    void setViewerWidget(osgEarth::QtGui::MultiViewerWidget* viewerWidget, const osgEarth::QtGui::ViewVector& views)
    {
        setCentralWidget(viewerWidget);
        _compositeViewerWidget = viewerWidget;

        _views.clear();
        _views.insert(_views.end(), views.begin(), views.end());

        _annotationToolbar->setActiveViews(_views);
    }

    void setTerrainProfileWidget(osgEarth::QtGui::TerrainProfileWidget* widget)
    {
        if (!_terrainProfileDock)
        {
            _terrainProfileDock = new QDockWidget;
            _terrainProfileDock->setAllowedAreas(Qt::BottomDockWidgetArea);
            _terrainProfileDock->setFeatures(QDockWidget::NoDockWidgetFeatures);
            addDockWidget(Qt::BottomDockWidgetArea, _terrainProfileDock);
            _terrainProfileDock->setVisible(_terrainProfileAction->isChecked());
        }

        _terrainProfileDock->setWidget(widget);
    }

    private slots:

        void addRemoveLayer()
        {
            if (!_testLayer.valid())
            {
                osgEarth::Drivers::GDALOptions layerOpt;
                layerOpt.url() = osgEarth::URI("../data/nyc-inset-wgs84.tif");
                _testLayer = new osgEarth::ImageLayer(osgEarth::ImageLayerOptions("ny_inset", layerOpt));
            }

            if (!_layerAdded)
            {
                _manager->map()->addImageLayer(_testLayer.get());
                _layerAdded = true;
                _addRemoveLayerAction->setText(tr("&Remove Layer"));
                _addRemoveLayerAction->setToolTip("Remove an image layer");
            }
            else
            {
                _manager->map()->removeImageLayer(_testLayer.get());
                _layerAdded = false;
                _addRemoveLayerAction->setText(tr("&Add Layer"));
                _addRemoveLayerAction->setToolTip("Add an image layer");
            }
        }

    void addAnnotation()
    {
        osgEarth::Annotation::PlaceNode* annotation = new osgEarth::Annotation::PlaceNode(
            _mapNode.get(), 
            osgEarth::GeoPoint(_mapNode->getMapSRS(), -74.0, 40.714),
            osgDB::readImageFile("../data/placemark32.png"),
            "New York");

        osgEarth::Annotation::AnnotationData* annoData = new osgEarth::Annotation::AnnotationData();
        annoData->setName("New York");
        annoData->setViewpoint(osgEarth::Viewpoint(osg::Vec3d(-74, 40.714, 0), 0.0, -90.0, 1e5));
        annotation->setAnnotationData(annoData);

        annotation->installDecoration("selected", new osgEarth::Annotation::ScaleDecoration(2.0f));

        _manager->addAnnotation(annotation, _annoRoot.get());

        _addAnnotationAction->setDisabled(true);
    }

    void terrainProfileToggled(bool checked)
    {
        if (_terrainProfileDock)
            _terrainProfileDock->setVisible(checked);
    }

protected:

    void closeEvent(QCloseEvent *event)
    {
        if (_viewerWidget)
        {
            //_viewerWidget->getViewer()->setSceneData(0);
            //_viewerWidget->getViewer()->frame();
            _viewerWidget->getViewer()->setDone(true);
        }

        if (_compositeViewerWidget)
        {
            _compositeViewerWidget/*->getViewer()*/->setDone(true);
        }

        event->accept();
    }

private:

    void initUi()
    {
        setWindowTitle(tr("osgEarth Qt"));
        //setWindowIcon(QIcon(":/resources/images/pmicon32.png"));

        createActions();
        createToolbars();
    }

	void createActions()
    {
        _addRemoveLayerAction = new QAction(tr("&Add Layer"), this);
        _addRemoveLayerAction->setToolTip(tr("Add an image layer"));
        connect(_addRemoveLayerAction, SIGNAL(triggered()), this, SLOT(addRemoveLayer()));
        _addRemoveLayerAction->setDisabled(!_manager.valid());

        _addAnnotationAction = new QAction(/*QIcon(":/images/open.png"),*/ tr("&Add Annotation"), this);
        _addAnnotationAction->setToolTip(tr("Add an annotation"));
        connect(_addAnnotationAction, SIGNAL(triggered()), this, SLOT(addAnnotation()));
        _addAnnotationAction->setDisabled(!_manager.valid() || !_mapNode.valid() || !_annoRoot.valid());

        _terrainProfileAction = new QAction(QIcon(":/images/terrain_profile.png"), tr(""), this);
        _terrainProfileAction->setToolTip(tr("Terrain Profile Tool"));
        _terrainProfileAction->setCheckable(true);
        connect(_terrainProfileAction, SIGNAL(toggled(bool)), this, SLOT(terrainProfileToggled(bool)));
    }

	void createToolbars()
    {
        _fileToolbar = addToolBar(tr("File Toolbar"));
        _fileToolbar->setObjectName(tr("FILE_TOOLBAR"));
        _fileToolbar->setIconSize(QSize(24, 24));
        _fileToolbar->addAction(_addRemoveLayerAction);
        _fileToolbar->addAction(_addAnnotationAction);
        _fileToolbar->addSeparator();
        _fileToolbar->addAction(_terrainProfileAction);

        _annotationToolbar = new osgEarth::QtGui::AnnotationToolbar(_annoRoot, _mapNode, _manager);
        addToolBar(_annotationToolbar);
    }
	
    osg::ref_ptr<osgEarth::QtGui::DataManager> _manager;
    osg::ref_ptr<osgEarth::MapNode> _mapNode;
    osg::ref_ptr<osg::Group> _annoRoot;
    osg::ref_ptr<osgEarth::ImageLayer> _testLayer;
    osgEarth::QtGui::ViewerWidget* _viewerWidget;
    osgEarth::QtGui::MultiViewerWidget* _compositeViewerWidget;
    //osg::ref_ptr<osgEarth::QtGui::ViewerWidget> _viewerWidget;
    //osg::ref_ptr<osgEarth::QtGui::MultiViewerWidget> _compositeViewerWidget;
    osgEarth::QtGui::AnnotationToolbar* _annotationToolbar;
    osgEarth::QtGui::ViewVector _views;
    bool _layerAdded;
    QAction *_addRemoveLayerAction;
    QAction *_addAnnotationAction;
    QAction *_terrainProfileAction;
    QToolBar *_fileToolbar;
    QDockWidget *_terrainProfileDock;
};
