var async = true;

function callFunctions(input)
{
    if(typeof(input) == "object")
    {
        for(var function_to_call in input)
        {
            try
            {
                var params = input[function_to_call];
                if(typeof(params) == "object")
                {
                    switch(function_to_call)
                    {
                        case "defaultEventHandler":
                            defaultEventHandler(params);
                        break;

                        case "setSelected":
                            for(var i = 0 ; i < params.length ; i++)
                            {
                                setSelected(params[i]);
                            }
                        break;

                        case "hideHierarchyArrows":
                            hideHierarchyArrows(params);
                        break;


                        default:
                           throw function_to_call+" wurde nicht in loadFunctions definiert";
                        break;
                    }
                }
                else
                {
                    throw "Der Parameter von "+function_to_call+" ist kein Objekt.";
                }
            }
            catch(error)
            {
                alert(error.toString());
            }
        }
    }
};

/**
 * Wandelt eine ID in eine fuer jquery lesbare Form um ([ in \\[, ] in \\])
 * Achtung, der ID-identifier # wird noch vor den ouput gesetzt
 */
function jqid(myid)
{
    return '#'+myid.replace(/\[/g,"\\[").replace(/\]/g,"\\]");
};

function jqclass(myid)
{
    return '.'+myid.replace(/\[/g,"\\[").replace(/\]/g,"\\]");
};

var NOT_SELECTED  = -2;
var NOT_SPECIFIED = -1;
/**
 * Funktionen für Ajax
 */
/**
 * uebermittelt ajax die selektierten items der selectbox
 * @param String el_id, [ID der Selectbox]
 * @params String function_name [abweichende Funktion]
 * @params Int return_type [Datentyp der zurückgeliefert werden soll]
 */
function setSelected(el_id, function_name, return_type, change)
{
    var el = document.getElementById(el_id);
    if(!el)
    {
        //console.log('Das Element '+el_id+' ist nicht vorhanden');
        return;
    }
    var cnt = el.options.length;

    var ids = "";
    if(!function_name)
    {
        function_name = 'setValues';
    }

    if(!change)
    {
        change = false;
    }

    for(i = 0; i < cnt; i++)
    {
        if(el.options[i].selected)
        {
            ids += (ids.length == 0 ? el.options[i].value:","+el.options[i].value);
        }
    }

    if(ids.length == 0)
    {
        ids = NOT_SELECTED;
    }

    var data = "function="+function_name+"&element_id="+el_id+"&ids="+ids;
    if(!return_type)
    {
        var return_type = 2;
    }
    sendRequest(data, return_type, change);
};

/**
 * Übermittelt ajax den eingegebenen Suchstring
 *
 * @params String el_id [Id des Zielelementes]
 * @params Object obj [Das Element, das den Suchstring liefert]
 * @params String function_name [alternativ abweichende Funktion]
 * @params Int return_type [Datentyp der zurückgeliefert werden soll]
 */
function getValues(el_id, obj, function_name, return_type, change)
{
    var value = obj.value;
    if(obj.getAttribute("field"))
    	field = obj.getAttribute("field");

	if(obj.id)
	{
	    field = obj.id;
	}
    if(!field)
    {
        return;
    }

    if(!change)
    {
        change = false;
    }

    if(!function_name)
    {
        function_name = 'getValues';
    }

    var data  = "element_id="+el_id+"&function="+function_name;
	data += "&field="+field+"&value="+encodeURIComponent(value);
    if(!return_type)
    {
        var return_type = 2;
    }
	sendRequest(data, return_type, change);
};

function saveTags()
{
    var value = $(jqid('tags')).val();
    var object_id = $("input[name='tag_dialog[object_id]']").getValue();
    var object_type = $("input[name='tag_dialog[object_type]']").getValue();
    var data  = "function=saveTags&value="+encodeURIComponent(value)+"&element_id="+object_id+"&field="+object_type;
	sendRequest(data, 42);
}

/**
 * Erzeugt einen Ajax-Request um ein oder mehrere Ajaxelemente zu löschen
 *
 * @author Martin Kluge <m.kluge@ipark.media.de>
 * @params Array source_id [Array mit den zu löschenden Elementen]
 */
