
//==================================================================================
//==================================================================================
// 
// SHOP-MODUL HAUPTPROGRAMM
// OO-PROGRAMMIERUNG
// AUTOR: DF
// ERSTELLT: 24.01.2005
//
//==================================================================================
//==================================================================================


// ============================================================
// Globale Deklarationen
// ============================================================

// den undefinierten Wert deklarieren
var undefined;


/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// ============================================================
// Klasse ORDER
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// Order()
// ---------------------------------------
//
// Beschreibung:
// -------------
// Konstruiert ein Order Objekt.
//
// Beispiel:
// ---------
// 

function Order() {  
  // Attribute
  this._date = {};
  this._language = undefined;
  this._expanded = undefined;  
  this._totalPrice = undefined;
  this._customer = {}; 
  this._shippingAdress = {}; 
  this._orderedItemList = []; 
  
  // Initialisierungen
  this.date();
  this.language();
  this.totalPrice();
  this.customer();
  this.shippingAdress(); 
  this.orderedItemList(); 
  this.expanded();
  
  //Default setzen
  this._setDate();
  this.setLanguage('de');
  this.setExpanded('no');
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// date(obj)
// -----------
//
// Beschreibung:
// -------------
//

Order.prototype.date = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Date) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassDate!");
    }
    this._date = obj;
  }
  return this._date;
}

// -----------
// language(string)
// -----------
//
// Beschreibung:
// -------------
//

Order.prototype.language = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._language = str;
  }
  return this._language;
}

// -----------
// totalPrice(n)
// -----------
//
// Beschreibung:
// -------------
//

Order.prototype.totalPrice = function(n) {
  if (arguments.length) {
    if (!ShopUtils.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:notANumber");
    }
    n = ShopUtils.checkNumber(n);
    this._totalPrice = n;
  }
  return this._totalPrice;
}

// --------------
// orderedItemList(arr)
// --------------
//
// Beschreibung:
// -------------
//

Order.prototype.orderedItemList = function(arr) {
  if (arguments.length) {
    if (! arr instanceof Array) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassArray!");
    }
    this._orderedItemList = arr;
  }
  return this._orderedItemList;
}

// -----------
// expanded(str)
// -----------
//
// Beschreibung:
// -------------
//

Order.prototype.expanded = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._expanded = str;
  }
  return this._expanded;
}

// -----------
// customer(obj)
// -----------
//
// Beschreibung:
// -------------
//

Order.prototype.customer = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Customer) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassCustomer!");
    }
    this._customer = obj;
  }
  return this._customer;
}

// -----------
// shippingAdress(obj)
// -----------
//
// Beschreibung:
// -------------
//

Order.prototype.shippingAdress = function(obj) {
  if (arguments.length) {
    if (! obj instanceof ShippingAdress) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassShippingAdress!");
    }
    this._shippingAdress = obj;
  }
  return this._shippingAdress;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// _setDate()
// -------------------------------------------
//
// Beschreibung:
// -------------

// Beispiel:
// ---------
// _setDate();
//

Order.prototype._setDate = function() {
  this.date(new Date());
}


// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// setLanguage()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setLanguage();
//

Order.prototype.setLanguage = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.language(str);
  }
}

// -------------------------------------------
// setExpanded()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setExpanded();
//

Order.prototype.setExpanded = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.expanded(str);
  }
}

// -------------------------------------------
// setTotalPrice()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setTotalPrice();
//

Order.prototype.setTotalPrice = function(n) {
  if (arguments.length) {
    n = ShopUtils.stripSpace(n);
    if (!ShopUtils.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:notANumber");
    }
    n = ShopUtils.checkNumber(n);
    this.totalPrice(n);
  }
}

// -------------------------------------------
// setCustomer()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setCustomer();
//

Order.prototype.setCustomer = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Customer) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassCustomer!");
    }
    this.customer(obj);
  }
}

// -------------------------------------------
// setShippingAdress()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setCustomer();
//

Order.prototype.setShippingAdress = function(obj) {
  if (arguments.length) {
    if (! obj instanceof ShippingAdress) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassShippingAdress!");
    }
    this.shippingAdress(obj);
  }
}

// -------------------------------------------
// addOrderedItemList()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.addOrderedItemList();
//

