/***********************************************************************
**
**   settingspagemap.cpp
**
**   This file is part of Cumulus
**
************************************************************************
**
**   Copyright (c):  2002 by André Somers
**
**   This file is distributed under the terms of the General Public
**   Licence. See the file COPYING for more information.
**
**   $Id: settingspagemap.cpp,v 1.27 2005/02/28 10:23:51 andre Exp $
**
***********************************************************************/

#include <qlayout.h>
#include <qlabel.h>
#include <qlineedit.h>

#include "settingspagemap.h"
#include "generalconfig.h"

SettingsPageMap::SettingsPageMap(QWidget *parent, const char *name ) : QWidget(parent,name) {
  QGridLayout * topLayout = new QGridLayout(this, 3,2,5);
  int row=0;

  advancedPage = new SettingsPageMapAdv(this, "advancedMapPage");

  lvLoadOptions = new QListView(this, "loadoptionlist");
  lvLoadOptions->addColumn(tr("Load / show map object"),192);
  lvLoadOptions->setAllColumnsShowFocus(true);
  topLayout->addMultiCellWidget(lvLoadOptions,0,0,0,1);
  topLayout->setRowStretch(row++,100);

  topLayout->addRowSpacing(row++,10);
  
  chkDrawDirectionLine = new QCheckBox(tr("Draw Bearing line"), this );
  topLayout->addWidget(chkDrawDirectionLine,row++,0);

  cmdAdvanced = new QPushButton(tr("Advanced..."), this );
  topLayout->addWidget(cmdAdvanced, row++, 1, AlignRight);
  connect(cmdAdvanced, SIGNAL(clicked()), advancedPage, SLOT(showMaximized()));
}


SettingsPageMap::~SettingsPageMap(){
}


/** Called to initiate loading of the configurationfile */
void SettingsPageMap::slot_load(){
  GeneralConfig *conf = GeneralConfig::instance();

  chkDrawDirectionLine->setChecked(conf->getMapBearLine());
  
  fillLoadOptionList();

  liIsolines->setOn(conf->getMapLoadIsoLines());
  liIsolineBorders->setOn(conf->getMapShowIsoLineBorders());
  liWpLabels->setOn(conf->getMapShowWaypointLabels());
  liWpLabelsExtraInfo->setOn(conf->getMapShowWaypointLabelsExtraInfo());
  liRoads->setOn(conf->getMapLoadRoads());
  liHighways->setOn(conf->getMapLoadHighways());
  liRailroads->setOn(conf->getMapLoadRailroads());
  liCities->setOn(conf->getMapLoadCities());
  liWaterways->setOn(conf->getMapLoadWaterways());
  liForests->setOn(conf->getMapLoadForests());

  advancedPage->slot_load();
}


/** Called to initiate saving to the configurationfile. */
void SettingsPageMap::slot_save(){

  GeneralConfig *conf = GeneralConfig::instance();

  conf->setMapBearLine(chkDrawDirectionLine->isChecked());

  conf->setMapLoadIsoLines(liIsolines->isOn());
  conf->setMapShowIsoLineBorders(liIsolineBorders->isOn());
  conf->setMapShowWaypointLabels(liWpLabels->isOn());
  conf->setMapShowWaypointLabelsExtraInfo(liWpLabelsExtraInfo->isOn());
  conf->setMapLoadRoads(liRoads->isOn());
  conf->setMapLoadHighways(liHighways->isOn());
  conf->setMapLoadRailroads(liRailroads->isOn());
  conf->setMapLoadCities(liCities->isOn());
  conf->setMapLoadWaterways(liWaterways->isOn());
  conf->setMapLoadForests(liForests->isOn());

  advancedPage->slot_save();
}