function deleteAjaxElements(source_id)
{
    var data = "function=deleteElements&source_id="+source_id;
    sendRequest(data, 2);
}


/**
 * Funktionen zur Bearbeitung von DIVs
 */
/**
 * loescht den div-container mit der uebergebenen id
 * und ggf. auch das dazugehoerende hidden-Feld
 *
 * Diese Funktion loescht rekursiv auch alle Childs
 *
 * @author Martin Kluge
 * @param String id [id des div-container]
 * @param bool delete_ajax_elements [Sollen auch Ajaxelemente gelöscht werden]
*/
function delDiv(id, delete_ajax_elements)
{
    var div, parent, last, primary, hidden, child_block;

    div = document.getElementById(id);
    if(div == null)
    {
        return false;
    }

    parent = div.parentNode;

    // Lies das letzte Element der ID aus
    last = id.substring(id.lastIndexOf('[')+1, id.lastIndexOf(']'));

    // Wenn last keine Zahl ist, bilde daraus den PK, wenn doch lies den PK aus der Id aus
    if(isNaN(parseInt(last)))
    {
        primary = last+'_id';
    }
    else
    {
        primary = getPrimary(id);
    }
    // Die Id mit angehaengtem PK ergibt die Bezeichnung des hidden-Feldes
    hidden = id+'['+primary+']';

    // Durchlaufe alle Childs des DIV-Containers
    for(var i = 0 ; i < div.childNodes.length ; i++)
    {
        child_block = div.childNodes[i];

       // Wenn das Child ein Div ist und die ID des parent in seiner ID vorkommt, dann
        // ist es auch ein logisches Kind
        if(child_block['id'] && child_block.nodeName == 'DIV' && child_block.getAttribute('id').indexOf(id) != -1)
        {
            // loesche rekursiv die Childs des DIV-Containers
            delDiv(child_block.getAttribute('id'));

            // Wenn ein Div geloescht wurde, den Zaehler verringern, da sich die Anzahl der
            // Childs auch um 1 verringert hat.
            i--;
        }
    }

    // Loeschen des hidden-field
    var form = document.forms.form;
    if(form[hidden] != undefined)
    {
        form.removeChild(form[hidden]);
    }

    // Das Div erst ganz zum Schluss loeschen, wegen der verschachtelten Struktur
    parent.removeChild(div);

    if(delete_ajax_elements && delete_ajax_elements == true)
    {
        deleteAjaxElements(new Array(id));
    }
};

/**
 * Löscht das letzte Element aus einer Reihe von Elementen
 *
 * Ausgewählt werden die Elemente die, die die übergebene Klasse oder Id haben
 * per default wird der Klassenselector verwendet
 *
 * @author Martin Kluge <m.kluge@ipark-media.de>
 * @param String identifier [Wert der Klasse oder Id]
 * @param Char selector [JQuery Selector für den Wert]
 */
function delLastElement(identifier, selector)
{
    if(!selector)
    {
        var selector = '.';
    }
    // Suchen der Divs nach den Übergabeparametern
    var divs = $(selector+identifier);

    // Auslesen der Anzahl - 1
    var counter = divs.length - 1;

    // Wenn mehr als ein Element vorhanden ist, dann das letzte löschen
    if(counter > 0)
    {
        delDiv(divs[counter]['id'], true);
    }
}


/**
 * Setzt die Felder eines kopierten Blockes wieder zurück und aktiviert ggf. die Elemente
 *
 * @author Martin Kluge <m.kluge@ipark-media.de>
 * @param Obj obj Der kopierte Div-Container
 **/
