﻿// collection of objects.
function Collection()
{
	this.type = "";
  this.items = new Array();
	this.count = 0;
  this.add = addCollectionItem;
	this.get = getCollectionItem;

	// Adds an item (object) to the collection.
	// item: The object to add
	// remark: Only objects of class specified in this.type are allowed.
  function addCollectionItem(item)
  {
		var className = /(\w+)\(/.exec(item.constructor.toString())[1];
		if(className == this.type && item.id)
		{
			this.items[this.count] = item;
			this.count++;
		}
		else
		{
			if(item.id)alert('Collection.add Error\nOnly >' + this.type + '< allowed!');
			else alert('Collection.add Error\nItem has no >Id< Property!');
		}
  }

  // Get an object from the collection by object.id;
  function getCollectionItem(id)
  {
		var item = null;
		for(i=0;i<this.count;i++)
		{
			if(this.items[i].id == id)
			{
				item = this.items[i];
			}
		}
		return item;
  }
}

/* Prices */
function Price(id, type, caption, value, formatedValue)
{
  this.id = id;
  this.type = type;
  this.caption = caption;
  this.value = value;
  this.formatedValue = formatedValue;
  this.formatPrice = formatPrice;

	function formatPrice(strValue, currency)
	{
		var objRegExp  = new RegExp('(-?[0-9]+)([0-9]{3})');
		switch(currency)
		{
		  case '€':
		    strValue = strValue + ' €';
        break;
		  case '£':
		    strValue = '£' + strValue;
        break;
		  case '$':
		    strValue = '$ ' + strValue;
        break;
		  default:
		    strValue = strValue + ' ' + currency
        break;
		}
		strValue = strValue.replace('.', ',');

		//check for match to search criteria
		while(objRegExp.test(strValue))
		{
				//replace original string with first group match,
				//a comma, then second group match
				strValue = strValue.replace(objRegExp, '$1.$2');
		}
		return strValue;
	}      
}

// Collection of Price elements. Derived from Collection.
function Prices()
{
  this.items = new Array();
	this.type = "Price";
	this.sum = sumPrices;
  this.currency = '€';

  function sumPrices()
  {
		var price = 0;
		for(i=0;i<this.count;i++)
		{
			price += this.items[i].value;
		}
		
		price = new Price('sum', null, null, price, null);
		price.formatedValue = price.formatPrice(price.value, this.currency);
		return price;
		//return price;
  }
}
Prices.prototype = new Collection;

/* Options */
function FormOption(id, caption, description, price)
{
  this.id = id;
  this.caption = caption;
  this.description = description;
  this.price = price;
}

// Collection of FormOption elements. Derived from Collection.
function FormOptions()
{
  this.items = new Array();
	this.type = "FormOption";
}
FormOptions.prototype = new Collection;

// Helper Methods for handling forms
function FormHelper(formName)
{
	this.name = formName; // Set/Get the Name of the form
	this.get = getElement; 
	this.enable = enableElement;
	this.disable = disableElement;
	this.value = getFormValue; // Get the value of an form element
	this.attachToEvent = attachToEvent;
	
  // enables a form element.
  // elementName: name of the form element
  // remark: The className of the table with id table_[elementName] will be assigned to formsfield
	function enableElement(elementName)
	{
    var table = this.get('table_' + elementName);
    var element = this.get(elementName);
    if(table)table.className='formsfield';
    if(element)element.disabled=false;
	}

  // Disables a form element.
  // elementName: name of the form element
  // remark: The className of the table with id table_[elementName] will be assigned to disabledformsfield
	function disableElement(elementName)
	{
    var table = this.get('table_' + elementName);
    var element = this.get(elementName);
    if(table)table.className='disabledformsfield';
    if(element)
    { element.disabled=true;
		  if(element.selectedIndex)element.selectedIndex = 0;
		}
	}
	
  // Get a form element.
  // elementName: name of the form element
  function getElement(elementName)
  {
    var element = null;
    element = document.getElementById(elementName);
		if(!element)element = eval('document.forms["' + this.name + '"].' + elementName);
		return element;
	}
	
  // Get the value of a form element.
  // elementName: name of the form element
  function getFormValue(elementName)
  {
		formElement = eval('document.forms["' + this.name + '"].' + elementName);
		if(formElement)
		{
		  if(formElement.length != null)var type = formElement[0].type;
		  if((typeof(type) == 'undefined') || (type == 0)) var type = formElement.type;

		  switch(type)
		  {
			  case 'undefined': return;

			  case 'radio':
				  for(var x=0; x < formElement.length; x++) 
					  if(formElement[x].checked == true)
				  return formElement[x].value;

			  case 'select-multiple':
				  var myArray = new Array();
				  for(var x=0; x < formElement.length; x++) 
					  if(formElement[x].selected == true)
						  myArray[myArray.length] = formElement[x].value;
				  return myArray;

			  case 'checkbox': return formElement.checked;
  		
			  default: return formElement.value;
		  }
		}
	}

  function attachToEvent(obj,eventToAttach,functionToAdd)
  {
	  var oldEvent = (eval('obj.' + eventToAttach)) ? eval('obj.' + eventToAttach) : function () {};
	  eval('obj.' + eventToAttach + ' = function(){oldEvent();functionToAdd();}')
  }
}

function DrivingSchoolContanier(formName)
{
	this.name = formName;
	this.selectParticipants = selectParticipants;
	this.selectPaticipateCarType = selectPaticipateCarType;
	this.selectHotelBooking = selectHotelBooking;
	this.selectHotel = selectHotel;
	this.calcPrice = calcPrice;
	this.init = init;
	this.currency = '€';
	this.hotels = null;
	this.rentCars = null;
  this.basePrice = null;
	this.personalTrainerPrices = null;
	this.participantPrices = null;
	this.totalPriceElementname = 'training_totalprice';

	function init()
	{
	  var obj = this;
		var initFunction = function()
		{
			obj.selectPaticipateCarType();
			obj.selectParticipants();
			obj.selectHotelBooking();
			obj.calcPrice();
    }
		obj.attachToEvent(window,'onload',initFunction);
	}
	
  function selectParticipants()
  {
		var persons = this.value('drivingschool2_participants')
    if(persons != '0')
    {
      this.enable('drivingschool2_firstname');
      this.enable('drivingschool2_lastname');
    }
    else
    {
      this.disable('drivingschool2_firstname');
      this.disable('drivingschool2_lastname');
    }
    this.selectHotelBooking();
  }

  function selectPaticipateCarType()
  {
		var selectedCar = null;
		sfsCarElement = this.get('drivingschool2_sfscar')
		if(sfsCarElement)
		{
			/*
			document.forms["formcontrol"].drivingschool2_sfscar.length = 1;
			document.forms["formcontrol"].drivingschool2_sfscar.selectedIndex = 0;
			for(i=0;i<this.rentCars.count;i++)
			{
				selectedCar = this.rentCars.items[i];
				newValue = new Option(selectedCar.caption + ' - ' + selectedCar.price.formatedValue + ' ' + selectedCar.price.caption, selectedCar.id, false, false);
				document.forms["formcontrol"].drivingschool2_sfscar.options[document.forms["formcontrol"].drivingschool2_sfscar.length] = newValue;
			}
			*/

			var currentCarType = this.value('drivingschool2_paticipatecartype');
			switch(currentCarType)
			{
				case 'rent':
					this.enable('drivingschool2_sfscar');
					this.disable('car_make');
					this.disable('car_model');
					this.disable('car_type');
					this.disable('car_modelyear');
					this.disable('car_licencenumber');
					this.disable('car_power');
					break;
				case 'own':
					this.disable('drivingschool2_sfscar');
					this.enable('car_make');
					this.enable('car_model');
					this.enable('car_type');
					this.enable('car_modelyear');
					this.enable('car_licencenumber');
					this.enable('car_power');
					break;
				default:
					this.disable('drivingschool2_sfscar');
					this.disable('car_make');
					this.disable('car_model');
					this.disable('car_type');
					this.disable('car_modelyear');
					this.disable('car_licencenumber');
					this.disable('car_power');
					break;
			}
    }
  }

  function selectHotel()
  {
	  var selectedHotel;
		var price;
		if(this.get('drivingschool2_hotel'))
		{
			var participants = this.value('drivingschool2_participants');
			curHotelId = this.value('drivingschool2_hotel');
			selectedHotel = this.hotels.get(curHotelId);
			hotelRoomOne = this.get('drivingschool2_hotelroomone');
			hotelRoomTwo = this.get('drivingschool2_hotelroomtwo');
			if(selectedHotel)
			{
	      this.enable('drivingschool2_hotelroomone');
        if(participants != '0')this.enable('drivingschool2_hotelroomtwo');
        else this.disable('drivingschool2_hotelroomtwo');

				if(hotelRoomOne)hotelRoomOne.length = 1;
				if(hotelRoomTwo)hotelRoomTwo.length = 1;
				for(i=0;i<selectedHotel.price.count;i++)
				{
					price = selectedHotel.price.items[i];
					newValue = new Option(price.caption + ' - ' + price.formatedValue, price.id, false, false);
					switch(price.type)
					{
						case 'hotelroomone':
							if(hotelRoomOne)hotelRoomOne.options[hotelRoomOne.length] = newValue;
							break;
						case 'hotelroomtwo':
							if(hotelRoomTwo)hotelRoomTwo.options[hotelRoomTwo.length] = newValue;
							break;
					}
				}
			}
			else
			{
        if(participants == '0')this.disable('drivingschool2_hotelroomtwo');
				if(hotelRoomOne)hotelRoomOne.length = 1;
				if(hotelRoomTwo)hotelRoomTwo.length = 1;
        this.disable('drivingschool2_hotelroomone');
        this.disable('drivingschool2_hotelroomtwo');
			}
    }
  }

  function selectHotelBooking()
  {
    var booking = this.value('drivingschool2_hotelbooking');
    var participants = this.value('drivingschool2_participants');
    switch(booking)
    {
      case 'yes':
        this.enable('drivingschool2_hotel');
        break;
      default:
        this.disable('drivingschool2_hotel');
        break;
    }
    this.selectHotel();
  }

  function calcPrice()
  {
    var prices = new Prices();
		var price = null;

		prices.currency = this.currency;

    prices.add(new Price('base', null, null, this.basePrice));
    
		/* calculate participants */
		var currentParticipants = this.value('drivingschool2_participants');
		if(currentParticipants && currentParticipants != '0')
		{
			price = null;
			price = this.participantPrices.get(currentParticipants);
      if(price)prices.add(new Price(currentParticipants, null, null, price.value));
		}

		/* calculate car */
		var currentCarType = this.value('drivingschool2_paticipatecartype');
		if(currentCarType && currentCarType == 'rent')
		{
			price = null;
			var selectedCar = this.value('drivingschool2_sfscar');
			if(selectedCar && selectedCar != '')price = this.rentCars.get(selectedCar);
      if(price)
      {
				price = price.price
				prices.add(new Price(selectedCar, null, null, price.value));
      }
		}

		/* calculate personal trainer */
		var currentPT = this.value('drivingschool2_personaltrainer')
		if(currentPT && currentPT != '')
		{
		  price = this.personalTrainerPrices.get(currentPT)
			if(price)prices.add(price);
		}
		
		sum = prices.sum()
		this.get(this.totalPriceElementname).innerHTML=sum.formatedValue;
  }
      
	/************************************************
	DESCRIPTION: Inserts commas into numeric string.

	PARAMETERS:
		strValue - source string containing commas.

	RETURNS: String modified with comma grouping if
		source was all numeric, otherwise source is
		returned.

	REMARKS: Used with integers or numbers with
		2 or less decimal places.
	*************************************************/
}
DrivingSchoolContanier.prototype = new FormHelper(DrivingSchoolContanier.name)

/*
function ContainerManager(sId)
{
  var m_id;
  var m_containerElem;
  
  this.id = m_id;
  this.switchDisplay = switchDisplay;
  this.getContainer = getContainer;

  function switchDisplay()
  {
    var cssClass = this.getContainer().className;
    if(cssClass.indexOf('collapsed') > 0)cssClass = cssClass.replace('collapsed','expanded');
    else cssClass = cssClass.replace('expanded','collapsed');
    this.getContainer().className = cssClass;
  }
  
  function getContainer() {
    if(!m_containerElem) {
      var containerElem = document.getElementById(sId);
      if(containerElem) {
        m_id = sId;
        m_containerElem = containerElem;
      }
      else {
        alert('Error: Container ' + sId + ' not found!');
      }
    }
    return m_containerElem;
  }
}
*/

/*
// Class Input Element
function InputElement(id, completed)
{
   this.id = id
   this.required = false;
   this.completed = false;

   if(id == null)
      throw ('InputElement: id may not be null')
   if(completed == null)
      throw ('InputElement: required may not be null')

   switch(completed)
   {
     case true:
     case 1:
     case 'true':
     case 'True':
     case 'TRUE':
     case '1':
        this.completed = true;
        break;
     default:
        this.completed = false;
        break;
   }
}
*/

/***************************************************************/
/*                                                             */
/*                      SSO-Optimierung                        */
/*                                                             */
/***************************************************************/

var g_container_curr_open = null;

// Variablen für Complete/Incomplete Icons
// Defaultwerte können über die Textliste des Formulars überschrieben werden
var g_icon_imagepath = '/images/icons/';
var g_icon_image_complete = 'complete.gif';
var g_icon_image_incomplete = 'incomplete.gif';
var g_icon_title_complete = 'ausgefüllt';
var g_icon_title_incomplete = 'nicht ausgefüllt';


// Class Dynamic Container
function DynamicContainer(sBaseId, typeOptions, formName, iMinComplete, iMaxComplete, iShowMinSubcontainers, iMinCompleteSubcontainers, sSubContainerDisabledTriggerElementID, sSubContainerDisabledTriggerElementValue)
{
    this.baseId = sBaseId;
    this.toggle = toggle;
    this.init = init;
    this.container = null;
    this.containerHead = null;
    this.formName = 'formcontrol'; // formName;
    this.isInitialized = false;
    this.maxSubContainers = 0;
    this.subContainers = null;
    this.typeOptions = typeOptions;
    this.toggleSubContainer = toggleSubContainer;
    this.toggleSubContainer2 = toggleSubContainer2;
    this.toggleSubContainersAll = toggleSubContainersAll;
    this.reinitializeTypes = reinitializeTypes;
    this.minShowSubContainers = (iShowMinSubcontainers == null ? 2 : iShowMinSubcontainers);
    this.inputElements = new Hashtable();
    this.isCompleted = isCompleted;
    this.setComplete = setComplete;
    this.completedIcon = null;
    this.checkComplete = checkComplete;
    this.minComplete = iMinComplete;
    this.maxComplete = iMaxComplete;
    this.minCompleteSubcontainers = iMinCompleteSubcontainers;
    this.initItems = initItems;
    this.isExpanded = isExpanded;
    this.initSubContainers = initSubContainers;
    this.fillContainer = fillContainer;
    this.resetInput = resetInput;
    this.checkDisableSubcontainers = checkDisableSubcontainers;
    this.disabledSubContainerTriggerElementID = (sSubContainerDisabledTriggerElementID == null ? null : sSubContainerDisabledTriggerElementID);
    this.disabledSubContainerTriggerElementValue = (sSubContainerDisabledTriggerElementValue == null ? null : sSubContainerDisabledTriggerElementValue);

    this.checkDisableContainers = checkDisableContainers;
    this.containerTriggerElement = null;
    this.containerTriggerElementTargets = null;
    this.tcCount = 0;

    this.init();

    function init()
    {
        this.containerHead = document.getElementById(this.baseId + '_head');
        this.container = document.getElementById(this.baseId);
        if (!this.container)
        {
            alert('Error: Container ' + this.baseId + ' not found!');
        }
        else
        {
            var elem = null;
            var subCounter = 0;
            do
            {
                subCounter++;
                elem = document.getElementById(this.baseId + subCounter)
            }
            while (elem)
            {
                this.maxSubContainers = subCounter - 1;
            }
            this.subContainers = new Array(this.maxSubContainers);
            var subCounterLastCompleted = 0;
            var subCounter = 0
            for (subCounter; subCounter < this.maxSubContainers; subCounter++)
            {
                this.subContainers[subCounter] = new SubContainer(this.baseId + (subCounter + 1), this.typeOptions, subCounter + 1)
                if (this.minShowSubContainers > subCounter)
                {
                    this.subContainers[subCounter].forceVisible = true;
                    this.subContainers[subCounter].show();
                    if ((this.subContainers[subCounter].inputTypeElem.value != '') || (subCounter == 0)) // Felder anzeigen wenn: Dropdown ausgefüllt ODER 1. Container
                    {
                        this.subContainers[subCounter].showFields();
                        subCounterLastCompleted = subCounter;
                    }
                }
                else
                {
                    if (subCounter == 0)
                    {
                        this.subContainers[subCounter].show();
                    }
                    // wenn aktueller Subcontainer ausgefüllt: anzeigen
                    if (this.subContainers[subCounter].inputTypeElem.value != '')
                    {
                        this.subContainers[subCounter].show();
                        this.subContainers[subCounter].showFields();
                        subCounterLastCompleted = subCounter;
                    }
                    else
                    {
                        // wenn vorheriger Subcontainer ausgefüllt, dann Dropdown des aktuellen Subcontainer anzeigen
                        if (subCounterLastCompleted == (subCounter - 1))
                        {
                            this.subContainers[subCounter].show();
                            this.subContainers[subCounter].hideFields();
                        }
                    }
                }
            }
            if (this.maxSubContainers > 0)
                this.toggleSubContainersAll(this);

            this.completedIcon = document.getElementById(this.baseId + 'Completion');
            if (this.completedIcon == null)
                ; //alert(this.baseId + 'Completion' + ' is undefined');
            else
                this.checkComplete();

            if (this.isExpanded())
            {
                g_container_curr_open = this;
            }

            this.reinitializeTypes();

            this.isInitialized = true;
        }
    }

    function isExpanded()
    {
        return (this.container.className.indexOf('expanded') > 0);
    }

    ///////////////////
    // STV: 
    //    >> Variante 1: für jedes Element in oHashtable prüfen ob der Container ein solches Element hat: 
    //        ja -> den entsprechenden Wert im Container setzen
    //        nein -> nichts tun
    //
    //    >> Variante 2: für jedes Element in this.inputElements, prüfen ob es einen Wert in der Hashtable gibt: 
    //        ja   -> Wert im Container setzen
    //        nein -> Wert im Container löschen
    //
    //    >> implementiert ist Variante 1
    //
    function fillContainer(oHashtable)
    {
        if (typeof (oHashtable) == 'undefined')
            return;

        if (oHashtable.items == 'undefined')
            return;

        // Variante 1:
        for (var key in oHashtable.items)
        {
            var elemID = this.baseId + '_' + key;
            var elem = document.getElementById(elemID);
            //alert(elemID + ' = ' + elem);
            if (elem)
            {
                var elementValue = oHashtable.getItem(key);
                var elemCompleted = false;
                if (typeof (elem.type) != 'undefined')
                {
                    if ((elem.type == 'checkbox') || (elem.type == 'radio'))
                    {
                        elem.checked = true;
                        elemCompleted = true;
                    }
                    else if (elem.type == 'text')
                    {
                        elem.value = elementValue;
                        elemCompleted = (elem.value != null && elem.value.toString() != '');
                    }
                    else if (typeof (elem.selectedIndex) != 'undefined')
                    {
                        for (var i = 0; i < elem.options.length; i++)
                        {
                            if (elem.options[i].value == elementValue)
                            {
                                elem.selectedIndex = i;
                                elemCompleted = true;
                                break;
                            }
                        }
                    }
                    if (elem.onchange)
                    {
                        elem.onchange();
                    }
                }
                this.inputElements.setItem(elemID, elemCompleted);
            }
        }

        this.checkComplete();
    }

    function initItems(aItemIDs, aContainerTrigger, aContainerTriggerTargets)
    {
        if ((typeof (aContainerTrigger) != 'undefined') && (typeof (aContainerTriggerTargets) != 'undefined')) {
            if ((aContainerTrigger.length == 2) && (aContainerTriggerTargets.length > 0)) {
                if (this.containerTriggerElement == null) {
                    this.containerTriggerElement = new Hashtable();
                    this.containerTriggerElement.setItem(aContainerTrigger[0], aContainerTrigger[1]); // trigger ElementID, ausgewählte Value bei dem der Trigger ausgelöst wird
                }
                if (this.containerTriggerElementTargets == null)
                    this.containerTriggerElementTargets = new Hashtable();

                // jedes Element, das für den Trigger ausgeblendet werden soll:
                var j = 0;
                var aTmp = new Array();
                for (j; j < aContainerTriggerTargets.length; j++) {
                    aTmp[j] = aContainerTriggerTargets[j];
                    //alert(j + ': ' + aTmp[j]);
                }
                this.containerTriggerElementTargets.setItem(aContainerTrigger[0], aTmp);
            }
        }
        for (var i = 0; i < aItemIDs.length; i++)
        {
            var elemID = /*this.baseId + '_' +*/ aItemIDs[i];
            var elem = document.getElementById(elemID);
            if (!elem)
            {
                elemID = this.baseId + '_' + aItemIDs[i];
                elem = document.getElementById(elemID);
            }
            if (elem)
            {
                var elemCompleted = false;
                if (elem.type == 'text') 
                {
                    if (elem.value.toString() == '')
                        elemCompleted = false;
                    else
                        elemCompleted = true;
                }
                else if (typeof (elem.checked) != 'undefined') 
                {
                    elemCompleted = elem.checked;
                }
                else if (typeof (elem.value) != 'undefined') 
                {
                    elemCompleted = ((elem.value == null) || (elem.value.toString() == '')) ? false : true;
                }
                if (elem.type == 'radio') // Radiobuttons sind immer false
                {
                    elemCompleted = false;
                }

                this.inputElements.setItem(elemID, elemCompleted);
                this.checkDisableSubcontainers(elemID);
                this.checkDisableContainers(elemID);
            }
        }
        //this.checkComplete();
    }

    function initSubContainers(aSubcontainerItems, aSubcontainerTrigger, aSubcontainerTriggerTargets)
    {
        for (var subCounter = 0; subCounter < this.maxSubContainers; subCounter++)
        {
            this.subContainers[subCounter].initSubcontainerItems(aSubcontainerItems, this.baseId + (subCounter + 1).toString(), aSubcontainerTrigger, aSubcontainerTriggerTargets);
        }
        this.reinitializeTypes();
        this.checkComplete();
    }


    // TODO: fix
    function setComplete(inputElementID, elementValue)
    {
        if (this.inputElements.hasItem(inputElementID))
        {
            if (elementValue == '')
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == 'undefined')
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == null)
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == 0) 
                this.inputElements.setItem(inputElementID, true);
            else if (elementValue == false)
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == true)
                this.inputElements.setItem(inputElementID, true);
            else
                this.inputElements.setItem(inputElementID, true);

            this.checkDisableSubcontainers(inputElementID);
            this.checkDisableContainers(inputElementID);
        }
    }

    // prüft ob der Haupt-Container als ausgefüllt zähllt
    function isCompleted()
    {
        var complete = true;
        var countComplete = 0;
        var countIncomplete = 0;
        var foundPush = false;  // Safari (Win) hat immer ein zusätzliches Element Namens 'push' ?!?
        for (var key in this.inputElements.items)
        {
            foundPush = (key == 'push');
            if (!foundPush)
            {
                if (this.inputElements.getItem(key) == false)
                {
                    var tmpElem = document.getElementById(key);
                    if ( (typeof(tmpElem) != 'undefined') && (typeof (tmpElem.type) != 'undefined')  &&  (tmpElem.type == 'radio') )
                    {
                        ; // radio buttons ignorieren
                    }
                    else
                        countIncomplete++;
                }
                else
                {
                    countComplete++;
                }
            }
        }

        // Keine Eingabeelemente oder alle ausgefüllt: ok
        if (countIncomplete == 0)
        {
            complete = true;
        }
        else if (this.minComplete == null) // countIncomplete > 0 und es müssen alle Felder ausgefüllt sein
        {
            complete = false;
        }
        else
        {
            // Anzahl ausgefüllter Elemente >= Mindestanzahl auszufüllender Elemente
            if (countComplete >= this.minComplete)
            {
                complete = true;
            }
            else
            {
                complete = false;
            }
        }

        if (complete) 
        {
            // wenn Hauptcontainer ausgefüllt, aber keine Elemente enthält UND Subcontainer existieren: -> incomplete setzen)
            if((this.inputElements.length == 0) && (this.subContainers.length > 0))
            {
                complete = false;
            }
        }

        if (complete)
        {
            // nicht ausgewählte Elemente auf 'disable', wenn 
            // maximale Anzahl ausfüllbarer Elemente erreicht
            if (countComplete == this.maxComplete)
            {
                for (var key in this.inputElements.items)
                {
                    if (this.inputElements.getItem(key) == false)
                    {
                        var elemDisable = document.getElementById(key);
                        if (elemDisable)
                        {
                            elemDisable.disabled = 'disabled';
                        }
                    }
                }
            }
            else
            {
                //alle Elemente auf enable
                for (var key in this.inputElements.items)
                {
                    if (this.inputElements.getItem(key) == false)
                    {
                        var elemDisable = document.getElementById(key);
                        if (elemDisable)
                        {
                            elemDisable.disabled = '';
                        }
                    }
                }
            }
        }

        // alert(this.baseId + ' completed: ' + complete);

        return complete;
    }

    function checkComplete()
    {
        var completed = this.isCompleted();
        var completedSubcontainer = 0;

        // Subcontainer prüfen:
        if (!completed                                  // wenn Hauptcontainer nicht ausgefüllt 
            ||                                          // ODER
            ((this.minComplete == null) && completed)   // Gesamter Container muss komplett ausgefüllt sein UND Hauptcontainer ist ausgefüllt 
           ) 
        {
            for (var subCounter = 0; subCounter < this.maxSubContainers; subCounter++) 
            {
                if (this.subContainers[subCounter].display == true) 
                {
                    var subContainerCompleted = this.subContainers[subCounter].isCompleted();

                    if (subContainerCompleted)
                        completedSubcontainer++;

                    if (this.minCompleteSubcontainers != null && this.minCompleteSubcontainers <= completedSubcontainer) 
                    {
                        completed = true;
                        break;
                    }
                    else if (this.minCompleteSubcontainers != null && this.minCompleteSubcontainers > completedSubcontainer) 
                    {
                        continue;
                    }
                    else if (subContainerCompleted == false) 
                    {
                        completed = false;
                        break;
                    }
                }
            }
        }

        if (this.completedIcon != null)
        {
            if (completed)
            {
                this.completedIcon.src = g_icon_imagepath + g_icon_image_complete; // 'images/complete.gif';
                this.completedIcon.alt = g_icon_title_complete;
                this.completedIcon.title = g_icon_title_complete;
            }
            else
            {
                this.completedIcon.src = g_icon_imagepath + g_icon_image_incomplete; //'images/incomplete.gif';
                this.completedIcon.alt = g_icon_title_incomplete;
                this.completedIcon.title = g_icon_title_incomplete;
            }
        }
    }

    function checkDisableContainers(checkInputElementID) 
    {
        if ((this.containerTriggerElement == null) || (this.containerTriggerElementTargets == null))
            return;

        if (!this.containerTriggerElement.hasItem(checkInputElementID))
            return;

        if (!this.containerTriggerElementTargets.hasItem(checkInputElementID))
            return;

        var elemTrigger = document.getElementById(checkInputElementID);
        if (elemTrigger) 
        {
            var triggerValue = this.containerTriggerElement.getItem(checkInputElementID).toString();
            var aTriggerTargets = this.containerTriggerElementTargets.getItem(checkInputElementID);
            // alert(checkInputElementID + ' | ' + triggerValue + ' | ' + aTriggerTargets);
            if (typeof (aTriggerTargets) != 'object')
                return;

            var enable = false;

            //alert(elemTrigger.value.toString() + ' | ' + triggerValue + ' | ' + elemTrigger.checked.toString());
            if (elemTrigger.value.toString() != triggerValue) 
            {
                enable = true;
            }
            if (elemTrigger.type == 'checkbox') 
            {
                enable = !elemTrigger.checked; // && elemTrigger.value.toString() != triggerValue;
            }

            for (var i = 0; i < aTriggerTargets.length; i++) 
            {
                try
                {
                    var htElementsToDisable = eval(aTriggerTargets[i]).inputElements;  //this.setEnabled(aTriggerTargets[i], enable);
                    //alert(htElementsToDisable);
                    if (htElementsToDisable) 
                    {
                        for (var key in htElementsToDisable.items) 
                        {
                            //alert(key);
                            var elem = document.getElementById(key);
                            if (elem) 
                            {
                                elem.disabled = (enable ? false : true);
                            }
                        }
                    }
                }
                catch (e)
                {
                    if (this.tcCount < 3) 
                    {
                        this.tcCount += 1;
                        //alert(this.baseId + ".checkDisableContainers('" + checkInputElementID + "')");
                        window.setTimeout(this.baseId + ".checkDisableContainers('" + checkInputElementID + "')", 200);
                    }
                    else 
                    {
                        this.tcCount = 0;
                    }
                }
            }
        } 
    }

    // wenn itemValue == disabledTriggerValue, dann werden alle Subcontainer resetet (und dadurch ausgeblendet). Danach werden alle Eingabefelder im 1. Subcontainer auf Disable gesetzt.
    function checkDisableSubcontainers(checkInputElementID) 
    {
        if (this.disabledSubContainerTriggerElementID == null)
            return;

        if (checkInputElementID != this.disabledSubContainerTriggerElementID)
            return;

        var elemTrigger = document.getElementById(this.disabledSubContainerTriggerElementID);
        if(elemTrigger)
        {
            if (elemTrigger.value.toString() != this.disabledSubContainerTriggerElementValue.toString()) // toString(), da sonst ('' != 0) false ist: durch die Typkonvertierung nach Boolean wird '' = false und 0 = false also flase != false
            {
                if (this.subContainers) 
                {
                    this.subContainers[0].setEnabledAll(true); // 1. Container immer auf enable, falls er vorher disabled wurde.
                }
                return;
            }

            for (var subCounter = this.maxSubContainers - 1; subCounter >= 0; subCounter--) 
            {
                this.subContainers[subCounter].resetInput();
                if (subCounter == 0)
                    this.subContainers[subCounter].setEnabledAll(false);
            }
        }
    }

    function toggle()
    {
        var cssClass = this.container.className;
        var cssClassContainer = (this.containerHead != null ? this.containerHead.className : '');
        var isOpen = false;
        if (cssClass.indexOf('collapsed') > 0)
        {
            cssClass = cssClass.replace('collapsed', 'expanded');
            cssClassContainer = cssClassContainer.replace('containercollapsed', 'containerexpanded');
            isOpen = true;
        }
        else
        {
            cssClass = cssClass.replace('expanded', 'collapsed');
            cssClassContainer = cssClassContainer.replace('containerexpanded', 'containercollapsed');
        }

        // wenn dieser container aufgeklappt wurde, dann den bestehenden offenen Container schließen
        if (isOpen)
        {
            if ((g_container_curr_open != null) && (g_container_curr_open != this))
            {
                if (typeof (g_container_curr_open.isExpanded) != 'undefined')
                {
                    if (g_container_curr_open.isExpanded())
                    {
                        g_container_curr_open.toggle();
                    }
                }
            }
            g_container_curr_open = this;
        }

        this.container.className = cssClass;
        if (this.containerHead != null)
            this.containerHead.className = cssClassContainer;
    }

    function reinitializeTypes()
    {
        var usedTypes = '';
        var currElem = null;
        var currValue = '';
        for (var subCounter = 0; subCounter < this.maxSubContainers; subCounter++)
        {
            currElem = this.subContainers[subCounter].inputTypeElem
            currValue = currElem.options[currElem.selectedIndex].value;
            if (currValue != '') 
                usedTypes += currElem.options[currElem.selectedIndex].value + ';';
        }

        for (var subCounter = 0; subCounter < this.maxSubContainers; subCounter++)
        {
            this.subContainers[subCounter].reinitializeTypes(usedTypes);
        }
    }

    function toggleSubContainersAll(objContainer) 
    {
        for (var i = objContainer.subContainers.length; i >= 1; i--)
        {
            toggleSubContainer2(i, objContainer);
        }
    }
    function toggleSubContainer(number)
    {
        toggleSubContainersAll(this);
    }
    function toggleSubContainer2(number, objContainer)
    {
        var nextCont = objContainer.subContainers[number];
        var currCont = objContainer.subContainers[number - 1];

        objContainer.reinitializeTypes();
        if (currCont.inputTypeElem.options[currCont.inputTypeElem.selectedIndex].value == '')
        {
            //currCont.hideFields(); // Felder des aktuellen Containers nur verstecken wenn es keinen Folgecontainer gibt
            if (typeof (nextCont) != 'undefined') 
            {
                if (nextCont.inputTypeElem.selectedIndex == 0) 
                {
                    currCont.hideFields(); // Felder des aktuellen Containers nur verstekcen, wenn im Folgecontainer nichts ausgewählt wurde
                }
                while (typeof(nextCont) != 'undefined') 
                {
                    if (nextCont.inputTypeElem.selectedIndex == 0) 
                    {
                        //toggleSubContainer(number+1);
                        nextCont.hide();
                        nextCont.hideFields();
                    }
                    number++;
                    nextCont = objContainer.subContainers[number];
                    if ((typeof (nextCont) == 'undefined')) 
                    {
                        currCont.hideFields(); // Felder des aktuellen Containers nur verstekcen, wenn im Folgecontainer nichts ausgewählt wurde
                    } 
                }
                
            }
            else
            {
                currCont.hideFields();
                //currCont.hide(); // << warum drop down verstecken?
            }
        }
        else
        {
            currCont.showFields();
            if (nextCont)
            {
                nextCont.show();
            }
        }
    }

    function resetInput()
    {
        for (var key in this.inputElements.items)
        {
            var elem = document.getElementById(key);
            //alert(elem);
            if (elem)
            {
                if (typeof (elem.type) != 'undefined')
                {
                    if ((elem.type == 'text') || (elem.type == 'password'))
                    {
                        elem.value = '';
                        if (elem.onblur)
                            elem.onblur();
                    }
                    else if (elem.type == 'checkbox')
                    {
                        elem.checked = false;
                        if (elem.onclick)
                            elem.onclick();
                    }
                    else if (elem.type == 'radio')
                    {
                        //alert(document.forms['formcontrol'].elements[elem.name]);
                        var i = 0;
                        for (i; i < document.forms['formcontrol'].elements[elem.name].length; i++)
                        {
                            //alert(document.forms['formcontrol'].elements[elem.name][i].checked);
                            document.forms['formcontrol'].elements[elem.name][i].checked = false;
                            if (document.forms['formcontrol'].elements[elem.name][i].onclick)
                                document.forms['formcontrol'].elements[elem.name][i].onclick();
                        }
                    }
                    if (typeof (elem.selectedIndex) != 'undefined')
                    {
                        elem.selectedIndex = 0;
                        if (elem.onchange)
                            elem.onchange();
                    }
                }
                else if (typeof (elem.selectedIndex) != 'undefined')
                {
                    elem.selectedIndex = -1;
                    if (elem.onchange)
                        elem.onchange();
                }
                else if (typeof (elem.checked) != 'undefined')
                {
                    elem.checked = false;
                    if (elem.onclick)
                        elem.onclick();
                }
            }
        }
    }
    this.checkComplete();
}

