/**
 *
 * Kalle Dalheimer <kalle@kde.org>
 */

#include "kchart_view.h"
#include "kchart_factory.h"
#include "kchart_part.h"
#include "kchartWizard.h"
#include "kchartDataEditor.h"
#include "kchartBarConfigDialog.h"
#include "KChartViewIface.h"
#include "kchartPageLayout.h"

#include "kchart_params.h"

#include <qpainter.h>
#include <qcursor.h>
#include <qpopupmenu.h>
#include <kaction.h>
#include <kglobal.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <dcopobject.h>
#include <kxmlguifactory.h>

using namespace std;

//#include "sheetdlg.h"

KChartView::KChartView( KChartPart* part, QWidget* parent, const char* name )
    : KoView( part, parent, name )
{
    setInstance( KChartFactory::global() );
    if ( koDocument()->isReadWrite() )
        setXMLFile( "kchart.rc" );
    else
        setXMLFile( "kchart_readonly.rc" );
    dcop = 0;
    dcopObject(); // build it

    m_wizard = new KAction( i18n("Customize with &Wizard..."),
                            "wizard", 0,
                            this, SLOT( wizard() ),
                            actionCollection(), "wizard");
    m_edit = new KAction( i18n("&Edit Data..."), "edit", 0,
                          this, SLOT( edit() ),
                          actionCollection(), "edit");
    m_config = new KAction( i18n( "&Configure..." ), "configure", 0,
                            this, SLOT( slotConfig() ),
                            actionCollection(), "config" );
    m_loadconfig = new KAction( i18n("&Load Config"),
                                "fileopen", 0, this,
                                SLOT( loadConfig() ),
                                actionCollection(), "loadconfig");
    m_saveconfig = new KAction( i18n("&Save Config"),
                                "filesave",	0, this,
                                SLOT( saveConfig() ),
                                actionCollection(), "saveconfig");
    m_defaultconfig = new KAction( i18n("&Default Config"),
                                   "defaultconfig", 0, this,
                                   SLOT( defaultConfig() ),
                                   actionCollection(), "defaultconfig");

    m_chartpie = new KToggleAction( i18n("&Pie"), "cakes", 0, this,
                                    SLOT( pieChart() ), actionCollection(),
                                    "piechart");
    m_chartpie->setExclusiveGroup( "charttypes" );
    m_chartline = new KToggleAction( i18n("&Line"), "lines3d", 0, this,
                                     SLOT( lineChart() ), actionCollection(),
                                     "linechart");
    m_chartline->setExclusiveGroup( "charttypes" );
    m_chartareas = new KToggleAction( i18n("&Areas"), "areas3d", 0, this,
                                      SLOT( areasChart() ), actionCollection(),
                                      "areaschart");
    m_chartareas->setExclusiveGroup( "charttypes" );
    m_chartbars = new KToggleAction( i18n("&Bars"), "bars3d", 0, this,
                                     SLOT( barsChart() ), actionCollection(),
                                     "barschart");
    m_chartbars->setExclusiveGroup( "charttypes" );
    m_chartbars->setChecked( true );
    m_charthilo = new KToggleAction( i18n("&HiLo"), "hilo", 0, this,
                                     SLOT( hiLoChart() ), actionCollection(),
                                     "hilochart");
    m_charthilo->setExclusiveGroup( "charttypes" );
    m_chartring = new KToggleAction( i18n("&Ring"), "ring", 0, this,
                                     SLOT( ringChart() ), actionCollection(),
                                     "ringchart");
    m_chartring->setExclusiveGroup( "charttypes" );

    m_chartpolar = new KToggleAction( i18n("&Polar"), "polar", 0, this,
                                     SLOT( polarChart() ), actionCollection(),
                                     "polarchart");
    m_chartpolar->setExclusiveGroup( "charttypes" );


    m_colorConfig = new KAction( i18n( "&Configure Colors..." ), 0,
                            this, SLOT( slotConfigColor() ),
                            actionCollection(), "color_config" );

    m_fontConfig = new KAction( i18n( "&Configure Font..." ), 0,
                            this, SLOT( slotConfigFont() ),
                            actionCollection(), "font_config" );

    m_backConfig = new KAction( i18n( "&Configure Background..." ), 0,
                            this, SLOT( slotConfigBack() ),
                            actionCollection(), "back_config" );

    m_legendConfig = new KAction( i18n( "&Configure Legend..." ), 0,
                            this, SLOT( slotConfigLegend() ),
                            actionCollection(), "legend_config" );
    m_subTypeChartConfig= new KAction( i18n( "&Configure Sub Type Chart..." ), 0,
                            this, SLOT( slotConfigSubTypeChart() ),
                            actionCollection(), "legend_subtype" );
    m_headerFooterConfig= new KAction( i18n( "&Configure Header Footer..." ), 0,
                            this, SLOT( slotConfigHeaderFooterChart() ),
                            actionCollection(), "headerfooter_subtype" );

    m_pageLayoutConfig=new KAction( i18n( "Page Layout..." ), 0,
                            this, SLOT( slotConfigPageLayout() ),
                            actionCollection(), "page_layout" );
    // initialize the configuration
    //    loadConfig();
    // make sure there is always some test data
    m_edit->setEnabled(((KChartPart*)koDocument())->canChangeValue());
    createTempData();
    updateGuiTypeOfChart();
}