Order.prototype.addOrderedItemList = function(idItem, quant) {
  if (!ShopUtils.checkNumber(quant)) {
    return alert('Bitte überprüfen Sie Ihre Eingabe!');
  }
  quant = ShopUtils.checkNumber(quant);
  idItem = ShopUtils.stripSpace(idItem).toString();
  if (idItem.length){
    var item = Item.GetInstance(idItem);
    var orderedItem = OrderedItem.CreateInstance(idItem);
    orderedItem.setQuantity(quant);
    orderedItem.setItem(item);
    for (var i=0; i<this.orderedItemList().length; i++){
      if (this.orderedItemList()[i].item().id() == idItem){
        if (quant <= 0){
          this.orderedItemList(ShopUtils.deleteItemFromArray(this.orderedItemList(), i));
        }
        return;
      }
    }
    orderedItem.setPos(parseInt(this.orderedItemList().length+1));
    this.orderedItemList().push(orderedItem);
  }
}

// -------------------------------------------
// getTotalQuantity()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getTotalQuantity();
//

Order.prototype.getTotalQuantity = function() {
  var result = 0;
  for (var i=0; i<this.orderedItemList().length; i++){
    result += parseInt(this.orderedItemList()[i].quantity());
  }
  return result;
}

// -------------------------------------------
// getTotalPrice()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getTotalPrice();
//

Order.prototype.getTotalPrice = function() {
  var result = 0;
  for (var i=0; i<this.orderedItemList().length; i++){
    result += parseFloat(this.orderedItemList()[i].quantity() * this.orderedItemList()[i].item().price());
  }
  return ShopUtils.formatCashFloat(result);
}

// -------------------------------------------
// getTaxFromTotalPriceTaxInclusive(rate)
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getTaxFromTotalPriceTaxInclusive(rate);
//

Order.prototype.getTaxFromTotalPriceTaxInclusive = function(rate) {
  var taxRate = rate;
  if (taxRate == undefined){
    taxRate = Order.TaxRate;
  }
  var result = 0;
  for (var i=0; i<this.orderedItemList().length; i++){
    result += parseFloat(this.orderedItemList()[i].quantity() * this.orderedItemList()[i].item().price());
  }
  var diff = parseFloat(100 + taxRate);
  return ShopUtils.formatCashFloat(parseFloat((result/diff)*taxRate));
}

// -------------------------------------------
// getTaxFromTotalPriceTaxNotInclusive(rate)
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getTaxFromTotalPriceTaxNotInclusive(rate);
//

Order.prototype.getTaxFromTotalPriceTaxNotInclusive = function(rate) {
  var taxRate = rate;
  if (taxRate == undefined){
    taxRate = Order.TaxRate;
  }
  var result = 0;
  for (var i=0; i<this.orderedItemList().length; i++){
    result += parseFloat(this.orderedItemList()[i].quantity() * this.orderedItemList()[i].item().price());
  }
  return ShopUtils.formatCashFloat(parseFloat((result/100)*taxRate));
}

// -------------------------------------------
// getText()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getText();
//

Order.prototype.getText = function() {
  return this.getOrderTEXT();
}

// -----------
// getHTML()
// -----------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getHTML();
//

Order.prototype.getHTML = function() {
  return this.getOrderHTML();
}

// -----------
// getXML()
// -----------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getXML();
//

Order.prototype.getXML = function() {
  return this.getOrderXML();
}

// -------------------------------------------
// resetOrderedItems()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.resetOrderedItems();
//

