// ---------------------------------------------------------------------------
// - Tcz.cpp                                                                 -
// - afnix:tcz service - tcz class implementation                            -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  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.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2023 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Tcz.hpp"
#include "QuarkZone.hpp"
#include "Exception.hpp"

namespace afnix {
  
  // -------------------------------------------------------------------------
  // - private section                                                       -
  // -------------------------------------------------------------------------

  // the content mode
  static const String CS_CMOD_NONE  = "CONTENT-MODE-NONE";
  static const String CS_CMOD_CNST  = "CONTENT-MODE-CONSTANT";
  static const String CS_CMOD_IPUT  = "CONTENT-MODE-INPUT";
  static const String CS_CMOD_OPUT  = "CONTENT-MODE-OUTPUT";
  // alternate content mode
  static const String AS_CMOD_NONE  = "none";
  static const String AS_CMOD_CNST  = "constant";
  static const String AS_CMOD_IPUT  = "input";
  static const String AS_CMOD_OPUT  = "output";

  // the object eval quarks
  static const long QUARK_TCZ       = String::intern("Tcz");
  static const long QUARK_CMODNONE  = String::intern(CS_CMOD_NONE);
  static const long QUARK_CMODCNST  = String::intern(CS_CMOD_CNST);
  static const long QUARK_CMODIPUT  = String::intern(CS_CMOD_IPUT);
  static const long QUARK_CMODOPUT  = String::intern(CS_CMOD_OPUT);

  // -------------------------------------------------------------------------
  // - public section                                                        -
  // -------------------------------------------------------------------------

  // map an item to a content mode
  
  Tcz::t_cmod Tcz::tocmod (const Item& item) {
    // check for a tcz item
    if (item.gettid () != QUARK_TCZ) {
      throw Exception ("tcz-error", "item is not a tcz item");
    }
    // map the item to the enumeration
    long quark = item.getquark ();
    if (quark == QUARK_CMODNONE) return Tcz::CMOD_NONE;
    if (quark == QUARK_CMODCNST) return Tcz::CMOD_CNST;
    if (quark == QUARK_CMODIPUT) return Tcz::CMOD_IPUT;
    if (quark == QUARK_CMODOPUT) return Tcz::CMOD_OPUT;
    throw Exception ("tcz-error", "cannot map item to content mode");
  }

  // map a string to a content mode

  Tcz::t_cmod Tcz::tocmod (const String& smod) {
    // check for none
    if (smod.isnil () == true) return Tcz::CMOD_NONE;
    // map direct mode
    if (smod == CS_CMOD_NONE) return Tcz::CMOD_NONE;
    if (smod == CS_CMOD_CNST) return Tcz::CMOD_CNST;
    if (smod == CS_CMOD_IPUT) return Tcz::CMOD_IPUT;
    if (smod == CS_CMOD_OPUT) return Tcz::CMOD_OPUT;
    // map alternate mode
    if (smod == AS_CMOD_NONE) return Tcz::CMOD_NONE;
    if (smod == AS_CMOD_CNST) return Tcz::CMOD_CNST;
    if (smod == AS_CMOD_IPUT) return Tcz::CMOD_IPUT;
    if (smod == AS_CMOD_OPUT) return Tcz::CMOD_OPUT;
    throw Exception ("tcz-error", "cannot map content mode", smod);
  }

  // map a content mode into an item
  
  Item* Tcz::toitem (const Tcz::t_cmod cmod) {
    Item* result = nullptr;
    switch (cmod) {
    case Tcz::CMOD_NONE:
      result = new Item (QUARK_TCZ, QUARK_CMODNONE);
      break;
    case Tcz::CMOD_CNST:
      result = new Item (QUARK_TCZ, QUARK_CMODCNST);
      break;
    case Tcz::CMOD_IPUT:
      result = new Item (QUARK_TCZ, QUARK_CMODIPUT);
      break;
    case Tcz::CMOD_OPUT:
      result = new Item (QUARK_TCZ, QUARK_CMODOPUT);
      break;
    }
    return result;
  }

  // map a material topology mode into a string

  String Tcz::tostring (const Tcz::t_cmod cmod) {
    String result;
    switch (cmod) {
    case Tcz::CMOD_NONE:
      result = CS_CMOD_NONE;
      break;
    case Tcz::CMOD_CNST:
      result = CS_CMOD_CNST;
      break;
    case Tcz::CMOD_IPUT:
      result = CS_CMOD_IPUT;
      break;
    case Tcz::CMOD_OPUT:
      result = CS_CMOD_OPUT;
      break;
    }
    return result;
  }

  // -------------------------------------------------------------------------
  // - object section                                                        -
  // -------------------------------------------------------------------------

  // evaluate an object data member

  Object* Tcz::meval (Evaluable* zobj, Nameset* nset, const long quark) {
    // map a content mode quark to an item
    if (quark == QUARK_CMODNONE) return Tcz::toitem (Tcz::CMOD_NONE);
    if (quark == QUARK_CMODCNST) return Tcz::toitem (Tcz::CMOD_CNST);
    if (quark == QUARK_CMODIPUT) return Tcz::toitem (Tcz::CMOD_IPUT);
    if (quark == QUARK_CMODOPUT) return Tcz::toitem (Tcz::CMOD_OPUT);
    // invalid quark member
    throw Exception ("eval-error", "cannot evaluate member",
                     String::qmap (quark));
  }
}