// SubContainer class
function SubContainer(id, typeOptions, iContainerNumber)
{
    this.id = id;
    this.containerNumber = iContainerNumber;
    this.container = null;
    this.forceVisible = false;
    this.init = init;
    this.display = false;
    this.hasType = false;
    this.show = show;
    this.hide = hide;
    this.showFields = showFields;
    this.hideFields = hideFields;
    this.typeOptions = typeOptions;
    this.inputFields = null;
    this.inputTypeElem = null;
    this.inputTypeElemName = '';
    this.reinitializeTypes = reinitializeTypes;
    this.inputElements = new Hashtable();
    this.isCompleted = isCompleted;
    this.setComplete = setComplete;
    this.initItems = initItems;
    this.resetInput = resetInput;
    this.initSubcontainerItems = initSubcontainerItems;
    this.setEnabledAll = setEnabledAll;
    this.setEnabled = setEnabled;
    this.triggerElement = null;  //new Hashtable();
    this.triggerElementTargets = null;  //new Hashtable();
    this.checkDisableElements = checkDisableElements;

    this.init();

    function init()
    {
        this.container = document.getElementById(id);
        this.inputTypeElemName = id + '_subtype';
        this.inputTypeElem = document.getElementById(this.inputTypeElemName);
        this.inputFields = document.getElementById(id + '_inputfields');

        if (!this.inputFields) throw ('Error: Init SubContainer. ' + id + '_inputfields not found!');
        this.inputTypeElem != null ? this.hasType = true : this.hasType = false;
        if (!this.container)
        {
            throw ('Error: SubContainer ' + id + ' not found!');
        }
        else
        {
            if (this.container.style.display == 'block') //STV: funktioniert nur wenn style attribut explizit auf 'block' gesetzt wird, ansonsten ist die Property ein Leestring
                this.display = true;
        }
    }

    // new
    function initSubcontainerItems(aItemIDs, prefix, aSubcontainerTrigger, aSubcontainerTriggerTargets)
    {
        if ((typeof (aSubcontainerTrigger) != 'undefined') && (typeof (aSubcontainerTriggerTargets) != 'undefined'))
        {
            if ((aSubcontainerTrigger.length == 2) && (aSubcontainerTriggerTargets.length > 0)) 
            {
                if (this.triggerElement == null)
                {
                    this.triggerElement = new Hashtable();
                    this.triggerElement.setItem(prefix + '_' + aSubcontainerTrigger[0], aSubcontainerTrigger[1]); // trigger ElementID, ausgewählte Value bei dem der Trigger ausgelöst wird
                }
                if (this.triggerElementTargets == null)
                    this.triggerElementTargets = new Hashtable();


                // jedes Element, das für den Trigger ausgeblendet werden soll:
                var j = 0;
                var aTmp = new Array(); 
                for (j ; j < aSubcontainerTriggerTargets.length; j++)
                {
                    aTmp[j] = prefix + '_' + aSubcontainerTriggerTargets[j];
                    //alert(j + ': ' + aTmp[j]);
                }
                this.triggerElementTargets.setItem(prefix + '_' + aSubcontainerTrigger[0], aTmp);
            }
        }
        for (var i = 0; i < aItemIDs.length; i++)
        {
            var elemID = prefix + '_' + aItemIDs[i];
            var elem = document.getElementById(elemID);
            //if (prefix == 'contact1')
            //    alert(elemID + ' -> ' + elem.value + ' | ' + 'Type -> ' + elem.type + ' | ' + 'Checked -> ' + elem.checked);
            if (elem)
            {
                var elemCompleted = false;
                if(elem.type == 'text')
                {
                    if (elem.value.toString() == '')
                        elemCompleted = false;
                    else
                        elemCompleted = true;
                }
                else if (typeof (elem.checked) != 'undefined') 
                {
                    elemCompleted = elem.checked;
                }
                else if (typeof (elem.value) != 'undefined')
                {
                    elemCompleted = (elem.value != null && elem.value != '');
                }
                else
                {
                    // alert(elemID + ' -> else?!?');
                }
                if (elem.type == 'radio') // Radiobuttons immer false 
                {
                    elemCompleted = false;
                }
                this.inputElements.setItem(elemID, elemCompleted);
            }
        }
        //this.checkComplete();
    }

    // old
    function initItems(aItemIDs)
    {
        for (var i = 0; i < aItemIDs.length; i++)
        {
            var elemID = aItemIDs[i];
            var elem = document.getElementById(elemID);
            if (elem)
            {
                var elemCompleted = false;
                if (elem.type == 'text') 
                {
                    if (elem.value.toString() == '')
                        elemCompleted = false;
                    else
                        elemCompleted = true;
                }
                else if (typeof (elem.checked) != 'undefined')
                {
                    elemCompleted = elem.checked;
                }
                else if (typeof (elem.value) != 'undefined')
                {
                    elemCompleted = (elem.value != null && elem.value.toString() != '' && elem.value.toString() != 'false');
                }
                else
                {
                    // alert(elemID + ' -> else?!?')
                }
                if (elem.type == 'radio') // Radiobuttons immer false 
                {
                    elemCompleted = false;
                }

                this.inputElements.setItem(elemID, elemCompleted);
            }
        }
        //this.checkComplete();
    }

    function setEnabledAll(blnEnable)
    {
        for (var key in this.inputElements.items) 
        {
            setEnabled(key, blnEnable)
        } 
    }
    function setEnabled(itemID, blnEnable)
    {
        var elem = document.getElementById(itemID);
        if(elem)
        {
            elem.disabled = (blnEnable ? false : true);
        }
    }

    function setComplete(inputElementID, elementValue)
    {
        if (this.inputElements.hasItem(inputElementID))
        {
            if (elementValue == '')
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == undefined)
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == null)
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == 0) // sonst wird bei elementValue == false der Int 0 in false konvertiert
                this.inputElements.setItem(inputElementID, true);
            else if (elementValue == false)
                this.inputElements.setItem(inputElementID, false);
            else if (elementValue == true)
                this.inputElements.setItem(inputElementID, true);
            else
                this.inputElements.setItem(inputElementID, true);

            this.checkDisableElements(inputElementID);
        }
    }
    function checkDisableElements(checkInputElementID) 
    {
        if ((this.triggerElement == null) || (this.triggerElementTargets == null))
            return;

        if (!this.triggerElement.hasItem(checkInputElementID))
            return;

        if (!this.triggerElementTargets.hasItem(checkInputElementID))
            return;

        var elemTrigger = document.getElementById(checkInputElementID);
        if (elemTrigger) 
        {
            var triggerValue = this.triggerElement.getItem(checkInputElementID).toString();
            var aTriggerTargets = this.triggerElementTargets.getItem(checkInputElementID);
            // alert(checkInputElementID + ' | ' + triggerValue + ' | ' + aTriggerTargets);
            if (typeof (aTriggerTargets) != 'object')
                return;

            var enable = false;

            if (elemTrigger.value.toString() != triggerValue) 
            {
                enable = true;
            }

            for (var i = 0; i < aTriggerTargets.length; i++) 
            {
                this.setEnabled(aTriggerTargets[i], enable);
            }
        }
    }

    function isCompleted()
    {
        var completed = true;
        for (var key in this.inputElements.items)
        {
//            if(key.indexOf('car1_') >= 0)
//                alert(key + ' = ' + this.inputElements.getItem(key));
            if (this.inputElements.getItem(key) == false)
            {
                completed = false;
                break;
            }
        }
        // alert(this.id + ' completed: ' + completed);
        return completed;
    }

    function resetInput()
    {
        for (var key in this.inputElements.items)
        {
            var elem = document.getElementById(key);
            //alert(elem);
            if (elem)
            {
                if (typeof (elem.type) != 'undefined')
                {
                    if ((elem.type == 'text') || (elem.type == 'password'))
                    {
                        elem.value = '';
                        if (elem.onblur)
                            elem.onblur();
                    }
                    else if (elem.type == 'checkbox')
                    {
                        elem.checked = false;
                        if (elem.onclick)
                            elem.onclick();
                    }
                    else if (elem.type == 'radio')
                    {
                        elem.checked = false;
                        if (elem.onclick)
                            elem.onclick();
                    }
                    if (typeof (elem.selectedIndex) != 'undefined')
                    {
                        elem.selectedIndex = 0;
                        if (elem.onchange)
                            elem.onchange();
                    }
                }
                else if (typeof (elem.selectedIndex) != 'undefined')
                {
                    elem.selectedIndex = -1;
                    if (elem.onchange)
                        elem.onchange();
                }
                else if (typeof (elem.checked) != 'undefined')
                {
                    elem.checked = false;
                    if (elem.onclick)
                        elem.onclick();
                }
            }
        }
    }

    function show()
    {
        this.container.style.display = 'block';
        this.display = true;
    }

    function showFields()
    {
        this.inputFields.style.display = 'block';
    }

    function hide()
    {
        if (this.forceVisible || this.containerNumner == 1) // Dropdown vom 1. Container niemals verstecken
            return;
        this.container.style.display = 'none';
        this.display = false;
    }

    function hideFields()
    {
        if (this.forceVisible)
            return;
        this.inputFields.style.display = 'none';
    }

    // usedTypes delimited by ;
    function reinitializeTypes(usedTypes)
    {
        var types = usedTypes.split(';');
        var optionExists = false;
        var optionSelected = false;
        var optionUsed = false;
        var optionHandled = false;
        var currTypeElemOption = null;
        var currTypeOption = null;

        // alle vorgegebenen Typen prüfen
        for (var i = 0; i < this.typeOptions.length; i++)
        {
            currTypeOption = this.typeOptions[i];
            optionExists = false;
            optionSelected = false;
            optionUsed = false;
            optionHandled = false;
            if (usedTypes.indexOf(currTypeOption.value) >= 0) optionUsed = true;
            //den vorgegebenen Typ in der Combo box suchen
            for (var j = 0; j < this.inputTypeElem.options.length; j++)
            {
                currTypeElemOption = this.inputTypeElem.options[j];
                if (currTypeElemOption.value == currTypeOption.value)
                {
                    if (currTypeElemOption.value == currTypeOption.value) optionExists = true;
                    if (currTypeElemOption.selected == true) optionSelected = true;
                    if (optionExists && optionUsed && !optionSelected)
                    {
                        this.inputTypeElem.options[j] = null;
                        optionHandled = true;
                    }
                }
            }
            if (!optionExists && !optionUsed) this.inputTypeElem.options[this.inputTypeElem.options.length] = new Option(currTypeOption.text, currTypeOption.value, false, false);
        }
    }
}