KChartView::~KChartView()
{
    delete dcop;
}

DCOPObject* KChartView::dcopObject()
{
    if ( !dcop )
	dcop = new KChartViewIface( this );

    return dcop;
}

void KChartView::paintEvent( QPaintEvent* /*ev*/ )
{
    QPainter painter;
    painter.begin( this );

    // ### TODO: Scaling

    // Let the document do the drawing
    // PENDING(kalle) Do double-buffering if we are a widget
    //    part()->paintEverything( painter, ev->rect(), FALSE, this );
    // paint everything
    koDocument()->paintEverything( painter, rect(), FALSE, this );


    painter.end();
}

void KChartView::updateReadWrite( bool /*readwrite*/ )
{
#ifdef __GNUC__
#warning TODO
#endif
}

void KChartView::createTempData()
{
    int row, col;
    int nbrow,nbcol;

    KoChart::Data *dat = ((KChartPart*)koDocument())->data();

    // initialize some data, if there is none
    nbrow=4;
    nbcol=4;
    if (dat->rows() == 0)
        {
            kdDebug(35001) << "Initialize with some data!!!" << endl;
            dat->expand(4,4);
            dat->setUsedCols( 4 );
            dat->setUsedRows( 4 );
            for (row = 0;row < nbrow;row++)
                for (col = 0;col < nbcol;col++)
                    {
			//	  _widget->fillCell(row,col,row+col);
                        KoChart::Value t( (double)row+col );
			kdDebug(35001) << "Set cell for " << row << "," << col << endl;
			dat->setCell(row,col,t);
                    }
            //      _dlg->exec();
        }
}


void KChartView::edit()
{
    kchartDataEditor ed;
    KChartParams* params=((KChartPart*)koDocument())->params();

    KoChart::Data *dat = (( (KChartPart*)koDocument())->data());
    kdDebug(35001)<<"***Before calling editor: cols ="<<dat->cols()<<" , rows = "<<dat->rows()<<" , usedCols = "<<dat->usedCols()<<"  usedRows = "<<dat->usedRows()<<endl;
    ed.setData(dat);
    ed.setAxisLabelTextShort( ( (KChartPart*)koDocument() )->axisLabelTextShort() );
    ed.setAxisLabelTextLong( ( (KChartPart*)koDocument() )->axisLabelTextLong() );

    QStringList lst;
    for( uint i =0; i < dat->rows(); i++ )
        lst<<params->legendText( i );
    ed.setLegend(lst);

    QStringList *axisLabelTextLong = ( ( (KChartPart*)koDocument() )->axisLabelTextLong() );
    if( axisLabelTextLong )
    {
        QStringList lstLabel( *axisLabelTextLong );
        ed.setXLabel( lstLabel );
    }
    if( ed.exec() != QDialog::Accepted ) {
        return;
    }
    ed.getData(dat);
    ed.getLegend(params);
    ed.getXLabel(params );
    kdDebug(35001)<<"***After calling editor: cols ="<<dat->cols()<<" , rows = "<<dat->rows()<<" , usedCols = "<<dat->usedCols()<<"  usedRows = "<<dat->usedRows()<<endl;
    repaint();
}

