#ifndef _RIEMANNEVENT_CPP_
#define _RIEMANNEVENT_CPP_

#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "loader.h"
#include "table.h"
#include "str.h"
#include "riemannEvent.h"
#include "riemann.h"

#define MAXVALUE 32

RiemannEvent::RiemannEvent() : _base_key(UNDEFKEY), _base_gen(UNDEFGEN), _key(UNDEFKEY), _genus(UNDEFGEN), _bass(0) {
  _type = EVENT;
  _value = new char[MAXVALUE];
}

RiemannEvent::RiemannEvent(const RiemannEvent& m) : Event(m), _base_key(UNDEFKEY), _base_gen(UNDEFGEN), _key(UNDEFKEY), _genus(UNDEFGEN), _bass(0) {
  _type = EVENT;
  _value = new char[MAXVALUE];
}

RiemannEvent::RiemannEvent(Position pos, Harmony * harmony)
  : Event(pos,0), _base_key(UNDEFKEY), _base_gen(UNDEFGEN), _key(UNDEFKEY), _genus(UNDEFGEN), _bass(0) {
  _type = EVENT;
  _value = new char[MAXVALUE];
  if (harmony!=0) {
    _base_key = harmony->baseKey();
    _base_gen = harmony->baseGenus();
    _key      = harmony->key();
    _genus    = harmony->genus();
    _bass     = harmony->bass();
  }
}

RiemannEvent::~RiemannEvent() {
  delete _value;
}


ostream & RiemannEvent::print(int dep, ostream & s) const {
  s << spc(dep) << "<RIEMANN pos=\"" << internalStart().ticks() << "\" base=\"" << sKey[_key] << "\" genus=\"" << sGenus[_genus] << "\" bass=\"" << _bass
    << "\" />" << endl;
  return s;
}

void RiemannEvent::flush(const char * c) const {
  cout << c << "RIEMANN" << endl;
}

Element * RiemannEvent::copy() const {
  return new RiemannEvent(*this);
}

const char * RiemannEvent::value() {
  if (_bass > 1)
    snprintf(_value, MAXVALUE, "%s %s %d", sKey[_key], sGenus[_genus], _bass);
  else
    snprintf(_value, MAXVALUE, "%s %s", sKey[_key], sGenus[_genus]);
  return _value;
}

void RiemannEvent::set(const char * base, const char * gen, const char * bass) {
  _key  = key(base);
  _genus = genus(gen);
  _bass  = step(bass);
}

Key RiemannEvent::key(const char * k) {
  Key key = UNDEFKEY;
  for (Key i=UNDEFKEY; i<KEY; ((int) i)++)
    if (strcmp(k, sKey[i])==0) key = i;
  return key;
}

Genus RiemannEvent::genus(const char * g) {
  Genus genus = UNDEFGEN;
  for (Genus i=UNDEFGEN; i<GENUS; ((int) i)++)
    if (strcmp(g, sGenus[i])==0) genus = i;
  return genus;
}

int RiemannEvent::step(const char * /* s */ ) {
  int step = 0;
  // for (int i=0; i<INTERVAL; i++) if (strcmp(s, sStep[i])==0) step = i;
  return step;
}

Element * RiemannEvent::load(char * aline, ifstream *& inPtr, Element * parent) {
  cout << "entering RiemannEvent::load" << endl;
  RiemannEvent * riemannEvent = new RiemannEvent();
  Table * attr = Loader::getAttributes("RIEMANN",aline);
  if (attr!=0) {
    String * strPos   = (String*) attr->getEntry("pos");   long pos = atol(strPos->getValue());
    String * strBase  = (String*) attr->getEntry("base");  const char * base  = strBase==0 ? 0 : strBase->getValue();
    String * strGenus = (String*) attr->getEntry("genus"); const char * genus = strGenus==0 ? 0 : strGenus->getValue();
    String * strBass  = (String*) attr->getEntry("bass");  const char * bass  = strBass==0 ? 0 : strBass->getValue();

    riemannEvent->setInternalStart(pos);
    riemannEvent->set(base, genus, bass);

    attr->scratch();
  }
  cout << "leavinging RiemannEvent::load" << endl;
  return riemannEvent;
}



#endif
