
//==================================================================================
//==================================================================================
// 
// KALENDER-MODUL HAUPTPROGRAMM
// OO-PROGRAMMIERUNG
// AUTOR: DF
// ERSTELLT: 15.12.2004
//
//==================================================================================
//==================================================================================


// ============================================================
// Globale Deklarationen
// ============================================================

// den undefinierten Wert deklarieren
var undefined;


/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// ============================================================
// Klasse Calendar
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// Calendar(bundesland, sprache)
// ---------------------------------------
//
// Beschreibung:
// -------------
// Konstruiert ein Calendar Objekt.
//
// Beispiel:
// ---------
// 

function Calendar(id) {  
  // Attribute
  this._id = undefined;
  this._bundesland = undefined;
  this._sprache = undefined;  
  this._listEintrag = [];  
  this._listTag = []; 
  this._calendarTyp = undefined; 
  this._viewType = undefined;
  this._date = undefined; 
  this._intervall = 1; 
  // Initialisierungen
  this.id(this._setID(id));
  this.bundesland();
  this.sprache('de');
  this.listEintrag();
  this.listTag(); 
  this.calendarTyp(); 
  this.viewType(); 
  this.date();
  this.intervall();
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// id(string)
// -----------
//
// Beschreibung:
// -------------
//

Calendar.prototype.id = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._id = str;
  }
  return this._id;
}

// -----------
// sprache(string)
// -----------
//
// Beschreibung:
// -------------
//

Calendar.prototype.sprache = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._sprache = str;
  }
  return this._sprache;
}

// -----------
// bundesland(number)
// -----------
//
// Beschreibung:
// -------------
//

Calendar.prototype.bundesland = function(n) {
  if (arguments.length) {
    if (!Calendartools.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:noNumber!");
    }
    this._bundesland = n;
  }
  return this._bundesland;
}

// --------------
// listEintrag(obj)
// --------------
//
// Beschreibung:
// -------------
//

Calendar.prototype.listEintrag = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Eintrag) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassEintrag!");
    }
    this._listEintrag.push(obj);
  }
  return this._listEintrag;
}

// --------------
// listTag(arr)
// --------------
//
// Beschreibung:
// -------------
//

Calendar.prototype.listTag = function(arr) {
  if (arguments.length) {
    if (! arr instanceof Array) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassArray!");
    }
    this._listTag = arr;
  }
  return this._listTag;
}

// -----------
// calendarTyp(string)
// -----------
//
// Beschreibung:
// -------------
//

Calendar.prototype.calendarTyp = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._calendarTyp = str;
  }
  return this._calendarTyp;
}

// -----------
// viewType(string)
// -----------
//
// Beschreibung:
// -------------
//

Calendar.prototype.viewType = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._viewType = str;
  }
  return this._viewType;
}

// --------------
// date(obj)
// --------------
//
// Beschreibung:
// -------------
//

Calendar.prototype.date = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Date) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassDate!");
    }
    this._date = obj;
  }
  return this._date;
}

// -----------
// intervall(n)
// -----------
//
// Beschreibung:
// -------------
//

Calendar.prototype.intervall = function(n) {
  if (arguments.length) {
    if (!Calendartools.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:noNumber!");
    }
    this._intervall = n;
  }
  return this._intervall;
}


// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Calendar.setBundesland()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.setBundesland();
//

Calendar.prototype.setBundesland = function(n) { 
  this.bundesland(n);
}

// -------------------------------------------
// Calendar.setCalendarTyp()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.setCalendarTyp();
//

Calendar.prototype.setCalendarTyp = function(str) { 
  this.calendarTyp(str);
}

// -----------
// setViewType(string)
// -----------
//
// Beschreibung:
// -------------
//

Calendar.prototype.setViewType = function(str) {
  this.viewType(str);
}

// -------------------------------------------
// Calendar.setDate()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.setDate();
//

Calendar.prototype.setDate = function(obj) { 
  this.date(DateProperties.checkDate(obj));
}

