// ---------------------------------------------------------------------------
// - Encoding.cpp                                                            -
// - standard object library - encoding system 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-2019 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Encoding.hpp"
#include "Exception.hpp"
#include "cloc.hpp"

namespace afnix {

  // -------------------------------------------------------------------------
  // - private section                                                       -
  // -------------------------------------------------------------------------

  // the byte mode encoding
  static const t_byte ENC_BYTE_COD = 0x01;
  static const t_byte ENC_UTF8_COD = 0x08;
  
  // the natural encoding
  static const String DEF_MODE_DEF = "DEFAULT";

  // the natural encoding
  static const String DEF_MODE_UTF = "UTF-8";

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

  // get the encoding code by mode

  t_byte Encoding::tocode (const t_emod emod) {
    t_byte result = 0x00;
    switch (emod) {
    case BYTE:
      result = ENC_BYTE_COD;
      break;
    case UTF8:
      result = ENC_UTF8_COD;
      break;
    }
    return result;
  }

  // get the encoding mode by code

  Encoding::t_emod Encoding::toemod (const t_byte code) {
    switch (code) {
    case ENC_BYTE_COD:
      return BYTE;
      break;
    case ENC_UTF8_COD:
      return UTF8;
      break;
    default:
      break;
    }
    throw Exception ("encoding-error", "invalid encoding code to map");
  }
  
  // map the encoding mode by name

  Encoding::t_emod Encoding::toemod (const String& mode) {
    // map to upper case
    String umod = mode.toupper ();
    // check for utf mode
    if ((umod == "UTF-8") || (umod == "UTF_8")) return Encoding::UTF8;
    // default to byte mode
    return Encoding::BYTE;
  }

  // get the transcoding mode by name

  Encoding::t_tmod Encoding::totmod (const String& mode) {
    // map to upper case
    String umod = mode.toupper ();
    Encoding::t_tmod tmod = Encoding::DEFAULT;
    if ((umod == "DEFAULT") ||
	(umod == "ASCII")) {
      tmod = Encoding::DEFAULT;
    } else if ((umod == "ISO-8859-1") ||
	       (umod == "ISO_8859_1")) {
      tmod = Encoding::I8859_01;
    } else if ((umod == "ISO-8859-2") ||
	       (umod == "ISO_8859_2")) {
      tmod = Encoding::I8859_02;
    } else if ((umod == "ISO-8859-3") ||
	       (umod == "ISO_8859_3")) {
      tmod = Encoding::I8859_03;
    } else if ((umod == "ISO-8859-4") ||
	       (umod == "ISO_8859_4")) {
      tmod = Encoding::I8859_04;
    } else if ((umod == "ISO-8859-5") ||
	       (umod == "ISO_8859_5")) {
      tmod = Encoding::I8859_05;
    } else if ((umod == "ISO-8859-6") ||
	       (umod == "ISO_8859_6")) {
      tmod = Encoding::I8859_06;
    } else if ((umod == "ISO-8859-7") ||
	       (umod == "ISO_8859_7")) {
      tmod = Encoding::I8859_07;
    } else if ((umod == "ISO-8859-8") ||
	       (umod == "ISO_8859_8")) {
      tmod = Encoding::I8859_08;
    } else if ((umod == "ISO-8859-9") ||
	       (umod == "ISO_8859_9")) {
      tmod = Encoding::I8859_09;
    } else if ((umod == "ISO-8859-10") ||
	       (umod == "ISO_8859_10")) {
      tmod = Encoding::I8859_10;
    } else if ((umod == "ISO-8859-11") ||
	       (umod == "ISO_8859_11")) {
      tmod = Encoding::I8859_11;
    } else if ((umod == "ISO-8859-13") ||
	       (umod == "ISO_8859_13")) {
      tmod = Encoding::I8859_13;
    } else if ((umod == "ISO-8859-14") ||
	       (umod == "ISO_8859_14")) {
      tmod = Encoding::I8859_14;
    } else if ((umod == "ISO-8859-15") ||
	       (umod == "ISO_8859_15")) {
      tmod = Encoding::I8859_15;
    } else if ((umod == "ISO-8859-16") ||
	       (umod == "ISO_8859_16")) {
      tmod = Encoding::I8859_16;
    } else if ((umod == "UTF-8") ||
	       (umod == "UTF_8")) {
      tmod = Encoding::DEFAULT;
    } else {
      throw Exception ("mode-error", "invalid transcoding mode", mode);
    }
    return tmod;
  }

  // get the system encoding mode

  Encoding::t_emod Encoding::getsem (void) {
    // get the system codeset
    t_codeset codeset = c_getcset ();
    // map the code set
    switch (codeset) {
    case LOC_ASC_00:
    case LOC_ISO_01:
    case LOC_ISO_02:
    case LOC_ISO_03:
    case LOC_ISO_04:
    case LOC_ISO_05:
    case LOC_ISO_06:
    case LOC_ISO_07:
    case LOC_ISO_08:
    case LOC_ISO_09:
    case LOC_ISO_10:
    case LOC_ISO_11:
    case LOC_ISO_13:
    case LOC_ISO_14:
    case LOC_ISO_15:
    case LOC_ISO_16:
      return BYTE;
      break;
    case LOC_UTF_08:
      return UTF8;
      break;
    default:
      break;
    }
    return BYTE;
  }

  // get the system transcoding mode

  Encoding::t_tmod Encoding::getstm (void) {
    // get the system codeset
    t_codeset codeset = c_getcset ();
    // map the code set
    switch (codeset) {
    case LOC_ASC_00:
      return DEFAULT;
      break;
    case LOC_ISO_01:
      return I8859_01;
      break;
    case LOC_ISO_02:
      return I8859_02;
      break;
    case LOC_ISO_03:
      return I8859_03;
      break;
    case LOC_ISO_04:
      return I8859_04;
      break;
    case LOC_ISO_05:
      return I8859_05;
      break;
    case LOC_ISO_06:
      return I8859_06;
      break;
    case LOC_ISO_07:
      return I8859_07;
      break;
    case LOC_ISO_08:
      return I8859_08;
      break;
    case LOC_ISO_09:
      return I8859_09;
      break;
    case LOC_ISO_10:
      return I8859_10;
      break;
    case LOC_ISO_11:
      return I8859_11;
      break;
    case LOC_ISO_13:
      return I8859_13;
      break;
    case LOC_ISO_14:
      return I8859_14;
      break;
    case LOC_ISO_15:
      return I8859_15;
      break;
    case LOC_ISO_16:
      return I8859_16;
      break;
    default:
      return DEFAULT;
      break;
    }
    return DEFAULT;
  }

  // get the natural encoding mode

  String Encoding::getdem (void) {
    return DEF_MODE_DEF;
  }
  
  // get the natural encoding mode
  
  String Encoding::getnem (void) {
    return DEF_MODE_UTF;
  }
}