/** Fills the list with loadoptions */
void SettingsPageMap::fillLoadOptionList(){
  liIsolines=new QCheckListItem(lvLoadOptions, tr("Isolines"), QCheckListItem::CheckBox);
  liIsolineBorders=new QCheckListItem(lvLoadOptions, tr("Isoline borders"), QCheckListItem::CheckBox);
  liWpLabels=new QCheckListItem(lvLoadOptions, tr("Waypoint labels"), QCheckListItem::CheckBox);
  liWpLabelsExtraInfo=new QCheckListItem(lvLoadOptions, tr("Waypoint labels - Extra info"), QCheckListItem::CheckBox);
  liRoads=new QCheckListItem(lvLoadOptions, tr("Roads"), QCheckListItem::CheckBox);
  liHighways=new QCheckListItem(lvLoadOptions, tr("Highways"), QCheckListItem::CheckBox);
  liRailroads=new QCheckListItem(lvLoadOptions, tr("Railroads"), QCheckListItem::CheckBox);
  liCities=new QCheckListItem(lvLoadOptions, tr("Cities & Villages"), QCheckListItem::CheckBox);
  liWaterways=new QCheckListItem(lvLoadOptions, tr("Rivers & Canals"), QCheckListItem::CheckBox);
  liForests=new QCheckListItem(lvLoadOptions, tr("Forests & Ice"), QCheckListItem::CheckBox);
}


/* Called to ask is confirmation on the close is needed. */
void SettingsPageMap::slot_query_close(bool& warn, QStringList& warnings)
{
  /*forward request to advanced page */
  advancedPage->slot_query_close(warn, warnings);   
}


/******************************************************************************************************************************/
/*   Advanced map page    */
/*****************************************************************************************************************************/

SettingsPageMapAdv::SettingsPageMapAdv(QWidget *parent, const char *name) : QDialog(parent, name, true, Qt::WStyle_StaysOnTop) {
  setCaption(tr("Advanced map settings"));
  QGridLayout * topLayout = new QGridLayout(this, 6,2,5);
  int row=0;

  topLayout->addWidget(new QLabel(tr("Projection:"), this),row,0);
  cmbProjection=new QComboBox(this);
  topLayout->addWidget(cmbProjection, row++, 1);
  cmbProjection->insertItem(tr("Lambert"));
  cmbProjection->insertItem(tr("Plate Carée"));
  connect(cmbProjection, SIGNAL(activated(int)), this, SLOT(slotSelectProjection(int)));

  topLayout->addWidget(new QLabel(tr("1. St. Parallel:"), this),row,0);
  edtLat1=new LatEdit(this);
  topLayout->addWidget(edtLat1, row++, 1);

  topLayout->addWidget(new QLabel(tr("2. St. Parallel:"), this),row,0);
  edtLat2=new LatEdit(this);
  topLayout->addWidget(edtLat2, row++, 1);

  topLayout->addWidget(new QLabel(tr("Origin Lon.:"), this),row,0);
  edtLon=new LongEdit(this);
  topLayout->addWidget(edtLon, row++, 1);

  topLayout->addRowSpacing(row++,10);
 
  chkDeleteAfterCompile = new QCheckBox(tr("Delete original maps after compiling"), this );
  topLayout->addMultiCellWidget(chkDeleteAfterCompile,row, row ,0, 1);
  row++;

  chkUnloadUnneeded = new QCheckBox(tr("Immediately unload unneeded maps"), this );
  topLayout->addMultiCellWidget(chkUnloadUnneeded,row, row ,0, 1);
  row++;

  topLayout->setRowStretch(row, 20);

  currentProjType = ProjectionBase::Unknown;
}


SettingsPageMapAdv::~SettingsPageMapAdv(){
}