// -------------------------------------------
// Calendar.setIntervall()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.setIntervall();
//

Calendar.prototype.setIntervall = function(n) { 
  var _int = parseFloat(n - 1);
  this.intervall(_int);
}

// -------------------------------------------
// Calendar.setDate()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.setDate();
//

Calendar.prototype.getHTML = function() { 
  if (this.calendarTyp() == undefined || (this.calendarTyp()!='year' && this.calendarTyp()!='day' && this.calendarTyp()!='monthDetail')){
    //Standard-Typ month;
    this._setListTag(DateProperties.getMonatAnfangVonDatum(this.date()), DateProperties.getMonatEndeVonDatum(this.date()));
    return this._drawMonthPeriod();
  }
  if (this.calendarTyp()=='day'){
    //Standard-Typ month;
    if (this.intervall() > 1){
      var intervallEnd = new Date(new Date().setTime(this.date().getTime() + (this.intervall() * (24*60*60*1000))));
      this._setListTag(this.date(), intervallEnd);
      return this._drawDayIntervallPeriod();
    } else {
      this._setListTag(this.date(), this.date());
      return this._drawDayPeriod();
    }
  }
  if (this.calendarTyp()=='year'){
    this._setListTag(new Date(this.date().getFullYear(),0,1,5,0,0), new Date(this.date().getFullYear(),11,31,5,0,0));
    return this._drawYearPeriod();
  }
  if (this.calendarTyp()=='monthDetail'){
    this._setListTag(DateProperties.getMonatAnfangVonDatum(this.date()), DateProperties.getMonatEndeVonDatum(this.date()));
    return this._drawMonthDetail();
  }
}

// -------------------------------------------
// setEintragList()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Objekt Eintrag wird übergebgen dann in _listEintrag gespeichert
//
// Beispiel:
// ---------
// setEintragList(createEintrag(...));
//

Calendar.prototype.setEintragList = function(obj) {  
  this.listEintrag(obj);
}

// -------------------------------------------
// Calendar.forward()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.forward();
//

Calendar.prototype.forward = function() {
  if (this.calendarTyp() == undefined || (this.calendarTyp()!='year' && this.calendarTyp()!='day')){
    //Standard-Typ month;
    this.setDate(new Date(new Date().setTime(DateProperties.getMonatEndeVonDatum(this.date()).getTime() + (24*60*60*1000))));
  }
  if (this.calendarTyp()=='day'){
    this.setDate(new Date(new Date().setTime(this.date().getTime() + (this.intervall() * (24*60*60*1000)))));
  }
  return CalendarUtil.replaceDocumentNode(this.id(), this.getHTML());
}

// -------------------------------------------
// Calendar.backward()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.backward();
//

Calendar.prototype.backward = function() {
  if (this.calendarTyp() == undefined || (this.calendarTyp()!='year' && this.calendarTyp()!='day')){
    //Standard-Typ month;
  this.setDate(new Date(new Date().setTime(DateProperties.getMonatAnfangVonDatum(this.date()).getTime() - (24*60*60*1000))));
  }
  if (this.calendarTyp()=='day'){
    this.setDate(new Date(new Date().setTime(this.date().getTime() - (this.intervall() * (24*60*60*1000)))));
  }
  return CalendarUtil.replaceDocumentNode(this.id(), this.getHTML()); 
}

// -------------------------------------------
// Calendar.navigationMonth()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.navigationMonth(month);
//

Calendar.prototype.navigationMonth = function(month) {
  this.setDate(new Date(this.date().getFullYear(),month,1,Calendar._setSystemHours(),0,0));
  return CalendarUtil.replaceDocumentNode(this.id(), this.getHTML()); 
}

// -------------------------------------------
// Calendar.navigationYear()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.navigationYear(year);
//

