/***************************************************************************
**
**  This file is part of GeopsyCore.
**
**  GeopsyCore 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.
**
**  GeopsyCore 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: 2008-07-10
**  Copyright: 2008-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "StationList.h"

namespace GeopsyCore {

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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
StationList::StationList()
{
  TRACE;
  _components=StationSignals::UndefinedComponent;
}

/*!
  Description of destructor still missing
*/
StationList::~StationList()
{
  TRACE;
  qDeleteAll(*this);
}

void StationList::setComponents(StationSignals::Components c)
{
  _components=c;
}

/*!
  Add signals of \a subPool to list
*/
bool StationList::addSignals(SubSignalPool * subPool)
{
  TRACE;
  for(SubSignalPool::iterator it=subPool->begin(); it!=subPool->end(); it++) {
    if(!addSignal(*it)) {
      return false;
    }
  }
  return true;
}

/*!
  Add signal \a sig to list
*/
bool StationList::addSignal(Signal * sig)
{
  TRACE;
  // Check for new components
  if (_components==StationSignals::AnySingleComponent) {
    // Try to find a matching station or if it is a new station
    // For AnySingleComponent mode, the component must also be the same for all signals in a station
    for(iterator it=begin(); it!=end(); ++it) {
      StationSignals * stat=*it;
      if(stat->component()!=sig->component()) {
        App::log(tr("Only one component type is allowed (%1<->%2).\n")
              .arg(stat->firstValidSignal()->componentUserName())
              .arg(sig->componentUserName()));
        return false;
      }
      if(stat->name()==sig->name() &&
         stat->utmZone()==sig->utmZone() &&
         stat->coordinates()==sig->receiver()) {
        return stat->addSignal(sig);
      }
    }
  } else if(_components==StationSignals::AnyComponent) {
    // Try to find a matching station or if it is a new station
    for (iterator it=begin(); it!=end(); ++it) {
      StationSignals * stat=*it;
      if(stat->name()==sig->name() &&
         stat->coordinates()==sig->receiver() &&
         stat->utmZone()==sig->utmZone() &&
         stat->component()==sig->component()) {
        return stat->addSignal(sig);
      }
    }
  } else {
    StationSignals::Components components=_components;
    switch (sig->component()) {
    case Signal::Vertical:
      components |= StationSignals::VerticalComponent;
      break;
    case Signal::North:
    case Signal::East:
      components |= StationSignals::HorizontalComponent;
      break;
    default:
      App::log(tr("Only Vertical, East or North components are allowed (%1).\n")
                       .arg(sig->componentUserName()));
      return false;
    }
    if(components!=_components) {
      // Correct number of components
      for(iterator it=begin(); it!=end(); ++it) {
        (*it)->setComponents(components);
      }
      _components=components;
    }
    // Try to find a matching station or if it is a new station
    for(iterator it=begin();it!=end();++it) {
      StationSignals * stat=*it;
      if(stat->name()==sig->name() &&
         stat->utmZone()==sig->utmZone() &&
         stat->coordinates()==sig->receiver()) {
        return stat->addSignal(sig);
      }
    }
  }
  StationSignals * stat=new StationSignals(_components);
  append(stat);
  return stat->addSignal(sig);
}

bool StationList::hasAllComponents() const
{
  TRACE;
  for(const_iterator it=begin();it!=end();++it) {
    if(!(*it)->hasAllComponents()) return false;
  }
  return true;
}

QList<NamedPoint> StationList::pointList() const
{
  TRACE;
  QList<NamedPoint> points;
  for(const_iterator it=begin(); it!=end(); it++) {
    StationSignals& stat=**it;
    points.append(NamedPoint(stat.name(), stat.coordinates()));
  }
  return points;
}

} // namespace GeopsyCore
