/***************************************************************************
**
**  This file is part of GeopsyGui.
**
**  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: 2005-09-20
**  Copyright: 2005-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <math.h>

#include <QGpGuiTools.h>
#include "SignalsProperties.h"

namespace GeopsyGui {

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

  Full description of class still missing
*/

/*
 *  Constructs a SignalsProperties as a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'.
 */
SignalsProperties::SignalsProperties(QWidget* parent)
    : PropertyWidget(parent)
{
  TRACE;
  _signalColorEditor=nullptr;
  _currentLayer=nullptr;
  setupUi(this);

  // Create properties
  addProperty(ColoredSection, coloredSection);
  addProperty(IsSpectrum);
  addProperty(Wiggle, wiggle);
  addProperty(VariableArea, variableArea);
  addProperty(Normalize, normalize);

  addProperty(NormalizeValue, normalizeValue, normalizeLabel);
  addProperty(ClipMode, clipMode);
  addProperty(ClipValue, clipValue);
  addProperty(Overlap, overlap, overlapLabel);
  addProperty(Offset, offset);

  addProperty(YAxis, yAxis);

  addProperty(TimeScale, timeScale);

  addProperty(TimeRange, timeRange);
  addProperty(AroundPickName, aroundPickEdit, aroundPickLabel);
  addProperty(BeforePickDelay, beforePickEdit, beforePickLabel);
  addProperty(AfterPickDelay, afterPickEdit, afterPickLabel);
  addProperty(CustomRange, customTimeRange);
}

/*
 *  Destroys the object and frees any allocated resources
 */
SignalsProperties::~SignalsProperties()
{
  TRACE;
  // no need to delete child widgets, Qt does it all for us
}

void SignalsProperties::setCurrentLayer(SignalLayer * l)
{
  _currentLayer=l;
  customTimeRange->blockSignals(true);
  customTimeRange->setSubPool(l->subPool());
  customTimeRange->blockSignals(false);
  aroundPickEdit->clear();
  aroundPickEdit->addItems(TimePick::registeredNames());
}

PropertyValue::WidgetType SignalsProperties::determineCustomWidgetType(int pid, QWidget *, QWidget * )
{
  if(pid==CustomRange) {
    return PropertyValue::Custom0;
  } else {
    return PropertyValue::Unknown;
  }
}

bool SignalsProperties::connectCustomWidget(PropertyValue & p)
{
  TRACE;
  if(p.widgetType()==PropertyValue::Custom0) {
    QObject::connect(customTimeRange, SIGNAL(parametersChanged()), &p, SLOT(touched()) );
    return true;
  } else {
    return false;
  }
}

bool SignalsProperties::setCustomWidget(PropertyValue & p)
{
  if(p.widgetType()==PropertyValue::Custom0) {
    static_cast<TimeRangeParameterWidget *>(p.widget())->setParameters(p.value().value<TimeRangeParameters>());
    return true;
  } else {
    return false;
  }
}

QVariant SignalsProperties::customWidgetValue(PropertyValue & p)
{
  if(p.widgetType()==PropertyValue::Custom0) {
    TimeRangeParameters t;
    static_cast<TimeRangeParameterWidget *>(p.widget())->getParameters(t);
    return QVariant::fromValue(t);
  } else {
    return QVariant();
  }
}

void SignalsProperties::setWidgets()
{
  TRACE;
  PropertyWidget::setWidgets();
  on_normalize_currentIndexChanged(0);
  on_clipMode_currentIndexChanged(0);
  on_timeRange_currentIndexChanged(0);
  on_coloredSection_clicked();
}

void SignalsProperties::on_coloredSection_clicked()
{
  TRACE;
  bool b=coloredSection->isChecked();
  defaultPaletteValues->setEnabled(b);
  wiggle->setEnabled(!b);
  variableArea->setEnabled(!b);
  setSignalColors->setEnabled(!b);
}

void SignalsProperties::on_normalize_currentIndexChanged(int)
{
  TRACE;
  normalizeValue->setEnabled(normalize->currentIndex()==4);
}

void SignalsProperties::on_clipMode_currentIndexChanged(int)
{
  TRACE;
  clipValue->setEnabled(clipMode->currentIndex() > 1);
}

void SignalsProperties::on_timeRange_currentIndexChanged(int)
{
  TRACE;
  if(timeRange->currentIndex()==1) {
    aroundPickEdit->show();
    aroundPickLabel->show();
    beforePickEdit->show();
    beforePickLabel->show();
    afterPickEdit->show();
    afterPickLabel->show();
  } else {
    aroundPickEdit->hide();
    aroundPickLabel->hide();
    beforePickEdit->hide();
    beforePickLabel->hide();
    afterPickEdit->hide();
    afterPickLabel->hide();
  }
  if(timeRange->currentIndex()==2) {
    customTimeRange->show();
  } else {
    customTimeRange->hide();
  }
}

void SignalsProperties::on_defaultPaletteValues_clicked()
{
  TRACE;
  bool ok;
  double val=fabs(overlap->text().toDouble(&ok) );
  ColorMap pal;
  if(ok) {
     if(value( IsSpectrum).toBool())
      pal.setVLinear(0, val);
    else
      pal.setVLinear( -val * 0.5, val * 0.5);
    emit setColorMapValues(pal);
  }
}