void KChartView::wizard()
{
    kdDebug(35001) << "Wizard called" << endl;
    KChartWizard *wiz =
	new KChartWizard((KChartPart*)koDocument(), this, "KChart Wizard", true);
    kdDebug(35001) << "Executed. Now, display it" << endl;
    if(wiz->exec())
    {
        repaint();
        updateGuiTypeOfChart();
        kdDebug(35001) << "Ok, executed..." << endl;
    }
}

void KChartView::updateGuiTypeOfChart()
{
  KDChartParams* params = ((KChartPart*)koDocument())->params();
  switch(params->chartType())
    {
    case KDChartParams::Bar:
      m_chartbars->setChecked(true);
      break;
    case KDChartParams::Line:
      m_chartline->setChecked(true);
      break;
    case KDChartParams::Area:
      m_chartareas->setChecked(true);
      break;
    case KDChartParams::Pie:
      m_chartpie->setChecked(true);
      break;
    case KDChartParams::HiLo:
      m_charthilo->setChecked(true);
      break;
    case KDChartParams::Gantt:
      //todo
      break;
    case KDChartParams::Ring:
      m_chartring->setChecked(true);
      break;
    case KDChartParams::Polar:
        m_chartpolar->setChecked(true);
        break;
    default:
      //todo
      break;
    }
  updateButton();
}

void KChartView::slotConfig()
{
    config(KChartConfigDialog::KC_ALL);
}

void KChartView::config(int flags)
{
    // open a config dialog depending on the chart type
    KChartParams* params = ((KChartPart*)koDocument())->params();
    KoChart::Data *dat = (( (KChartPart*)koDocument())->data());
    KChartConfigDialog* d = new KChartConfigDialog( params, this, flags, dat );
    connect( d, SIGNAL( dataChanged() ),
             this, SLOT( slotRepaint() ) );
    d->exec();
    delete d;
}

void KChartView::slotRepaint()
{
    repaint();
}


void KChartView::saveConfig() {
    kdDebug(35001) << "Save config..." << endl;
    ((KChartPart*)koDocument())->saveConfig( KGlobal::config() );
}

void KChartView::loadConfig() {
    kdDebug(35001) << "Load config..." << endl;
    KGlobal::config()->reparseConfiguration();
    ((KChartPart*)koDocument())->loadConfig( KGlobal::config() );
    updateGuiTypeOfChart();
    //refresh chart when you load config
    repaint();
}

void KChartView::defaultConfig() {
    ((KChartPart*)koDocument())->defaultConfig(  );
    updateGuiTypeOfChart();
    repaint();
}


void KChartView::pieChart()
{
  if ( m_chartpie->isChecked() )
    {
      KChartParams* params = ((KChartPart*)koDocument())->params();
      params->setChartType( KDChartParams::Pie );
      params->setThreeDPies( true );
      params->setExplodeFactor( 0 );
      params->setExplode( true );
      updateButton();
      repaint();
    }
  else
        m_chartpie->setChecked( true ); // always one has to be checked !
}

void KChartView::lineChart()
{
  if ( m_chartline->isChecked() )
    {
      KChartParams* params = ((KChartPart*)koDocument())->params();
      params->setChartType( KDChartParams::Line );
      params->setLineChartSubType( KDChartParams::LineNormal );
      updateButton();
      repaint();
    }
  else
    m_chartline->setChecked( true ); // always one has to be checked !

}