Calendar.prototype.navigationYear = function(year) {
  this.setDate(new Date(year,this.date().getMonth(),1,Calendar._setSystemHours(),0,0));
  return CalendarUtil.replaceDocumentNode(this.id(), this.getHTML()); 
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// -------------------------------------------
// _setID(id)
// -------------------------------------------
//
// Beschreibung:
// -------------

// Beispiel:
// ---------
// _setID(id);
//

Calendar.prototype._setID = function(id) {
  if (!id){
    return 'Calendar' + 1;
  } else {
    return id;
  }  
}

// -------------------------------------------
// _setListTag()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Methode erstellt Liste Tag. 
// Methode prüft ob Tag schon erstell andernfalls wird neues Objekt erzeugt
//
// Beispiel:
// ---------
// _setListTag(datumObj1, datumObj2);
//

Calendar.prototype._setListTag = function(datumObj1, datumObj2) {
  var tempTime = datumObj1;
  tempTime.setHours(Calendar._setSystemHours());
  tempTime.setMinutes(0);
  tempTime.setSeconds(0);
  var tempTime2 = datumObj2;
  tempTime2.setHours(Calendar._setSystemHours());
  tempTime2.setMinutes(0);
  tempTime2.setSeconds(0); 
  var arr = [];
  while (tempTime.getTime() <= tempTime2.getTime()){ 
    arr[arr.length] = Tag.createTag({'datum':new Date(tempTime)}, {'sprache':this.sprache()});
    tempTime = new Date(new Date().setTime(tempTime.getTime() + (24 * 60 * 60 * 1000)));
    tempTime.setHours(Calendar._setSystemHours());
    tempTime.setMinutes(0);
    tempTime.setSeconds(0);
  }
  this.listTag(arr);
}

// -------------------------------------------
// _createTempEintrag()
// -------------------------------------------
//
// Beschreibung:
// -------------
// Vorauswahl der Einträge für bestimmten Monat/e.
//
// Beispiel:
// ---------
// _createTempEintrag();
//

Calendar.prototype._createTempEintrag = function(zeitraum) {
  var jahrVon = this.listTag()[0].datum().getFullYear();
  var jahrBis = this.listTag()[this.listTag().length-1].datum().getFullYear();
  var monatVon = parseFloat(jahrVon + this.listTag()[0].datum().getMonth());
  var monatBis = parseFloat(jahrBis + this.listTag()[this.listTag().length-1].datum().getMonth());
  
  var arr = [];
  
  for (var i=0; i<this.listEintrag().length; i++){    
    if (zeitraum == 'jahr'){
      if (this.listEintrag()[i].datum2().getFullYear() >= jahrVon && this.listEintrag()[i].datum1().getFullYear() <= jahrBis){
        arr.push(this.listEintrag()[i]);
      }
    }
    // Monat
    else{
      if (parseFloat(this.listEintrag()[i].datum2().getFullYear() + this.listEintrag()[i].datum2().getMonth()) >= monatVon && parseFloat(this.listEintrag()[i].datum2().getFullYear() + this.listEintrag()[i].datum1().getMonth()) <= monatBis){
        arr.push(this.listEintrag()[i]);
      }
    }
  }   
  return arr;  
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

Calendar.instance = undefined;
Calendar.registeredInstance = [];

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Calendar._setSystemHours()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar._setSystemHours()
//

Calendar._setSystemHours = function() {
  return 5;
}

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Calendar.createMontagAktuelleWoche()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.createMontagAktuelleWoche();
//

Calendar.createMontagAktuelleWoche = function(date) {
  var datum = undefined;
  if (date){
    datum = date;
  } else {
    datum = new Date();
  }  
  if (datum.getDay() > 1){
    datum = new Date(datum.setTime(datum.getTime() - ((datum.getDay()-1) *24*60*60*1000)));
  }
  if (datum.getDay() < 1){
    datum = new Date(datum.setTime(datum.getTime() - (6 *24*60*60*1000)));
  }
  datum.setHours(Calendar._setSystemHours());
  datum.setMinutes(0);
  datum.setSeconds(0);
  return datum;
}

// -------------------------------------------
// Calendar.createSystemDate()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.createSystemDate();
//

Calendar.createSystemDate = function() {
  return new Date(DateProperties.createDatefromTime(new String(Calendar._setSystemHours() + '0000')));
}

// -------------------------------------------
// Calendar.setInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.setInstance();
//

Calendar.setInstance = function(obj) { 
  if (arguments.length) {
    if (! obj instanceof Eintrag) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassEintrag!");
    }
    Calendar.instance = obj;
  }
  Calendar.instance;
}

// -------------------------------------------
// Calendar.registerInstance(id)
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.registerInstance(id);
//

Calendar.registerInstance = function(id) { 
  if (arguments.length) {
    if (typeof id != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    if (!Calendar.registeredInstance[id]){
      Calendar.registeredInstance[id] = new Calendar(id);
    }  
  }
}

// -------------------------------------------
// Calendar.getInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.getInstance();
//

Calendar.getInstance = function(id) { 
  if (!id){
    return Calendar.instance;
  } else {
    if (Calendar.registeredInstance[id]){
      return Calendar.registeredInstance[id];
    } else {
      focus();
      throw new Error("No Calender with ID = "+ id +"!");
    }
  }
}


// -------------------------------------------
// Calendar.createInstance()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Calendar.createInstance();
//

Calendar.createInstance = function(id) {  
  // defaultArguments
  if (!id){
    Calendar.setInstance(new Calendar());
  } else {
    Calendar.registerInstance(id);
  }
  return Calendar.getInstance(id);
}

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

Calendar.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  //return Object.prototype.toString.apply(this);
  var str = new String('');
  str += '<b>Calendar</b><br>'
  str += 'bundesland = ' + Calendartools.gibBundesland(this.bundesland()) +'<br>\n';
  str += 'sprache = ' + this.sprache() +'<br><br>\n';
  str += 'Datum = ' + this.date() +'<br>\n';
  str += 'Typ = ' + this.calendarTyp() +'<br><br>\n';
  
  str += 'Anzahl Tage = ' + this.listTag().length +'<br>\n\n';
  str += 'listTag =\n\n<br><br>' + this.listTag() +'<br>\n\n';
  
  str += 'Anzahl Einträge = ' + this.listEintrag().length +'<br>\n\n';
  str += 'listEintrag =\n\n<br><br>' + this.listEintrag() +'<br>\n\n';
  return str;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// ============================================================
// Klasse Eintrag
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// Eintrag(datum1, datum2, titel, untertitel, uhrzeit1, uhrzeit2)
// ---------------------------------------
//
// Beschreibung:
// -------------
// Konstruiert ein EintragObjekt mit optionalen Eigenschaften
//
// Beispiel:
// ---------
// 

function Eintrag(datum1, datum2, titel, untertitel, uhrzeit1, uhrzeit2, detailURL) {  
  // Attribute
  this._id = undefined;
  this._datum1 = undefined;
  this._datum2 = undefined; 
  this._titel = undefined;  
  this._untertitel = undefined; 
  this._uhrzeit1 = undefined;  
  this._uhrzeit2 = undefined; 
  this._detailURL = undefined;
  this._style = undefined;
  // Initialisierungen
  this.id(Eintrag._createID());
  this.datum1(datum1);
  this.datum2(datum2);
  this.titel(titel);
  this.untertitel(untertitel);
  this.uhrzeit1(uhrzeit1);
  this.uhrzeit2(uhrzeit2);
  this.detailURL(detailURL);
  this.style();
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// id(number)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.id = function(n) {
  if (arguments.length) {
    if (!Calendartools.checkNumber(n)) {
      focus();
      throw new Error("ArgumentError:noNumber!");
    }
    this._id = n;
  }
  return this._id;
}

// -----------
// datum1(obj)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.datum1 = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Date) {
      focus();
      throw new Error("ArgumentError:notObjectOfClassDate!");
    }
    this._datum1 = obj;
  }
  return this._datum1;
}