function resetField(obj)
{
   // Wenn es kein Option-Feld ist, Inhalte l�schen
    if(obj.value && obj.nodeName != 'INPUT' && obj.nodeName != 'OPTION')
    {
        obj.value = "";
    }
    // Wenn es ein Textfeld ist, Inhalte L�schen
    if(obj.nodeName == 'INPUT' && obj.type == 'text')
    {
        obj.value = "";
    }

    if(obj.type == 'select-one')
    {
		obj.selectedIndex = 0;
		obj.disabled      = false;
    }

    if(obj.type == 'select-multiple')
    {
        if(obj.id)
        obj.selectedIndex = -1;
        var klasse = obj.className;
        if(klasse != null && klasse.lastIndexOf('empty') != -1)
        {
            obj.options.length = 0;
        }
    }

    // Buttons aktivieren
    if(obj.type == 'button' || obj.nodeName == 'INPUT')
    {
        /*if(obj.id)
        {
            var temp = obj.id.substring(0, obj.id.lastIndexOf(']['));
            var id = parseInt(temp.substring(temp.lastIndexOf('][')+2));
            if(id > 0)
            {
                obj.disabled = false;
            }
        }
        else
        {*/
            obj.disabled = false;
        //}
    }

    // Radiobuttons deselectieren
    if(obj.type == 'radio')
    {
        obj.checked = false;
    }
    if(obj.hasChildNodes())
    {
        var cnt_childs = obj.childNodes.length;
        for(var i = 0; i < cnt_childs; i++)
        {
            var child = obj.childNodes[i];
            resetField(child);
        }
    }
};


/**
* funktion loeschen von eingabefeldern
*
* @author Martin Kluge <m.kluge@ipark-media.de>
* @param Objekt obj
* @param String value
*/
function clearInputValue(obj, value)
{
	if(obj.value == value)
	{
		obj.value = '';
	}
};

function toogleSelectBox(element_id)
{
    id = element_id.replace(/\[/g,"\\[").replace(/\]/g,"\\]");
    var element = $("."+id);
//    var options = element.options;
    var options = $("#"+id+" option");
    if(options.length > 0)
    {
        showElement(true, element);
    }
    else
    {
        showElement(false, element);
    }

}

function changeRadioGroup(element_id, group_class)
{
    id = element_id.replace(/\[/g,"\\[").replace(/\]/g,"\\]");
    var elements = $("."+group_class+"[id!='"+id+"'");
    //console.log('length: '+elements.length);

    var element = $("."+group_class+":checked");
    for(var i = 0 ; i < element.length ; i++)
    {
        if(element[i].id !== element_id)
        {
            element[i].checked = false
        }
    }
}


/**
* Funktion zum Kopieren von div-containern
* dabei werden eventuelle indizes heraufgezaehlt
*
* @author Martin Kluge <m.kluge@ipark-media.de>
* @param source_id 	[zu kopierender container]
* @param create_ajax_elements [Ob ein neuer Zweig eines Ajax-Tree erzeugt werden soll]
*/
function copyDiv(source_id, create_ajax_elements)
{
    async = false;
    var start_el = document.getElementById(source_id);
    if(!start_el)
    {
        return;
    }

    var parent_el = start_el.parentNode;
    if(!start_el || !parent_el)
    {
        return;
    }

    var el_div_copy = start_el.cloneNode(true);

    var cnt_div = 0;
    // Durchlaufe alle Childs, um den neuen Index zu ermitteln
    var max = 0;
    for(var i = 0 ; i < parent_el.childNodes.length ; i++)
    {
        if(parent_el.childNodes[i].nodeName == 'DIV')
        {
            var child_id = parent_el.childNodes[i].id;
            var start = child_id.lastIndexOf('[');
            var stop = child_id.lastIndexOf(']');
            var id = parseInt(child_id.substring(start+1, stop));
            if(id > max)
            {
                max = id;
            }
        }
    }
    max++;

    // loeschen von subbloecken
    deleteSubblocks(el_div_copy);

    // loeschen eventueller fehlermeldungen
    deleteErrorMessage(el_div_copy, '');

    // Ein zu kopierender Container hat immer einen Index als letztes Element der Id
    // Dieser Index, bzw. die koplette Id ist auch Teil der Ids von Kindelementen
    // sowie Event-Handler Aufrufen. Bei kopieren muß der Index der Id aktualisiert werden
    var new_source_id = source_id.substring(0, source_id.lastIndexOf('[') + 1) + max + ']';

    // escapen von []
    var escaped_source_id = source_id.replace(/\[/g,"\\[").replace(/\]/g,"\\]");

    // erzeugen des Pattern zum ersetzen
    var pattern=eval('/' + escaped_source_id + '/g');

    // ersetzen der source_id im gesammten HTML-Code
    var new_HTML = el_div_copy.innerHTML.replace(pattern, new_source_id);

    // Ersetzen des HTML-Codes
    el_div_copy.innerHTML = new_HTML;

    // Erzeugen der neuen Id für den Div-Container
    var new_id = el_div_copy.getAttribute('id').replace(pattern, new_source_id);

    // Wenn der zu kopierende Block ausgeblendet ist, dann muß der neue eingeblendet werden
    var pattern_hidden = eval('/hidden/g');
    if(el_div_copy.getAttribute('class'))
    {
    var new_class = el_div_copy.getAttribute('class').replace(pattern_hidden, '');
    el_div_copy.setAttribute('class', new_class);
    }

    // Setzen der neuen Id des Div-Containers
    el_div_copy.setAttribute('id', new_id);
    // Zurücksetzen der Formularfelder
    resetField(el_div_copy)

    // kopierten container einfuegen
    parent_el.appendChild(el_div_copy);
    if(create_ajax_elements)
    {
        var data = "function=createRegisteredElements&source_id="+source_id+"&counter="+max;
        sendRequest(data, 2);
    }

    // es gibt Elemente, bei denen nach dem Kopieren, noch bestimmte
    // clean up Funktionen aufgerufen werden müssen

    // der Datepicker wird nicht ausgelöst, wenn hasDatepicker 
    // schon vorher gesetzt ist
    $(jqid(el_div_copy.id) + " .datepicker").removeClass("hasDatepicker");

    return el_div_copy;
}