void SettingsPageMapAdv::slot_load()
{
  GeneralConfig *conf = GeneralConfig::instance();

  chkDeleteAfterCompile->setChecked( conf->getMapDeleteAfterCompile() );
  chkUnloadUnneeded->setChecked( conf->getMapUnload() );

  currentProjType = conf->getMapProjectionType();
  lambertV1 =       conf->getLambertParallel1();
  lambertV2 =       conf->getLambertParallel2();
  lambertOrigin =   conf->getLambertOrign();
  cylinPar =        conf->getCylinderParallel();

  // @AP: Note, that the index of the list starts with 0 but the
  // ProjectionType uses zero for unknown. So we must subtract 1
  // to get the right value.

  int projIndex = currentProjType - 1;
  cmbProjection->setCurrentItem(projIndex);
  slotSelectProjection(projIndex);
}


void SettingsPageMapAdv::slot_save()
{
        // @AP: here we must overtake the new user values at first. after that
        // we can store them.
        // Check, if input string values have been changed. If not, no
        // overtake of values to avoid roundings errors. They can appear if
        // the position formats will be changed between DMS <-> DDM vise
        // versa.

  switch(cmbProjection->currentItem())
    {
    case 0:
      if( edtLat1->isInputChanged() )
        lambertV1 = edtLat1->KFLogDegree();
      if( edtLat2->isInputChanged() )
        lambertV2 = edtLat2->KFLogDegree();
      if( edtLon->isInputChanged() )
        lambertOrigin = edtLon->KFLogDegree();
      break;
    case 1:
      if( edtLat1->isInputChanged() )	    
        cylinPar = edtLat1->KFLogDegree();
      break;
    }

  GeneralConfig *conf = GeneralConfig::instance();

  conf->setMapDeleteAfterCompile( chkDeleteAfterCompile->isChecked() );
  conf->setMapUnload( chkUnloadUnneeded->isChecked() );
  conf->setMapProjectionType( currentProjType );
  conf->setLambertParallel1( lambertV1 );
  conf->setLambertParallel2( lambertV2 );
  conf->setLambertOrign( lambertOrigin );
  conf->setCylinderParallel( cylinPar );
}


// selection in the combo box has been changed. index is a reference
// to the current entry. initialize widgets with the internal values
// normally read from the config file.
void SettingsPageMapAdv::slotSelectProjection(int index){

  switch(index)
    {
    case 0:    // Lambert
      edtLat2->setEnabled(true);
      edtLon-> setEnabled(true);
      edtLat1->setKFLogDegree(lambertV1);
      edtLat2->setKFLogDegree(lambertV2);
      edtLon->setKFLogDegree(lambertOrigin);
      currentProjType = ProjectionBase::Lambert;
      break;
    case 1:    // Plate Carée
    default:   // take this if index is unknown
      edtLat2->setEnabled(false);
      edtLon->setEnabled(false);
      edtLat1->setKFLogDegree(cylinPar);
      edtLat2->setKFLogDegree(0);
      edtLon->setKFLogDegree(0);
      currentProjType = ProjectionBase::Cylindric;
      break;
    }
}


void SettingsPageMapAdv::reject(){
  slot_load();
}


/* Called to ask is confirmation on the close is needed. */
void SettingsPageMapAdv::slot_query_close(bool& warn, QStringList& warnings)
{
  /*set warn to 'true' if the data has changed. Note that we can NOT just set warn equal to
  _changed, because that way we might erase a warning flag set by another page! */
  bool changed=false;
  GeneralConfig *conf = GeneralConfig::instance();
   
  changed = changed || (chkDeleteAfterCompile->isChecked() != conf->getMapDeleteAfterCompile() );
  changed = changed || (chkUnloadUnneeded->isChecked() != conf->getMapUnload() );
    
  switch(cmbProjection->currentItem())
    {
    case 0:
      changed = changed || ( edtLat1->isInputChanged() );
      changed = changed || ( edtLat2->isInputChanged() );
      changed = changed || ( edtLon->isInputChanged() );
      break;
    case 1:
      changed = changed || ( edtLat1->isInputChanged() );     
      break;
    }

  changed = changed || (currentProjType != conf->getMapProjectionType());

  if (changed) {
    warn=true;
    warnings.append(tr("the advanced map settings"));
  }
}