void SignalsProperties::on_setSignalColors_clicked()
{
  TRACE;
  Dialog * d=new Dialog(this);
  d->setWindowTitle(tr("Signal colors"));
  ASSERT(_signalColorEditor==nullptr);
  ASSERT(_currentLayer);
  _signalColorEditor=new LegendProperties;
  _signalColorEditor->setPropertySections(LegendTable::Text | LegendTable::Pen);
  d->setMainWidget(_signalColorEditor, Dialog::TitleClose);
  _signalColorEditor->setLegend(_currentLayer->signalLegend());
  _signalColorEditor->setReadOnlyText(true);
  Settings::getRect(d, "SignalsProperties::legend");
  connect(_signalColorEditor, SIGNAL(touched()), this, SLOT(commitSignalColors()));
  d->exec();
  Settings::setRect(d, "SignalsProperties::legend");
  delete d;
  _signalColorEditor=nullptr;
}

void SignalsProperties::commitSignalColors()
{
  TRACE;
  if(_signalColorEditor) {
    _currentLayer->setSignalLegend(_signalColorEditor->legend());
    _currentLayer->deepUpdate();
  }
}

int SignalsProperties::normalize2item(SignalLayer::Normalize n)
{
  TRACE;
  switch (n) {
  case SignalLayer::NormalizeAll:
    return 0;
  case SignalLayer::NormalizeOne:
    return 1;
  case SignalLayer::NormalizeVisibleAll:
    return 2;
  case SignalLayer::NormalizeVisibleOne:
    return 3;
  case SignalLayer::NormalizeValue:
    return 4;
  }
  return 0;
}

SignalLayer::Normalize SignalsProperties::item2normalize(int index)
{
  TRACE;
  switch (index) {
  case 1:
    return SignalLayer::NormalizeOne;
  case 2:
    return SignalLayer::NormalizeVisibleAll;
  case 3:
    return SignalLayer::NormalizeVisibleOne;
  case 4:
    return SignalLayer::NormalizeValue;
  default:
    return SignalLayer::NormalizeAll;
  }
}

int SignalsProperties::clip2item(SignalLayer::Clip n)
{
  TRACE;
  switch (n) {
  case SignalLayer::NoClip:
    return 0;
  case SignalLayer::ClipOverlap:
    return 1;
  case SignalLayer::ClipValue:
    return 2;
  case SignalLayer::ClipPercentage:
    return 3;
  }
  return 0;
}

SignalLayer::Clip SignalsProperties::item2clip(int index)
{
  TRACE;
  switch (index) {
  case 1:
    return SignalLayer::ClipOverlap;
  case 2:
    return SignalLayer::ClipValue;
  case 3:
    return SignalLayer::ClipPercentage;
  default:
    return SignalLayer::NoClip;
  }
}

int SignalsProperties::offset2item(SignalLayer::Offset n)
{
  TRACE;
  switch (n) {
  case SignalLayer::NoOffset:
    return 0;
  case SignalLayer::GlobalOffset:
    return 1;
  case SignalLayer::VisibleOffset:
    return 2;
  }
  return 0;
}

SignalLayer::Offset SignalsProperties::item2offset(int index)
{
  TRACE;
  switch (index) {
  case 1:
    return SignalLayer::GlobalOffset;
  case 2:
    return SignalLayer::VisibleOffset;
  default:
    return SignalLayer::NoOffset;
  }
}

int SignalsProperties::yAxis2item(SignalLayer::YAxis n)
{
  TRACE;
  switch (n) {
  case SignalLayer::ViewerIndex:
    return 0;
  case SignalLayer::Receiver:
    return 1;
  case SignalLayer::SignalName:
    return 2;
  case SignalLayer::Overlay:
    return 3;
  }
  return 0;
}

SignalLayer::YAxis SignalsProperties::item2yAxis(int index)
{
  TRACE;
  switch (index) {
  case 1:
    return SignalLayer::Receiver;
  case 2:
    return SignalLayer::SignalName;
  case 3:
    return SignalLayer::Overlay;
  default:
    return SignalLayer::ViewerIndex;
  }
}

int SignalsProperties::timeScale2item(SignalLayer::TimeScale n)
{
  TRACE;
  switch (n) {
  case SignalLayer::AbsoluteTime:
    return 0;
  case SignalLayer::RelativeToStartTime:
    return 1;
  }
  return 0;
}

SignalLayer::TimeScale SignalsProperties::item2timeScale(int index)
{
  TRACE;
  switch (index) {
  case 1:
    return SignalLayer::RelativeToStartTime;
  default:
    return SignalLayer::AbsoluteTime;
  }
}

int SignalsProperties::timeRange2item(SignalLayer::TimeRange n)
{
  TRACE;
  switch (n) {
  case SignalLayer::AvailableRange:
    return 0;
  case SignalLayer::AroundPickRange:
    return 1;
  case SignalLayer::CustomRange:
    return 2;
  }
  return 0;
}

SignalLayer::TimeRange SignalsProperties::item2timeRange(int index)
{
  TRACE;
  switch (index) {
  case 1:
    return SignalLayer::AroundPickRange;
  case 2:
    return SignalLayer::CustomRange;
  default:
    return SignalLayer::AvailableRange;
  }
}

} // namespace GeopsyGui