Order.prototype.resetOrderedItems = function() {
  var arr = [];
  this.orderedItemList(arr);
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

Order.Instance = {};
Order.ID = [];
Order.TaxRate = 16;

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Order._CreateIndex()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt eindeutige ID;
//
// Beispiel:
// ---------
// Order._CreateIndex();
//

Order._CreateIndex = function(id) {
  var index = id;
  if (index == undefined){
    Order.ID.push('');
    index = Order.ID.length;
  }  
  index = index.toString();
  return index;
}

// -------------------------------------------
// Order._SetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt Order-Objekt und registriert Objekt in Array Order.Instance;
//
// Beispiel:
// ---------
// Order._SetInstance();
//

Order._SetInstance = function(id) {
  if (Order.Instance[id] == undefined){
    Order.Instance[id] = new Order();
  }  
}

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Order.GetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Order.getInstance();
//

Order.GetInstance = function(id) {
  if (id == undefined){
    var index = Order.ID.length;
    index = index.toString();
    return Order.Instance[index];
  } else {
    if (Order.Instance[id] == undefined){
      focus();
      throw new Error("System-Error:NoObject-InstanceWithID='" + id +"'");
    } else {
      return Order.Instance[id];
    }
  }
}


// -------------------------------------------
// Order.CreateInstance(id)
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Order.CreateInstance(id);
//

Order.CreateInstance = function(id) {  
  // defaultArguments
  var index = Order._CreateIndex(id);
  Order._SetInstance(index);
  return Order.GetInstance(index);
}

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

Order.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  //return Object.prototype.toString.apply(this);
  var str = new String('');
  str += 'Order:\n'
  str += 'language = ' + this.language() +'\n';
  str += 'date = ' + this.date() +'\n';
  str += 'totalPrice = ' + this.totalPrice() +'\n';
  str += 'orderedItemList: ' + this.orderedItemList().length +' Items\n';
  for (var i=0; i<this.orderedItemList().length; i++){
    str += 'item-'+ i +' = ' + this.orderedItemList()[i].toString() +'\n';
  }
  str += '\n';
  str += 'customer: ' + this.customer().toString() +'\n';
  str += 'shippingAdress: ' + this.shippingAdress().toString() +'\n';
  return str;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ENDE ORDER
/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// ============================================================
// Klasse CUSTOMER
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// Customer()
// ---------------------------------------
//
// Beschreibung:
// -------------
// Konstruiert ein Customer Objekt.
//
// Beispiel:
// ---------
// 

function Customer() {  
  // Attribute
  this._language = undefined;
  this._name = undefined;  
  this._firstName = undefined;  
  this._street = undefined;   
  this._postCode = undefined;  
  this._city = undefined;  
  this._country = undefined; 
  this._telephone = undefined; 
  this._telefax = undefined; 
  this._email = undefined; 
  
  // Initialisierungen
  this.language();
  this.name();
  this.firstName();
  this.street();
  this.postCode();
  this.city();
  this.country();
  this.telephone();
  this.telefax();
  this.email();
  
  //Default setzen
  this.setLanguage('de');
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// language(string)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.language = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._language = str;
  }
  return this._language;
}

// -----------
// name(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.name = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._name = str;
  }
  return this._name;
}

// -----------
// firstName(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.firstName = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._firstName = str;
  }
  return this._firstName;
}

// -----------
// street(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.street = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._street = str;
  }
  return this._street;
}

// -----------
// postCode(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.postCode = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._postCode = str;
  }
  return this._postCode;
}

// -----------
// city(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.city = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._city = str;
  }
  return this._city;
}

// -----------
// country(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.country = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._country = str;
  }
  return this._country;
}

// -----------
// telephone(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.telephone = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._telephone = str;
  }
  return this._telephone;
}

// -----------
// telefax(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.telefax = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._telefax = str;
  }
  return this._telefax;
}

// -----------
// email(str)
// -----------
//
// Beschreibung:
// -------------
//

Customer.prototype.email = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._email = str;
  }
  return this._email;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// setLanguage()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setLanguage();
//

Customer.prototype.setLanguage = function(str) { 
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.language(str);
  }
}

// -------------------------------------------
// setName()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setName();
//

Customer.prototype.setName = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.name(str);
  }
}

// -------------------------------------------
// setFirstName()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setFirstName();
//

Customer.prototype.setFirstName = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.firstName(str);
  }
}

// -------------------------------------------
// setStreet()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setStreet();
//

Customer.prototype.setStreet = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.street(str);
  }
}

// -------------------------------------------
// setPostCode()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setPostCode();
//

Customer.prototype.setPostCode = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.postCode(str);
  }
}

// -------------------------------------------
// setCity()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setCity();
//

Customer.prototype.setCity = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.city(str);
  }
}

// -------------------------------------------
// setCountry()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setCountry();
//

Customer.prototype.setCountry = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.country(str);
  }
}

// -------------------------------------------
// setTelephone()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setTelephone();
//

Customer.prototype.setTelephone = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.telephone(str);
  }
}

// -------------------------------------------
// setTelefax()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setTelefax();
//

Customer.prototype.setTelefax = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.telefax(str);
  }
}

// -------------------------------------------
// setEmail()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setEmail();
//

Customer.prototype.setEmail = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.email(str);
  }
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