void KChartView::barsChart()
{
  if ( m_chartbars->isChecked() )
    {
      KChartParams* params = ((KChartPart*)koDocument())->params();
      params->setChartType( KDChartParams::Bar );
      params->setBarChartSubType( KDChartParams::BarNormal );
      updateButton();
      params->setThreeDBars( true );
      repaint();
    }
  else
    m_chartbars->setChecked( true ); // always one has to be checked !
}

void KChartView::areasChart()
{
  if ( m_chartareas->isChecked() )
    {
      KChartParams* params = ((KChartPart*)koDocument())->params();
      params->setChartType( KDChartParams::Area );
      params->setAreaChartSubType( KDChartParams::AreaNormal );
      updateButton();
      repaint();
    }
  else
    m_chartareas->setChecked( true ); // always one has to be checked !

}


void KChartView::hiLoChart()
{
if ( m_charthilo->isChecked() )
    {
    KChartParams* params = ((KChartPart*)koDocument())->params();
    params->setChartType( KDChartParams::HiLo );
    params->setHiLoChartSubType( KDChartParams::HiLoNormal );
    updateButton();
    repaint();
    }
 else
   m_charthilo->setChecked( true ); // always one has to be checked !
}


void KChartView::ringChart()
{
  if ( m_chartring->isChecked() )
    {
      KChartParams* params = ((KChartPart*)koDocument())->params();
      params->setChartType( KDChartParams::Ring );
      updateButton();
      repaint();
    }
  else
    m_chartring->setChecked( true ); // always one has to be checked !

}

void KChartView::polarChart()
{
    if( m_chartpolar->isChecked() )
    {
        KDChartParams* params = ((KChartPart*)koDocument())->params();
        params->setChartType( KDChartParams::Polar );
        params->setPolarChartSubType( KDChartParams::PolarNormal );
        repaint();
    }
    else
        m_chartpolar->setChecked( true ); // always one has to be checked !
}

void KChartView::mousePressEvent ( QMouseEvent *e )
{
    if(!koDocument()->isReadWrite() || !factory())
        return;
    if( e->button() == RightButton )
        ((QPopupMenu*)factory()->container("action_popup",this))->popup(QCursor::pos());
}

void KChartView::slotConfigColor()
{
    config(KChartConfigDialog::KC_COLORS);
}

void KChartView::slotConfigFont()
{
    config(KChartConfigDialog::KC_FONT);
}

void KChartView::slotConfigBack()
{
    config(KChartConfigDialog::KC_BACK);
}

void KChartView::slotConfigLegend()
{
   config(KChartConfigDialog::KC_LEGEND);
}

void KChartView::slotConfigSubTypeChart()
{
    config(KChartConfigDialog::KC_SUBTYPE);
}

void KChartView::slotConfigHeaderFooterChart()
{
    config(KChartConfigDialog::KC_HEADERFOOTER);
}

void KChartView::updateButton()
{
    //disable sub chart config item.
    KChartParams* params = ((KChartPart*)koDocument())->params();
    bool state=(params->chartType()==KDChartParams::Bar ||
                params->chartType()==KDChartParams::Area ||
                params->chartType()==KDChartParams::Line ||
                params->chartType()==KDChartParams::HiLo ||
                params->chartType()==KDChartParams::Polar);
    m_subTypeChartConfig->setEnabled(state);
}

void KChartView::slotConfigPageLayout()
{
    KChartParams* params = ((KChartPart*)koDocument())->params();
    KChartPageLayout *dialog=new KChartPageLayout(params,this,"Page Layout");
    connect( dialog, SIGNAL( dataChanged() ),
             this, SLOT( slotRepaint() ) );
    dialog->exec();
    delete dialog;
}

#include "kchart_view.moc"