// -----------
// datum2(obj)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.datum2 = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Date) {
      focus();
      throw new Error("ArgumentError:notObjectOfClassDate!");
    }
    this._datum2 = obj;
  }
  return this._datum2;
}

// -----------
// titel(str)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.titel = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._titel = str;
  }
  return this._titel;
}

// -----------
// untertitel(str)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.untertitel = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._untertitel = str;
  }
  return this._untertitel;
}

// -----------
// uhrzeit1(obj)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.uhrzeit1 = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Date) {
      focus();
      throw new Error("ArgumentError:notObjectOfClassDate!");
    }
    this._uhrzeit1 = obj;
  }
  return this._uhrzeit1;
}

// -----------
// uhrzeit2(number)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.uhrzeit2 = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Date) {
      focus();
      throw new Error("ArgumentError:notObjectOfClassDate!");
    }
    this._uhrzeit2 = obj;
  }
  return this._uhrzeit2;
}

// -----------
// detailURL(str)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.detailURL = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._detailURL = str;
  }
  return this._detailURL;
}

// -----------
// style(obj)
// -----------
//
// Beschreibung:
// -------------
//

Eintrag.prototype.style = function(obj) {
  if (arguments.length) {
    if (! obj instanceof EintragStyle) {
      focus();
      throw new Error("ArgumentError:notObjectOfClassEintragStyle!");
    }
    this._style = obj;
  }
  return this._style;
}


// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

Eintrag.listeID = [];

// -------------------------------------------
// Eintrag._createID()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Eintrag._createID();
//

Eintrag._createID = function() { 
  var id = Eintrag.listeID.length; 
  Eintrag.listeID[id] = id;
  return Eintrag.listeID[id];  
}

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Eintrag.createEintrag()
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Eintrag.createEintrag({'datum1':new Date()},{'datum2':new Date()},{'titel':'str'},{'untertitel':'str'},{'uhrzeit1':new Date()},{'uhrzeit2':new Date()});
//

Eintrag.createEintrag = function() {  
  // defaultArguments
  var defArg = {};
  defArg['datum1'] = new Date();
  defArg['datum2'] = new Date();
  defArg['titel'] = '';
  defArg['untertitel'] = '';
  defArg['uhrzeit1'] = 0;
  defArg['uhrzeit2'] = 0;
  defArg['detailURL'] = '';
  // givenArguments
  defArg = Calendartools.getArgumentsAssArray(defArg, arguments);
  return new Eintrag(defArg['datum1'], defArg['datum2'], defArg['titel'], defArg['untertitel'], defArg['uhrzeit1'], defArg['uhrzeit2'], defArg['detailURL']);
}

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

Eintrag.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  //return Object.prototype.toString.apply(this);
  var str = new String('');
  str += '<b>Eintrag</b><br>'
  str += '\tid = ' + this.id() +'<br>\n';
  str += '\tdatum1 = ' + this.datum1() +'<br>\n';
  str += '\tdatum2 = ' + this.datum2() +'<br>\n';
  str += '\ttitel = ' + this.titel() +'<br>\n';
  str += '\tuntertitel = ' + this.untertitel() +'<br>\n';
  str += '\tuhrzeit1 = ' + this.uhrzeit1() +'<br>\n';
  str += '\tuhrzeit2 = ' + this.uhrzeit2() +'<br>\n';
  str += '\tdetailURL = ' + this.detailURL() +'<br><br>\n\n';
  return str;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ============================================================
// Klasse Tag
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// Tag(datum)
// ---------------------------------------
//
// Beschreibung:
// -------------
// Konstruiert ein TagObjekt mit optionalen Eigenschaften
//
// Beispiel:
// ---------
// 

function Tag(datum, sprache) {  
  // Attribute
  this._datum = undefined;
  this._sprache = undefined;
  this._properties = undefined;
  // Initialisierungen
  this.datum(datum);
  this.sprache(sprache);
  this.properties(DateProperties.createDateProperties({'datum':this.datum()},{'sprache':this.sprache()}));
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// datum(obj)
// -----------
//
// Beschreibung:
// -------------
//

Tag.prototype.datum = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Date) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassDate!");
    }
    this._datum = obj;
  }
  return this._datum;
}