Customer.Instance = [];
Customer.ID = [];

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Customer._CreateIndex()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt eindeutige ID;
//
// Beispiel:
// ---------
// Customer._CreateIndex();
//

Customer._CreateIndex = function() {
  Customer.ID.push('');
  index = Customer.ID.length;
  return index;
}

// -------------------------------------------
// Customer._SetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt Customer-Objekt und registriert Objekt in Array Customer.Instance;
//
// Beispiel:
// ---------
// Customer._SetInstance();
//

Customer._SetInstance = function(id) {
  if (Customer.Instance[id] == undefined){
    Customer.Instance[id] = new Customer();
  }  
}

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Customer.GetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Customer.getInstance();
//

Customer.GetInstance = function() {
  return Customer.Instance[Customer.Instance.length-1];
}


// -------------------------------------------
// Customer.CreateInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Customer.CreateInstance();
//

Customer.CreateInstance = function() {  
  // defaultArguments
  var index = Customer._CreateIndex();
  Customer._SetInstance(index);
  return Customer.GetInstance();
}

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

Customer.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  //return Object.prototype.toString.apply(this);
  var str = new String('');
  str += 'Customer:\n'
  str += 'language = ' + this.language() +'\n';
  str += 'name = ' + this.name() +'\n';
  str += 'firstName = ' + this.firstName() +'\n';
  str += 'street = ' + this.street() +'\n';
  str += 'postCode = ' + this.postCode() +'\n';
  str += 'city = ' + this.city() +'\n';
  str += 'country = ' + this.country() +'\n';
  str += 'telephone = ' + this.telephone() +'\n';
  str += 'telefax = ' + this.telefax() +'\n';
  str += 'email = ' + this.email() +'\n';
  return str;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ENDE CUSTOMER
/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// ============================================================
// Klasse SHIPPINGADRESS
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// ShippingAdress()
// ---------------------------------------
//
// Beschreibung:
// -------------
// Konstruiert ein ShippingAdress Objekt.
//
// Beispiel:
// ---------
// 

function ShippingAdress() {  
  // Attribute
  this._language = undefined;
  this._name = undefined;  
  this._firstName = undefined;  
  this._street = undefined;   
  this._postCode = undefined;  
  this._city = undefined;  
  this._country = undefined; 
  this._telephone = undefined; 
  this._telefax = undefined; 
  this._email = undefined; 
  
  // Initialisierungen
  this.language();
  this.name();
  this.firstName();
  this.street();
  this.postCode();
  this.city();
  this.country();
  this.telephone();
  this.telefax();
  this.email();
  
  //Default setzen
  this.setLanguage('de');
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// language(string)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.language = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._language = str;
  }
  return this._language;
}

// -----------
// name(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.name = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._name = str;
  }
  return this._name;
}

// -----------
// firstName(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.firstName = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._firstName = str;
  }
  return this._firstName;
}

// -----------
// street(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.street = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._street = str;
  }
  return this._street;
}

// -----------
// postCode(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.postCode = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._postCode = str;
  }
  return this._postCode;
}

// -----------
// city(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.city = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._city = str;
  }
  return this._city;
}

// -----------
// country(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.country = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._country = str;
  }
  return this._country;
}

// -----------
// telephone(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.telephone = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._telephone = str;
  }
  return this._telephone;
}

// -----------
// telefax(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.telefax = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._telefax = str;
  }
  return this._telefax;
}

// -----------
// email(str)
// -----------
//
// Beschreibung:
// -------------
//

ShippingAdress.prototype.email = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._email = str;
  }
  return this._email;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// setLanguage()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setLanguage();
//

ShippingAdress.prototype.setLanguage = function(str) { 
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.language(str);
  }
}

// -------------------------------------------
// setName()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setName();
//

ShippingAdress.prototype.setName = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.name(str);
  }
}

// -------------------------------------------
// setFirstName()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setFirstName();
//

ShippingAdress.prototype.setFirstName = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.firstName(str);
  }
}

// -------------------------------------------
// setStreet()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setStreet();
//

ShippingAdress.prototype.setStreet = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.street(str);
  }
}

// -------------------------------------------
// setPostCode()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setPostCode();
//

ShippingAdress.prototype.setPostCode = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.postCode(str);
  }
}

// -------------------------------------------
// setCity()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setCity();
//

ShippingAdress.prototype.setCity = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.city(str);
  }
}

