/***************************************************************************
**
**  This file is part of gpfksimulator.
**
**  gpfksimulator is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  gpfksimulator 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 General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2007-11-13
**  Copyright: 2007-2019
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "SourceParameters.h"
#include "Simulator.h"

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

  Full description of class still missing
*/

const QString SourceParameters::xmlSourceParametersTag="SourceParameters";

SourceParameters::SourceParameters()
{
  _name=tr("unnamed");
  _sourcePoint=Point(-1000.0, 0.0, 0.0);
  _azimuth=0.0;
  _amplitude=1.0;
  _phase=0.0;
  _velocity=300.0;
  _ellipticity=1.0;
  _polarization=Mode::Vertical;
  _color=Qt::black;
}

double SourceParameters::azimuth(WaveModel wm) const
{
  double a;
  if(wm==PlaneWaves) {
    a=_azimuth;
  } else {
    a=_sourcePoint.azimuthTo(Point());
  }
  return Angle::mathToGeographic(a);
}

double SourceParameters::azimuthMath(WaveModel wm) const
{
  if(wm==PlaneWaves) {
    return _azimuth;
  } else {
    return _sourcePoint.azimuthTo(Point());
  }
}

double SourceParameters::azimuthMath(WaveModel wm, const Point2D& to) const
{
  if(wm==PlaneWaves) {
    return _azimuth;
  } else {
    return _sourcePoint.azimuthTo(to);
  }
}

void SourceParameters::setAzimuth(WaveModel wm, double a)
{
  if(wm==PlaneWaves) {
    // DoubleSpinBox::setWrapping does not work with range restriction of  Angle::geographicToMath
    _azimuth=0.5*M_PI-Angle::degreesToRadians(a);
  } else {
    a=Angle::geographicToMath(a);
    double d=_sourcePoint.distanceTo(Point());
    _sourcePoint.setX(-d*cos(a));
    _sourcePoint.setY(-d*sin(a));
  }
}

double SourceParameters::distance() const
{
  return _sourcePoint.distanceTo(Point());
}

void SourceParameters::setDistance(double d)
{
  double a=Point().azimuthTo(_sourcePoint);
  _sourcePoint.setX(d*cos(a));
  _sourcePoint.setY(d*sin(a));
}

void SourceParameters::xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const
{
  TRACE;
  Q_UNUSED(context)
  writeProperty(s, "name", _name);
  writeProperty(s, "sourcePoint", _sourcePoint.toString());
  writeProperty(s, "polarization", Mode::polarization(_polarization));
  writeProperty(s, "azimuth", _azimuth);
  writeProperty(s, "amplitude", _amplitude);
  writeProperty(s, "phase", _phase);
  writeProperty(s, "velocity", _velocity);
  writeProperty(s, "ellipticity", _ellipticity);
  writeProperty(s, "color", _color.name());
}

XMLMember SourceParameters::xml_member(XML_MEMBER_ARGS)
{
  TRACE;
  Q_UNUSED(attributes)
  Q_UNUSED(context)
  if(tag=="name" ) return XMLMember(0);
  else if(tag=="sourcePoint") return XMLMember(1);
  else if(tag=="polarization") return XMLMember(2);
  else if(tag=="azimuth") return XMLMember(3);
  else if(tag=="amplitude") return XMLMember(4);
  else if(tag=="phase") return XMLMember(5);
  else if(tag=="velocity") return XMLMember(6);
  else if(tag=="ellipticity") return XMLMember(7);
  else if(tag=="color") return XMLMember(8);
  else return XMLMember(XMLMember::Unknown);
}

bool SourceParameters::xml_setProperty(XML_SETPROPERTY_ARGS)
{
  TRACE;
  Q_UNUSED(tag)
  Q_UNUSED(attributes)
  Q_UNUSED(context)
  switch (memberID) {
  case 0:
    _name=content.toString();
    return true;
  case 1:
    _sourcePoint.fromString(content.toString());
    return true;
  case 2:
    _polarization=Mode::polarization(content.toString());
    return true;
  case 3:
    _azimuth=content.toDouble();
    return true;
  case 4:
    _amplitude=content.toDouble();
    return true;
  case 5:
    _phase=content.toDouble();
    return true;
  case 6:
    _velocity=content.toDouble();
    return true;
  case 7:
    _ellipticity=content.toDouble();
    return true;
  case 8:
    _color.setNamedColor(content.toString());
    return true;
  default:
    return false;
  }
}
