/***************************************************************************
**
**  This file is part of SciFigs.
**
**  This library 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.1 of the License, or (at your option) any later version.
**
**  This file 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 library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2008-03-28
**  Copyright: 2008-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpCoreMath.h>

#include "AxisScaleProperties.h"
#include "Axis.h"

namespace SciFigs {

  /*!
    \class AxisScaleProperties AxisScaleProperties.h
    \brief Brief description of class still missing

    Full description of class still missing
  */

  /*!
    Description of constructor still missing
  */
  AxisScaleProperties::AxisScaleProperties(QWidget * parent)
      : PropertyWidget(parent)
  {
    TRACE
    setupUi(this);

    addProperty(MinimumValue, minimumEdit, minimumLabel);
    addProperty(MaximumValue, maximumEdit, maximumLabel);
    addProperty(MajorTicks, majorTicks, majorTicksLabel);
    addProperty(MinorTicks, minorTicks, minorTicksLabel);
    addProperty(AutoTicks, autoTicks);
    addProperty(ShowLabels, showLabels);
    addProperty(ZoomEnabled, zoomEnabled);
    addProperty(ScaleType, scaleType, scaleLabel);
    addProperty(SizeType, sizeType, sizeLabel);
    addProperty(SizeInfo, sizeEdit, sizeLabel);
    addProperty(ReversedScale, reversedScale);
  }

  PropertyValue::WidgetType AxisScaleProperties::determineCustomWidgetType(int pid, QWidget *, QWidget * )
  {
    switch(pid) {
    case MinimumValue:
    case MaximumValue:
      return PropertyValue::Custom0;
    default:
      return PropertyValue::Unknown;
    }
  }

  bool AxisScaleProperties::connectCustomWidget(PropertyValue & p)
  {
    if(p.widgetType()==PropertyValue::Custom0) {
      QObject::connect(p.widget(), SIGNAL(textChanged(const QString&)), this, SLOT(rangeTouched()));
      return true;
    } else {
      return false;
    }
  }

  bool AxisScaleProperties::setCustomWidget(PropertyValue & p)
  {
    if(p.widgetType()==PropertyValue::Custom0) {
      QLineEdit * w=static_cast<QLineEdit *>(p.widget());
      w->setText(p.value().toString());
      w->setCursorPosition(0);
      return true;
    } else {
      return false;
    }
  }

  QVariant AxisScaleProperties::customWidgetValue(PropertyValue & p)
  {
    if(p.widgetType()==PropertyValue::Custom0) {
      return static_cast<QLineEdit *>(p.widget())->text();
    } else {
      return QVariant();
    }
  }

  void AxisScaleProperties::rangeTouched()
  {
    PropertyValue * pMin=propertyValue(MinimumValue);
    PropertyValue * pMax=propertyValue(MaximumValue);
    if(pMin->isFrozen() || pMax->isFrozen()) return;
    bool ok=true;
    double min=_currentAxis->toDouble(minimumEdit->text(), ok);
    double max=_currentAxis->toDouble(maximumEdit->text(), ok);
    if(ok) {
      if(min<=max) {
        emit setProperty(MinimumValue, minimumEdit->text());
        emit setProperty(MaximumValue, maximumEdit->text());
        pMin->freeze(true);
        pMax->freeze(true);
        emit refreshValues();
        pMin->freeze(false);
        pMax->freeze(false);
      }
    }
  }

  void AxisScaleProperties::setWidgets()
  {
    PropertyWidget::setWidgets();
    if(sizeType->currentIndex()==2) {
      sizeEdit->setSuffix("");
      sizeEdit->setPrefix("1/" );
    } else {
      sizeEdit->setSuffix(" cm");
      sizeEdit->setPrefix("");
    }
  }

  void AxisScaleProperties::on_minZoom_clicked()
  {
    TRACE;
    switch(_currentAxis->scaleType()) {
    case Scale::Inversed:
    case Scale::InversedLog:
      emit setProperty(MinimumValue, 1.0/_currentAxis->visibleMinimum());
      break;
    default:
      emit setProperty(MinimumValue, _currentAxis->visibleMinimum());
      break;
    }
    emit refreshValues();
  }

  void AxisScaleProperties::on_maxZoom_clicked()
  {
    TRACE;
    switch(_currentAxis->scaleType()) {
    case Scale::Inversed:
    case Scale::InversedLog:
      emit setProperty(MaximumValue, 1.0/_currentAxis->visibleMaximum());
      break;
    default:
      emit setProperty(MaximumValue, _currentAxis->visibleMaximum());
      break;
    }
    emit refreshValues();
  }

  void AxisScaleProperties::on_minContent_clicked()
  {
    TRACE;
    Rect r=_currentAxis->boundingRect();
    switch(_currentAxis->scaleType()) {
    case Scale::Inversed:
    case Scale::InversedLog:
      switch (_currentAxis->orientation()) {
      case Axis::North:
      case Axis::South:
        emit setProperty(MinimumValue, 1.0/r.x2());
        break;
      case Axis::East:
      case Axis::West:
        emit setProperty(MinimumValue, 1.0/r.y2());
        break;
      }
      break;
    default:
      switch (_currentAxis->orientation()) {
      case Axis::North:
      case Axis::South:
        emit setProperty(MinimumValue, r.x1());
        break;
      case Axis::East:
      case Axis::West:
        emit setProperty(MinimumValue, r.y1());
        break;
      }
      break;
    }
    emit refreshValues();
  }

  void AxisScaleProperties::on_maxContent_clicked()
  {
    TRACE;
    Rect r=_currentAxis->boundingRect();
    switch(_currentAxis->scaleType()) {
    case Scale::Inversed:
    case Scale::InversedLog:
      switch (_currentAxis->orientation()) {
      case Axis::North:
      case Axis::South:
        emit setProperty(MaximumValue, 1.0/r.x1());
        break;
      case Axis::East:
      case Axis::West:
        emit setProperty(MaximumValue, 1.0/r.y1());
        break;
      }
      break;
    default:
      switch (_currentAxis->orientation()) {
      case Axis::North:
      case Axis::South:
        emit setProperty(MaximumValue, r.x2());
        break;
      case Axis::East:
      case Axis::West:
        emit setProperty(MaximumValue, r.y2());
        break;
      }
      break;
    }
    emit refreshValues();
  }

  int AxisScaleProperties::scaleType2item(Scale::Type st)
  {
    TRACE;
    switch (st) {
    case Scale::Inversed:
      return 1;
    case Scale::Log:
      return 2;
    case Scale::InversedLog:
      return 3;
    case Scale::AbsoluteTime:
      return 4;
    case Scale::RelativeTime:
      return 5;
    case Scale::Linear:
      break;
    }
    return 0;
  }

  Scale::Type AxisScaleProperties::item2scaleType(int index)
  {
    TRACE;
    switch (index) {
    case 1:
      return Scale::Inversed;
    case 2:
      return Scale::Log;
    case 3:
      return Scale::InversedLog;
    case 4:
      return Scale::AbsoluteTime;
    case 5:
      return Scale::RelativeTime;
    default:
      return Scale::Linear;
    }
  }

  int AxisScaleProperties::sizeType2item(Axis::SizeType st)
  {
    TRACE;
    switch (st) {
    case Axis::AxisSize:
      return 1;
    case Axis::Scaled:
      return 2;
    default:
      return 0;
    }
  }

  Axis::SizeType AxisScaleProperties::item2sizeType(int index)
  {
    TRACE;
    switch (index) {
    case 1:
      return Axis::AxisSize;
    case 2:
      return Axis::Scaled;
    default:
      return Axis::TotalSize;
    }
  }

} // namespace SciFigs