/**
* Loeschen von Childs eines DIV-Containers
*
* Dabei werden ausser dem ersten Child alle weiteren Childs geloescht
* damit immer nur eine Formularzeile im neuen Element existiert
* die einzelnen Childs werde rekursiv durchlaufen
*
* @author Martin Kluge <m.kluge@ipark-media.de>
* @param object element
**/
function deleteSubblocks(element)
{
    if(element.id)
    {
        for(var i = 0 ; i < element.childNodes.length ; i++)
        {
            // Nur wenn das Child ein Div und ein logisches Kind des Parent ist,
            // soll dieses bearbeitet werden das bedeutet das die ID im eine Komponente ergänzt wurde
            if(element.childNodes[i]['id'] && element.childNodes[i].nodeName == 'DIV' &&
               element.childNodes[i].getAttribute('id').indexOf(element.getAttribute('id')) == 0)
            {
                var child_block = element.childNodes[i];
                var first = true;
                var length = child_block.childNodes.length;
                for(var j = 0 ; j < child_block.childNodes.length ; j++)
                {
                    if(child_block.childNodes[j].nodeName == 'DIV')
                    {
                        // Das erste Element soll bestehen bleiben daher werden nur die
                        // Childs geloescht
                        if(first == true)
                        {
                            deleteSubblocks(child_block.childNodes[j]);
                            first = false;
                        }
                        // alle weiteren Elemente werden geloescht
                        else
                        {
                            child_block.removeChild(child_block.childNodes[j]);
                            // Wenn ein Div geloescht wurde, den Zaehler verringern, da sich die Anzahl der
                            // Childs auch um 1 verringert hat.
                            j--;
                        }
                    }
                }
            }
        }
    }
}

function emptySelectFields(class_name)
{
    var obj = $(jqclass(class_name));
    for(var i = 0 ; i < obj.length ; i++)
    {
        var select = obj[i];
        select.options.length = 0;
    }
}

/**
* loeschen von fehlermeldungen bei pflichtfeldern
*
* Dabei werden die Childs rekursiv durchlaufen
*
* @author Martin Kluge <m.kluge@ipark-media.de>
* @param obj [zu behandelndes objekt]
*/
function deleteErrorMessage(obj)
{
	for(var i = 0 ; i < obj.childNodes.length ; i++)
	{
		var child = obj.childNodes[i];
		if(child.hasChildNodes())
		{
			deleteErrorMessage(child);
		}
	}
	if(obj.getAttribute('class') == 'error')
	{
		var parent = obj.parentNode;
		// das folgende <br> wird zuerst geloescht
		parent.removeChild(obj.nextSibling);
		parent.removeChild(obj);
	}
};