// -----------
// sprache(str)
// -----------
//
// Beschreibung:
// -------------
//

Tag.prototype.sprache = function(str) {
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("ArgumentError:noString!");
    }
    this._sprache = str;
  }
  return this._sprache;
}

// -----------
// feiertag(obj)
// -----------
//
// Beschreibung:
// -------------
//

Tag.prototype.properties = function(obj) {
  if (arguments.length) {
    if (! obj instanceof DateProperties) {
      focus();
      throw new Error("ArgumentError:noObjectFromClassFeiertag!");
    }
    this._properties = obj;
  }
  return this._properties;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// -------------------------------------------
// Tag.createTag(datum)
// -------------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
// Tag.createTag({'datum':new Date()});
//

Tag.createTag = function() {  
  // defaultArguments
  var defArg = {};
  defArg['datum'] = new Date();
  defArg['sprache'] = 'de';
  // givenArguments
  defArg = Calendartools.getArgumentsAssArray(defArg, arguments);
  return new Tag(defArg['datum'], defArg['sprache']);
}

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

Tag.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  //return Object.prototype.toString.apply(this);
  var str = new String('');
  str += '<b>Tag</b><br>'
  str += '\tdatum = ' + this.datum() +'<br>\n';
  str += '\tproperties = <br>' + this.properties() +'<br><br>\n\n';
  return str;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ============================================================
// Klasse CalendarUtil
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// CalendarUtil()
// ---------------------------------------
//
// Beschreibung:
// -------------
//
// Beispiel:
// ---------
// 

function CalendarUtil() {  
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// ------------------------
// CalendarUtil.getDocumentFragment
// ------------------------
//
// Beschreibung:
// -------------
//   Wandelt einen HTML-String in ein DocumentFragment um.
//
// Beispiel:
// ---------
//   var f = CalendarUtil.getDocumentFragment(html);
//   var f = CalendarUtil.getDocumentFragment(html, document);
//
CalendarUtil.getDocumentFragment = function(html, doc) {
  if (!doc) {
    doc = document;
  }
  if (html.substr(0,6) == "<tbody" || html.substr(0,3) == "<tr") {
    html = "<table>" + html + "</table>";
    var elem = doc.createElement("div");
    elem.innerHTML = html;
    var f = doc.createDocumentFragment();
    if (elem.childNodes.length>1) {
      throw new Error("Fehler mit <tgroup>");
    }
    elem = elem.firstChild;
    while (elem.firstChild) {
      f.appendChild(elem.firstChild);
    }
    return f;
  }
  var elem = doc.createElement("div");
  elem.innerHTML = html;
  var f = doc.createDocumentFragment();
  while (elem.firstChild) {
    f.appendChild(elem.firstChild);
  }
  return f;
}

// ------------------------
// CalendarUtil.replaceDocumentNode
// ------------------------
//
// Beschreibung:
// -------------
//   Ersetzt eine Node durch eine neue.
//   Übergeben wird dazu ein HTML-String, der genau ein Wurzel-Element haben muss.
//
// Beispiel:
// ---------
//   var f = CalendarUtil.replaceDocumentNode(id, html);
//   var f = CalendarUtil.replaceDocumentNode(id, html, document);
//
CalendarUtil.replaceDocumentNode = function(id, html, doc) {
  if (!doc) {
    doc = document;
  }
  var f = CalendarUtil.getDocumentFragment(html, doc);
  if (f.childNodes.length>1) {
    //throw new Error("HTML-String muß genau ein Wurzel-Element haben:\n" + html);
  }
  var target = doc.getElementById(id);
  if (!target) {
    throw new Error("Element-ID not found in document: " + id + '\nDocument: ' + doc.URL);
  }
  target.parentNode.replaceChild(f, target);
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////