/* car container */

function SelectMake()
{
    SelectMake(null);
}
function SelectModel()
{
    SelectModel(null);
}

function SelectMake(carNumber)
{
    carNumber = (carNumber == null ? '' : carNumber);
    var carMake = document.getElementById('car' + carNumber + '_make');
    var carModel = document.getElementById('car' + carNumber + '_model');
    var carType = document.getElementById('car' + carNumber + '_type');
    carModel.length = 1;
    if(carType != null)
        carType.length = 1;
    carModel.selectedIndex = 0;
    if (carType != null)
        carType.selectedIndex = 0
    if (carMake.selectedIndex == 0)
    {
        return;
    }
    models = carlist[carMake.selectedIndex][1];
    for (count = 1; count != models.length; count++)
    {
        newModel = new Option(models[count][0], models[count][0], false, true);
        carModel.options[carModel.length] = newModel;
    }
    carModel.selectedIndex = 0;
}
function SelectModel(carNumber)
{
    carNumber = (carNumber == null ? '' : carNumber);
    var carMake = document.getElementById('car' + carNumber + '_make');
    var carModel = document.getElementById('car' + carNumber + '_model');
    var carType = document.getElementById('car' + carNumber + '_type');
    if (carType == null)
        return;

    carType.length = 1;
    carType.selectedIndex = 0;
    if (carMake.selectedIndex == 0)
        return;
    if (carModel.selectedIndex == 0)
        return;
    models = carlist[carMake.selectedIndex][1];
    types = models[carModel.selectedIndex][1];
    for (count = 1; count != types.length; count++)
    {
        newType = new Option(types[count], types[count], false, true);
        carType.options[carType.length] = newType;
    }
    carType.selectedIndex = 0;
}

/*  END: SSO Optimierung                                       */
/***************************************************************/