var selOptAr = new Object;
function getSelectedFieldsJQ(element_id)
{
	if(selOptAr[element_id] && selOptAr[element_id].length > 0)
	{
	    return;
	}

	selOptAr[element_id] = new Array();
    $(jqid(element_id)+' option: selected').each(function()
    {
        if(this.value != 0)
        {
            selOptAr[element_id].push(this.value);
        }
    });
};


function setSelectedFields(obj)
{
	id = obj.id;
	if(!selOptAr[id])
		return;

    for(var i = 0; i < obj.options.length; i++)
    {
        for(var j = 0; j < selOptAr[id].length; j++)
        {
            if(obj.options[i].value == selOptAr[id][j])
            {
                obj.options[i].selected = true;
                if(obj.type == "select-one")
                {
                	selOptAr[id] = new Array();
                	return;
                }
			}
         }
    }
    selOptAr[id] = new Array();
};



/**
 * Funktionen für Formularfunktionalitäten
 */


/**
 * Default Routine zur Behandlung von Formular-Events.
 *
 * Dem Eventhander wird ein Array aus Abhängigkeiten übergeben, die bestimmen welche
 * Werte mit welchen verglichen werden sollen. Dabei können die Werte aus einem
 * Formularfeld kommen oder statisch a übergeben werden. Ausserdem werden die
 * Zielelemente und die auszuführende Funktion übergeben.
 *
 * @param Array params
 *  source    String [ID des Source-Elementes von dem die Daten kommen]
 *  dest      Array  [Die Keys sind die möglichen JQuery Selektoren (id,class,element)]
 *  value     Array  [Fixe Werte die verglichen werden sollen]
 *  equal     Array  [Werte die auf Gleichheit überprüft werden sollen]
 *  not_equal Array  [Werte die auf Ungleicheit geprüft werden sollen]
 *  additionals Array [Wenn der Wert aufgeteilt werden muss]
 *  func      String [Funktion die im Erfolgsfall aufgerufen werden soll]
 */