// -------------------------------------------
// setCountry()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setCountry();
//

ShippingAdress.prototype.setCountry = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.country(str);
  }
}

// -------------------------------------------
// setTelephone()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setTelephone();
//

ShippingAdress.prototype.setTelephone = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.telephone(str);
  }
}

// -------------------------------------------
// setTelefax()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setTelefax();
//

ShippingAdress.prototype.setTelefax = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.telefax(str);
  }
}

// -------------------------------------------
// setEmail()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setEmail();
//

ShippingAdress.prototype.setEmail = function(str) { 
  if (arguments.length) {
    str = ShopUtils.stripSpace(str);
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.email(str);
  }
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

ShippingAdress.Instance = [];
ShippingAdress.ID = [];

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// ShippingAdress._CreateIndex()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt eindeutige ID;
//
// Beispiel:
// ---------
// ShippingAdress._CreateIndex();
//

ShippingAdress._CreateIndex = function() {
  ShippingAdress.ID.push('');
  index = ShippingAdress.ID.length;
  return index;
}

// -------------------------------------------
// ShippingAdress._SetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt ShippingAdress-Objekt und registriert Objekt in Array ShippingAdress.Instance;
//
// Beispiel:
// ---------
// ShippingAdress._SetInstance();
//

ShippingAdress._SetInstance = function(id) {
  if (ShippingAdress.Instance[id] == undefined){
    ShippingAdress.Instance[id] = new ShippingAdress();
  }  
}

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// ShippingAdress.GetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// ShippingAdress.getInstance();
//

ShippingAdress.GetInstance = function() {
  return ShippingAdress.Instance[ShippingAdress.Instance.length-1];
}


// -------------------------------------------
// ShippingAdress.CreateInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// ShippingAdress.CreateInstance();
//

ShippingAdress.CreateInstance = function() {  
  // defaultArguments
  var index = ShippingAdress._CreateIndex();
  ShippingAdress._SetInstance(index);
  return ShippingAdress.GetInstance();
}

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

ShippingAdress.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  //return Object.prototype.toString.apply(this);
  var str = new String('');
  str += 'ShippingAdress:\n'
  str += 'language = ' + this.language() +'\n';
  str += 'name = ' + this.name() +'\n';
  str += 'firstName = ' + this.firstName() +'\n';
  str += 'street = ' + this.street() +'\n';
  str += 'postCode = ' + this.postCode() +'\n';
  str += 'city = ' + this.city() +'\n';
  str += 'country = ' + this.country() +'\n';
  str += 'telephone = ' + this.telephone() +'\n';
  str += 'telefax = ' + this.telefax() +'\n';
  str += 'email = ' + this.email() +'\n';
  return str;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ENDE SHIPPINGADRESS
/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// ============================================================
// Klasse ORDEREDITEM
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// OrderedItem()
// ---------------------------------------
//
// Beschreibung:
// -------------
// Konstruiert ein OrderedItem Objekt.
//
// Beispiel:
// ---------
// 

function OrderedItem() {  
  // Attribute
  this._language = undefined;
  this._pos = undefined;  
  this._quantity = undefined;  
  this._item = {}; 
  
  // Initialisierungen
  this.language();
  this.pos();
  this.quantity();
  this.item();
  
  //Default setzen
  this.setLanguage('de');
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// language(string)
// -----------
//
// Beschreibung:
// -------------
//

OrderedItem.prototype.language = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._language = str;
  }
  return this._language;
}

// -----------
// pos(n)
// -----------
//
// Beschreibung:
// -------------
//

OrderedItem.prototype.pos = function(n) {
  if (arguments.length) {
    if (!ShopUtils.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:notANumber");
    }
    n = ShopUtils.checkNumber(n);
    this._pos = n;
  }
  return this._pos;
}

// -----------
// quantity(n)
// -----------
//
// Beschreibung:
// -------------
//

OrderedItem.prototype.quantity = function(n) {
  if (arguments.length) {
    if (!ShopUtils.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:notANumber");
    }
    n = ShopUtils.checkNumber(n);
    this._quantity = n;
  }
  return this._quantity;
}


// -----------
// item(n)
// -----------
//
// Beschreibung:
// -------------
//

OrderedItem.prototype.item = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Item) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassItem!");
    }
    this._item = obj;
  }
  return this._item;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// setLanguage()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setLanguage();
//

