#include <Nice/Map/Point.h>
#include <Nice/Qt/WidgetFactory.hh>
#include "DrotServicePanel.h"
#include <DrotServicePanelUI.h>
#include <Qt/qglobal.h>
#include <QTextEdit>
#include <boost/assign/list_of.hpp> // for 'map_list_of()'

extern "C" void instantType() {
    I_LOG("Load Sharknir::DrotServicePanel");
}

//------------------------------------------------------------
DrotServicePanel::DrotServicePanel ( QWidget * parent, bool _connect )
  : QWidget( parent ),  Nice::BridgeItem()
{
    Nice::BridgeItem::m_autoSynch = true;

    m_drotView = new Ui::DrotServicePanelUI;
    m_drotView->setupUi ( this );
    
    init ( this );
}

//------------------------------------------------------------
void DrotServicePanel::updateGUI ( const Nice::Any& _val )
{
    const Nice::Completion * completion;
    if ( ( completion = Nice::AnyCast<Nice::Completion> ( & _val ) ) )
    {
        if ( completion->percent() < 0 && (m_drotView->m_progressBar->maximum() != 0))
        {
            // set the completion bar ping pong mode
            m_drotView->m_progressBar->setMinimum ( 0 );
            m_drotView->m_progressBar->setMaximum ( 0 );
        }
        else
        {
            // set the completion bar in normal mode
            m_drotView->m_progressBar->setMinimum ( 0 );
            m_drotView->m_progressBar->setMaximum ( 100 );
        }

        m_drotView->m_progressBar->setFormat ( std::string(completion->action() + " %p %").c_str() );

        m_drotView->m_progressBar->setValue ( completion->percent() );

        // change the completion icon
        switch ( completion->state() )
        {
            case Nice::BUSY:
                m_drotView->m_statusLabel->setPixmap ( QPixmap(QString::fromUtf8(":/22x22/state_working.png") ));
                break;
            case Nice::OK:
                m_drotView->m_statusLabel->setPixmap ( QPixmap(QString::fromUtf8(":/22x22/state_online.png") ));
                break;
            case Nice::FATAL:
                m_drotView->m_statusLabel->setPixmap ( QPixmap(QString::fromUtf8(":/22x22/state_offline.png") ));
                break;
            case Nice::WARNING:
                m_drotView->m_statusLabel->setPixmap ( QPixmap(QString::fromUtf8(":/22x22/state_standby.png") ));
                break;
            default:
                m_drotView->m_statusLabel->setPixmap ( QPixmap(QString::fromUtf8(":/22x22/state_unknown.png") ));
                break;
        }
    }
}
//------------------------------------------------------------
void DrotServicePanel::initSlots()
{
    NICEQT_CONNECT(m_prop->attribute("VAR.RA"), this, DrotServicePanel, slotNice_getRa, double );
    NICEQT_CONNECT(m_prop->attribute("VAR.DEC"), this, DrotServicePanel, slotNice_getDec, double );
    NICEQT_CONNECT(m_prop->attribute("VAR.PA"), this, DrotServicePanel, slotNice_getParalacticAngle, double );
    NICEQT_CONNECT(m_prop->attribute("VAR.LST"), this, DrotServicePanel, slotNice_getLST, std::string );
    NICEQT_CONNECT(m_prop->attribute("VAR.UTC"), this, DrotServicePanel, slotNice_getUTC, std::string )
    NICEQT_CONNECT(m_prop->attribute("VAR.HA"), this, DrotServicePanel, slotNice_getHourAngle, std::string );
}

void DrotServicePanel::initAttributes ( )
{
    m_cmd = Sharknir::DrotServiceWorkerInterface::create(Nice::Application::config()->node(getNode()->parent()->path()));
}

void DrotServicePanel::slotQt_abort()
{
    try
    {
        m_cmd->abort();
    }

    catch (Basda::ServiceWorkerInterfaceCommandFailedException &e)
    {
        E_LOG(e);
    }

    catch (Basda::ServiceWorkerInterfaceIsBusyException &e)
    {
        E_LOG(e);
    }

    catch ( const std::exception& ex )
    {
        E_LOG(ex.what());
        assert(false);
    }
}

void DrotServicePanel::slotQt_stop()
{
    try
    {
//        m_drotView->m_RaDoubleSpinBox->maximum();
        m_cmd->stop();
    }

    catch (Basda::ServiceWorkerInterfaceCommandFailedException &e)
    {
        E_LOG(e);
    }

    catch (Basda::ServiceWorkerInterfaceIsBusyException &e)
    {
        E_LOG(e);
    }

    catch ( const std::exception& ex )
    {
        E_LOG(ex.what());
        assert(false);
    }
}