function defaultEventHandler(params)
{
    // Durchlauf der einzelnen Abhängigkeiten
    for(var i = 0 ; i < params.length ; i++)
    {
        var input = params[i];
        var destination = input['dest'];
        var func = input['func'];
        var equal = new Array;

        // Unterscheidung ob die Werte aus einem Formularfeld ausgelesen werden sollen
        // oder ob übergebene Werte verwendet werden sollen
        if(input['source'] && !input['value'] && !input['checked'])
        {
            // Wenn die Werte aus dem Formular kommen sollen, das entsprechende Feld
            // auslesen
            var value = $(jqid(input['source'])).val();
            // Wenn der Wert eine zusammengesetzte Zeichenkette ist, dann werden die
            // Parameter zum Auslesen als additionals übergeben.
            if(input['additionals'])
            {
                // Splitten des Wertes
                var data = value.split(input['additionals']['seperator']);

                // Übergabe des benötigten Wertes
                value = data[input['additionals']['counter']]
            }
        }
        else if(input['source'] && input['checked'])
        {
            // Werte von Checkbox werden verarbeitet
            if ($(jqid(input['source'])+':checked').val() == 1)
            {
            	var value = 'true';
            }
            else
            {
            	var value = 'false';
            }
        }
        else
        {
            // Wenn fixe Werte übergeben wurden, dann diese verwenden
            var value = input['value'];
        }

        //console.log(input['value']);

       // Wenn die Vegleichswerte als not_equal übergeben werden, wird die
        // Vergleichsvariable auf false gesetzt,
        if(input['not_equal'])
        {
            var compare = input['not_equal'];
            equal = false;
        }
        else if(input['equal'])
        {
            // nsonsten wird die Vergleichsvariable auf true gesetzt
            var compare = input['equal'];
            equal = true;
        }

        // Wenn einige der benötigten Parameter kein Array sind, wird eines erstellt
        if(typeof(compare) != 'object')
        {
            compare = new Array(compare);
        }
        if(typeof(destination) != 'object')
        {
            destination = new Array(destination);
        }

        if(value == null || typeof(value) != 'object')
        {
            value = new Array(value);
        }

        // Den Erfolgsfall auf false setzen
		var hit = valid = false;

		// Durchlauf der ausgewählten Werte
		for(var value_counter = 0 ; value_counter < value.length ; value_counter++)
		{
			// Durchlauf der einzelnen Vergleichswerte
			for(var counter_compare = 0 ; counter_compare < compare.length ; counter_compare++)
			{
				// Vergleichen der aktuellen Werte, im Erlogsfall wird hit auf true gesetzt
			    if(value[value_counter] != null &&
			       (compare[counter_compare] == value[value_counter] ||
			       compare[counter_compare] == '*'))
				{
					hit = true;
				}
			}
		}

		// Wenn es eine Übereinstimmung gab dann wird das Event verarbeitet
		if((equal == false && hit == false) ||
		   (equal == true && hit == true))
		{
		    valid = true;
		}
		// Durchlauf der einzelnen Typen aus dem dest-Array
		for(var type in destination)
		{
			var dest = destination[type];
			switch(type)
			{
				case "id":
					selector = '#';
				  break;

				case "class":
					selector = '.';
				  break;

				case "element":
					selector = '';
				  break;
			}

			// Durchlauf der einzelnen Elemente pro Typ
			for(var dc = 0 ; dc < dest.length ; dc++)
			{

				object = dest[dc].replace(/\[/g,"\\[").replace(/\]/g,"\\]");
				obj = $(selector+object);
			    switch(func)
				{
					case 'showElement':
						showElement(valid, obj);
					  break;

					case 'hideElement':
						hideElement(valid, obj);
					  break;

					case 'disableElement':
						disableElement(valid, obj);
					  break;

					case 'resetField':
						if(valid == true)
						{
							switch(type)
							{
								case "id":
									var divs = document.getElementById(dest[dc]);
								  break;

								case "class":
									var divs = getElementsByClassName(dest[dc]);
								  break;
							}
							if(typeof(divs) != 'object')
							{
								divs = new Array(divs);
							}
							for(var index in divs)
							{
								resetField(divs[index]);
							}
						}
					  break;

					  case 'setSelected':
                            var data = "function=setValues&element_id="+dest[dc]+"&ids="+valid;
                            sendRequest(data, 2);
					  break;

					  case 'submit':
					       if(valid == true)
					       {
					           document.form.submit();
					       }
					  break;

					  case 'block':
						  $.blockUI.defaults.applyPlatformOpacityRules = false;
						  if(valid)
					      {
                              obj.block({message: null});
					      }
					  break;

					  case 'unblock':
						  if(valid)
					      {
                              obj.unblock();
					      }
					  break;

                      case 'updateWithSameData':
                          if(valid)
					      {
                              obj.val(value);
					      }
                      break;
				}
			}
		}
    }
};


/**
 * Ausblenden von selectBoxen, wenn keine options vorhanden
 *
 * Wenn eine Selectbox die Daten per Ajax bekommt, kann es vorkommen das keine Optionen
 * vorhanden sind. In diesem Fall sollen die entsprechenden Divs ausgeblendet werden.
 * Dieses erfolgt im Normalfall durch ein Event des Elternelements. Beim kopieren
 * von Blöcken kann bei einer AMS jedoch kein Event ausgelöst werden. Daher müssen die
 * entsprechenden Boxen manuell überprüft werden.
 *
 * @author Martin Kluge <m.kluge@ipark-media.de>
 * @param String obj
 */
function checkSelectVisiblity(class_name)
{
    var elements = $('.'+class_name);
    for(var ec = 0 ; ec < elements.length ; ec++)
    {
        if(elements[ec].options.length == 0)
        {
            var id = elements[ec].getAttribute('id')+'_div';
            var id = id.replace(/\[/g,"\\[").replace(/\]/g,"\\]");
            var div = $('#'+id);
            div.hide();
        }
    }
};


