/***************************************************************************
**
**  This file is part of matfiles.
**
**  This file may be distributed and/or modified under the terms of the
**  GNU General Public License version 2 or 3 as published by the Free
**  Software Foundation and appearing in the file LICENSE.GPL included
**  in the packaging of this file.
**
**  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 General Public License for
**  more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program. If not, see <http://www.gnu.org/licenses/>.
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2013-11-21
**  Authors:
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#ifndef GP_MATLAB_LIBS

#include "MatContext.h"

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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
MatContext::MatContext()
{
  TRACE;
  _current=0;
  _state=Waiting;
}

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

void MatContext::openMatrix()
{
  TRACE;
  ASSERT(!_current);
  _current=new MatArray;
  _state=Waiting;
  _dataCount=0;
}

void MatContext::closeMatrix()
{
  _arrays.append(_current);
  _current=0;
}

bool MatContext::beginElement(int count)
{
  TRACE;
  ASSERT(_current);
  switch(_state) {
  case Waiting:
    _state=Flagging;
    break;
  case RealAdding:
    _dataCount=_current->dataCount();
    if(count!=_dataCount) {
      App::log(tr("MatContext: inconsistencies in dimensions (%1) and array size (%2)\n").arg(_dataCount).arg(count) );
      return false;
    }
    _realIndex=0;
    _imaginaryIndex=0;
    _current->allocateData();
    break;
  case Flagging:
  case Dimensioning:
  case Naming:
    break;
  case ImaginaryAdding:
  case Done:
    App::log(tr("MatContext: unexpected element\n") );
    break;
  }
  return true;
}

bool MatContext::endElement()
{
  TRACE;
  ASSERT(_current);
  switch(_state) {
  case Waiting:
    ASSERT(false);
    break;
  case Flagging:
    _state=Dimensioning;
    break;
  case Dimensioning:
    if(_current->dimensionCount()<2) {
      App::log(tr("MatContext: minimum number of dimension for an array is 2\n") );
      return false;
    }
    _state=Naming;
    break;
  case Naming:
    _state=RealAdding;
    break;
  case RealAdding:
    if(_current->complex()) {
      _state=ImaginaryAdding;
    } else {
      _state=Done;
    }
    break;
  case ImaginaryAdding:
    _state=Done;
    break;
  case Done:
    break;
  }
  return true;
}

MatArray * MatContext::array(const QString& name) const
{
  for(QVector<MatArray *>::const_iterator it=_arrays.begin(); it!=_arrays.end(); it++) {
    if((*it)->name()==name) {
      return *it;
    }
  }
  return 0;
}

#endif // GP_MATLAB_LIBS
