/***************************************************************************
                          Transformation.cpp  -  description
                             -------------------
    begin                : Di Feb 15 2005
    copyright            : (C) 2005 by klaus frieler
    email                : kgf@omniversum.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include "Transformation.h"
namespace Transformations{
MRESULT TransformationFactory::Create(Transformation **ppTransformation, const TransformationType type, const Melody* pMel)
{
   MRESULT  mr = SUCC_OK;
   Transformation *ret = 0;
   if(!ppTransformation){
      return ERR_INVALIDARG;
   }
   if(!pMel){
      return ERR_BAD_OBJECT;
   }
   switch(type){
     case ioi:
        ret = new IOI(pMel);
        if(!ret) mr = ERR_OUTOFMEMORY;
        break;
     case ooi:
        ret = new OOI(pMel);
        if(!ret) mr = ERR_OUTOFMEMORY;
        break;
     case intervals:
        ret = new PitchIntervals(pMel);
        if(!ret) mr = ERR_OUTOFMEMORY;
        break;
     case absIntervals:
        ret = new AbsPitchIntervals(pMel);
        if(!ret) mr = ERR_OUTOFMEMORY;
        break;
      default:
         mr = ERR_INVALIDARG;
         break;
   }
   if(ret) *ppTransformation =  ret;
   return mr;
}

MRESULT TransformationFactory::Destroy(Transformation **ppTransformation)
{
   if(ppTransformation == 0|| *ppTransformation == 0) return ERR_INVALIDARG;
   delete *ppTransformation;
   *ppTransformation = 0;
   return SUCC_OK;
}

MRESULT Transformation::get(Vector& ret)
{
   MRESULT mr = SUCC_OK;
   if(m_cache.empty()){
      mr = getData(m_cache);
   }
   ret = m_cache;
   return mr;
}

MRESULT IOI::getData(Vector& ret)const
{
   ret.clear();
   if(!isValid()){
      return ERR_BAD_OBJECT;
   }
   ret = m_pMel->getIOIs();

   return SUCC_OK;
}

MRESULT OOI::getData(Vector& ret)const
{
   ret.clear();
   if(!isValid()){
      return ERR_BAD_OBJECT;
   }
   ret = m_pMel->getOOIs();
   return SUCC_OK;
}

MRESULT PitchIntervals::getData(Vector& ret)const
{
   ret.clear();
   if(!isValid()){
      return ERR_BAD_OBJECT;
   }
   iData pitches = m_pMel->getPitches();
   if(pitches.empty()){
      return ERR_EMPTY;
   }   
   for(uint i = 0; i<pitches.size()-1; ++i){
      double interval = (double)pitches[i+1] - (double)pitches[i];
      ret.push_back(interval);
   }

   return SUCC_OK;
}

MRESULT AbsPitchIntervals::getData(Vector& ret)const
{
   ret.clear();
   if(!isValid()){
      return ERR_BAD_OBJECT;
   }
   MRESULT mr = PitchIntervals::getData(ret);
   if(FAIL(mr)){
      return mr;
   }
   for(uint i = 0; i<ret.size(); ++i){
      ret[i] = fabs(ret[i]);
   }
   return SUCC_OK;
}

MRESULT AverageIOI::getData(Vector& ret)const
{
   ret.clear();
   if(!isValid()){
      return ERR_BAD_OBJECT;
   }
   MRESULT mr = IOI::getData(ret);
   if(FAIL(mr)){
      return mr;
   }
   double sum = 0.0;
   for(uint i = 0; i<ret.size(); ++i){
      sum += ret[i];
      ret[i] = sum/(i+1);
   }
   return SUCC_OK;
}
}