/**
 * Funktion zum Auslesen sämtlicher Element einer bestimmten Klasse
 *
 * Diese Funktion macht eigentlich das selbe wie folgender Aufruf:
 * $('.'+class_name);
 * jedoch wird hier mich ein JQuery Objekt übergeben, sonder ein Array aus
 * HtmlObjekten. Nötig ist diese Funktion, da resetFields() noch nicht auf JQuery
 * umgestellt wurde
 *
 * @param String class_name [Klassenname]
 */
function getElementsByClassName(class_name)
{
  var all_obj,ret_obj=new Array(),j=0,teststr;

  if(document.all)
  {
      all_obj = document.all;
  }
  else if(document.getElementsByTagName && !document.all)
  {
      all_obj = document.getElementsByTagName("*");
  }


  for(i=0;i<all_obj.length;i++)
  {
    if(all_obj[i].className.indexOf(class_name)!=-1)
    {
      teststr=","+all_obj[i].className.split(" ").join(",")+",";
      if(teststr.indexOf(","+class_name+",")!=-1)
      {
        ret_obj[j]=all_obj[i];
        j++;
      }
    }
  }
  return ret_obj;
}


/**
* liefert aus der uebergebenen Id die PK Bezeichnung des Objektes zurueck
*
* @author Martin Kluge <m.kluge@ipark-media.de>
* @param String id
* @return String
**/
function getPrimary(id)
{
    var start, stop, substring;

    stop = id.lastIndexOf('][');
    // Wenn es kein Block ist dann gibt es nur eine Ebene
    if(stop != -1)
    {
        substring = id.substring(0, stop);
        start = substring.lastIndexOf('[');
    }
    else
    {
        stop = id.lastIndexOf('[');
        start = -1;
    }
    return id.substring(start+1, stop)+'_id';
}

/**
 * Zeigt ein Objekt an oder versteckt es
 *
 * @author Martin Kluge <m.kluge@ipark-media.de>
 * @param bool show
 * @param Object obj [Objekt, das bearbeitet werden soll]
 */
function showElement(show, obj)
{
    if(show == true)
    {
        obj.show();
    }
    else
    {
        obj.hide();
    }
}

function hideElement(hide, obj)
{
    if(hide == true)
    {
        obj.hide();
    }
}

/**
 * Disabled ein Objekt oder enabled es
 *
 * @author Martin Kluge <m.kluge@ipark-media.de>
 * @param bool disable
 * @param Object obj [Objekt, das bearbeitet werden soll]
 */
function disableElement(disable, obj)
{
    if(disable == true)
    {
        obj.attr("disabled", 'true');
    }
    else
    {
        obj.removeAttr('disabled');
    }
}


/**
 * Counter-Funktion fuer SMS-Formular
 *
 * @return  boolean  whether pointer is set or not
 */
function wordCount(max_length, total_max_length)
{
    //alert(document.form.elements['sms[sms_message]']);
    var sms_message = document.form.elements['sms[sms_message]'];

    //Behandlung der Sonderzeichen, die doppelt gezaehlt werden
    var extra = 0;
    for(i = 0; i < sms_message.value.length; i++)
    {
        s = sms_message.value.charCodeAt(i);

        //Behandlung der Sonderzeichen
        if((s > 32 && s < 48) || (s > 57 && s < 65) || (s > 90 && s < 97) || (s > 123))
        {
            extra++;
        }
    }

    if(sms_message.value.length > max_length)
    {
        sms_message.value = sms_message.value.substring(0,max_length);
    }

    document.form.elements['sms[counter]'].value = max_length - sms_message.value.length - extra;

    // Länge der Absenderkennung
    var laenge_absender = total_max_length - max_length;

    document.form.elements['sms[num_sms]'].value = Math.ceil((laenge_absender + sms_message.value.length) / 160);
};