OrderedItem.prototype.setLanguage = function(str) { 
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this.language(str);
  }
}

// -------------------------------------------
// setPos()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setPos();
//

OrderedItem.prototype.setPos = function(n) {
  if (arguments.length) {
    if (!ShopUtils.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:notANumber");
    }
    n = ShopUtils.checkNumber(n);
    this.pos(n);
  }
}

// -------------------------------------------
// setQuantity()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setQuantity();
//

OrderedItem.prototype.setQuantity = function(n) {
  if (arguments.length) {
    if (!ShopUtils.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:notANumber");
    }
    n = ShopUtils.checkNumber(n);
    this.quantity(n);
  }
}

// -------------------------------------------
// setItem()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.setItem();
//

OrderedItem.prototype.setItem = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Item) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassItem!");
    }
    this.item(obj);
  }
}

// -------------------------------------------
// getTotalPrice()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getTotalPrice();
//

OrderedItem.prototype.getTotalPrice = function(obj) {
  var result = 0;
  result += parseFloat(this.item().price() * this.quantity());
  return ShopUtils.formatCashFloat(result);
}

// -------------------------------------------
// getTaxFromTotalPriceTaxInclusive(rate)
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getTaxFromTotalPriceTaxInclusive(rate);
//

OrderedItem.prototype.getTaxFromTotalPriceTaxInclusive = function(rate) {
  var taxRate = rate;
  if (taxRate == undefined){
    taxRate = Order.TaxRate;
  }
  var result = 0;
  result += parseFloat(this.item().price() * this.quantity());
  var diff = parseFloat(100 + taxRate);
  return ShopUtils.formatCashFloat(parseFloat((result/diff)*taxRate));
}

// -------------------------------------------
// getTaxFromTotalPriceTaxNotInclusive(rate)
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// this.getTaxFromTotalPriceTaxNotInclusive(rate);
//

OrderedItem.prototype.getTaxFromTotalPriceTaxNotInclusive = function(rate) {
  var taxRate = rate;
  if (taxRate == undefined){
    taxRate = Order.TaxRate;
  }
  result += parseFloat(this.item().price() * this.quantity());
  var diff = parseFloat(100 + taxRate);
  return ShopUtils.formatCashFloat(parseFloat((result/100)*taxRate));
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

OrderedItem.Instance = [];
OrderedItem.ID = [];

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// OrderedItem._CreateIndex()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt eindeutige ID;
//
// Beispiel:
// ---------
// OrderedItem._CreateIndex(id);
//

OrderedItem._CreateIndex = function(id) {
  var index = id;
  if (index == undefined){
    OrderedItem.ID.push('');
    index = OrderedItem.ID.length;
  }  
  index = index.toString();
  return index;
}

// -------------------------------------------
// OrderedItem._SetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt OrderedItem-Objekt und registriert Objekt in Array OrderedItem.Instance;
//
// Beispiel:
// ---------
// OrderedItem._SetInstance();
//

OrderedItem._SetInstance = function(id) {
  if (OrderedItem.Instance[id] == undefined){
    OrderedItem.Instance[id] = new OrderedItem();
  }  
}

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// OrderedItem.GetInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// OrderedItem.getInstance();
//

OrderedItem.GetInstance = function(id) {
  if (id == undefined){
    var index = OrderedItem.ID.length;
    index = index.toString();
    return OrderedItem.Instance[index];
  } else {
    if (OrderedItem.Instance[id] == undefined){
      focus();
      throw new Error("System-Error:NoObject-InstanceWithID='" + id +"'");
    } else {
      return OrderedItem.Instance[id];
    }
  }
}


// -------------------------------------------
// OrderedItem.CreateInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// OrderedItem.CreateInstance();
//

OrderedItem.CreateInstance = function(id) {  
  // defaultArguments
  var index = OrderedItem._CreateIndex(id);
  OrderedItem._SetInstance(index);
  return OrderedItem.GetInstance(index);
}

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

OrderedItem.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  //return Object.prototype.toString.apply(this);
  var str = new String('');
  str += 'OrderedItem:\n'
  str += 'language = ' + this.language() +'\n';
  str += 'pos = ' + this.pos() +'\n';
  str += 'quantity = ' + this.quantity() +'\n';
  str += 'item = ' + this.item().toString() +'\n';
  return str;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ENDE ORDEREDITEM
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