void DrotServicePanel::slotNice_getRa(double _ra)
{
    m_drotView->m_RaLabel->setText(QString::number(_ra));
}

void DrotServicePanel::slotNice_getDec(double _dec)
{
    m_drotView->m_DecLabel->setText(QString::number(_dec));
}

void DrotServicePanel::slotNice_getParalacticAngle(double _pa)
{
    m_drotView->m_PaLabel->setText(QString::number(_pa));
}

void DrotServicePanel::slotNice_getUTC(std::string _utc)
{
    m_drotView->m_UtcLabel->setText(QString::fromStdString(_utc));
}

void DrotServicePanel::slotNice_getLST(std::string _lst)
{
    m_drotView->m_LstLabel->setText(QString::fromStdString(_lst));
}

void DrotServicePanel::slotNice_getHourAngle(std::string _ha)
{
   m_drotView->m_HaLabel->setText(QString::fromStdString(_ha));
}

void DrotServicePanel::slotQt_update()
{
    m_drotView->m_RaLabel->setText(QString::number(m_cmd->getRA()));
    m_drotView->m_DecLabel->setText(QString::number(m_cmd->getDEC()));
    m_drotView->m_PaLabel->setText(QString::number(m_cmd->getParalacticAngle()));
    m_drotView->m_UtcLabel->setText(QString::fromStdString(std::string(m_cmd->getUTC())));
    m_drotView->m_LstLabel->setText(QString::fromStdString(std::string(m_cmd->getLST())));
    m_drotView->m_HaLabel->setText(QString::fromStdString(std::string(m_cmd->getHourAngle())));
}

void DrotServicePanel::slotQt_setPresetTelescope()
{
    std::string side;
    if (m_drotView->m_leftRadioButton->isChecked() )
        side = "LEFT";
    else if (m_drotView->m_bothRadioButton->isChecked() )
        side = "BOTH";
    else if (m_drotView->m_rightRadioButton->isChecked() )
        side = "right";
    m_cmd->setPresetTelescope(m_drotView->m_RaDoubleSpinBox->value(), m_drotView->m_DecDoubleSpinBox->value(), 0.0, 0.0, "POSITION", side);
}

void DrotServicePanel::slotQt_setOffsetPointing()
{
    std::string side;
    if (m_drotView->m_leftRadioButton->isChecked() )
        side = "LEFT";
    else if (m_drotView->m_bothRadioButton->isChecked() )
        side = "BOTH";
    else if (m_drotView->m_rightRadioButton->isChecked() )
        side = "right";
    m_cmd->setOffsetPointing(m_drotView->m_dRaDoubleSpinBox->value(), m_drotView->m_dDecDoubleSpinBox->value(), std::string("RADEC"), std::string("REL"), side);
}

void DrotServicePanel::slotQt_saveTrajectory()
{

}

void DrotServicePanel::slotQt_getRotatorTrajectory()
{
    QString fileName = QFileDialog::getSaveFileName(this);
    if (!fileName.isEmpty())
    {
        QFile file(fileName);
        if (!file.open(QFile::WriteOnly | QFile::Text))
        {
            QMessageBox::warning(this, tr("Application"),
                                 tr("Cannot write file %1:\n%2.")
                                 .arg(fileName)
                                 .arg(file.errorString()));
        }
        else
        {

            QTextStream out(&file);
            #ifndef QT_NO_CURSOR
                QApplication::setOverrideCursor(Qt::WaitCursor);
            #endif
            std::string side;
            if (m_drotView->m_leftRadioButton->isChecked() )
                side = "LEFT";
            else if (m_drotView->m_bothRadioButton->isChecked() )
                side = "BOTH";
            else if (m_drotView->m_rightRadioButton->isChecked() )
                side = "right";
            std::vector<std::string> trajectory = m_cmd->getRotatorTrajectory(m_drotView->m_durationDoubleSpinBox->value(), m_drotView->m_intervalDoubleSpinBox->value(), m_drotView->m_startTimeDoubleSpinBox->value(), side);
            for ( unsigned int i = 0; i < trajectory.size(); i++)
            {
                out << QString::fromStdString(trajectory[i]) << QString::fromStdString("\n");
            }
            #ifndef QT_NO_CURSOR
                QApplication::restoreOverrideCursor();
            #endif
        }
    }
}

struct WidgetFactoryTypeMapInitializerDrotServicePanel
{
    WidgetFactoryTypeMapInitializerDrotServicePanel()
    {
        NicePlugins::addPlugin( new QTPluginImpl<DrotServicePanel> ( "DrotServicePanel.h", "DrotServicePanel" ) );
    };
} s_WidgetFactoryTypeMapInitializerDrotServicePanel;