/**
 * Baut eine Hierarchie von aufeinander aufbauenden Selectboxen
 *
 * Wenn selected != 0, lösche alles unter mir und führe ein copyDiv aus
 * Wenn selected == 0, lösche alle unter mir
*/
function buildHierarchy(source_id, selectbox_id_postfix)
{
    // hole das Level auf dem die event-auslösende Box liegt
    var level = source_id.substring(source_id.lastIndexOf('[') + 1, source_id.length - 1);
    // suche den root-path zur event-auslösenden Box
    var root = source_id.substring(0, source_id.lastIndexOf('['));

    var to_delete;
    var to_delete_string;
    var found = true;
    var deleted = false;
    async = false;

    while(found)
    {
        // alle tieferen Boxen müssen gelöscht werden
        to_delete_string = root+"["+ ++level +"]";
        to_delete = $(jqid(to_delete_string));
        if(to_delete.length)
        {
            to_delete.remove();
            if(!deleted)
            {
                // lösche auch in der Ajax-Session
                var data = "function=deleteElements&source_id="+to_delete_string;
                sendRequest(data, 2);
                deleted = true;
            }
        }
        else
        {
            found = false;
        }
    }

    var select_box = source_id+"["+ selectbox_id_postfix +"]"
    // wenn der Wert nicht 0 ist, soll eine neue Box erscheinen
    if($(jqid(select_box)).val() != 0)
    {
        var new_div = copyDiv(source_id, true);
        // verstecke letzten Pfeil
        $(jqid(new_div.id+"[arrow]")).hide();
        // zeige vorletzten Pfeil
        $(jqid(source_id+"[arrow]")).show();
        setSelected(select_box);
    }
    async = true;
};


/**
 * Löscht eine Hierarchie aus dem DOM und aus der Ajax-Session
 *
 */
function delHierarchy(to_delete_string)
{
    // entferne die Hierarchie
    $(jqid(to_delete_string)).remove();
    // das hidden Feld muss auch gelöscht werden, damit es keine
    to_delete_string += "[hierarchy_id]";
    to_delete_string = to_delete_string.replace(/\[/g,"\\[").replace(/\]/g,"\\]") ;
    $("[name="+to_delete_string+"]").remove();
    // lösche auch in der Ajax-Session
    var data = "function=deleteElements&source_id="+to_delete_string;
    sendRequest(data, 2);
};


/**
 * Kopiert eine komplette Hierarchie und blendet den letzten Pfeil aus
 */
function copyHierarchy(source_id)
{
    var new_div = copyDiv(source_id, true);
    // verstecke letzten Pfeil
    $(jqid(new_div.id)+" .hierarchy_arrow").hide();
};


/**
 * Blendet alle überflüssigen Pfeile in den Hierarchies aus
 */
function hideHierarchyArrows(params)
{
    $.each(params, function(key, value)
    {
        $(jqid(value+"[arrow]")).hide();
    });

};


/**
 * Blendet die Update-Selectboxen im Import ein und aus
 */
function toggleUpdateCheck(param)
{
    if($(jqid(param.id)+' option:selected').val() == '1')
    {
        $('.update_check').attr('checked', false);
        $('.update_check').attr('disabled', 'disabled');
    }
    else
    {
        $('.update_check').attr('disabled', '');
    }
};


function setValue(value, name)
{
    var element = document.getElementsByName(name)[0];
    if(value == true)
    {
        element.value = 1;
    }
    else
    {
        element.value = 0;
    }
}

function changeSelectValues()
{
    var start_el = document.getElementById('workflow_message[0]');
    if(!start_el)
    {
        return;
    }

    var parent_el = start_el.parentNode;
    if(!start_el || !parent_el)
    {
        return;
    }
    var max = 0;
    for(var i = 0 ; i < parent_el.childNodes.length ; i++)
    {
        if(parent_el.childNodes[i].nodeName == 'DIV')
        {
            var child_id = parent_el.childNodes[i].id;
            var start = child_id.lastIndexOf('[');
            var stop = child_id.lastIndexOf(']');
            var id = parseInt(child_id.substring(start+1, stop));
            if(id > max)
            {
                max = id;
            }
        }
    }
    var element = $(jqid('workflow_message['+max+'][dispatch_type]')+' option');
    $(jqid('workflow_message['+max+'][dispatch_type]')+' option').remove();
    $(jqid('workflow_message['+max+'][dispatch_type]')).append('<option value="4">nach Vorgänger</option>')
    $(jqid('workflow_message['+max+'][send_type]')).change();
    $(jqid('workflow_message['+max+'][dispatch_type]')).change();
}
