/**
 * General purpose event constructor.
 * Allows multiple event handlers to listen for the event.
 *
 * @return  void
 */
function CustomEvent() {
	// list of registered event handlers
	this._handlers = [];
} // end: function CustomEvent

/**
 * Register a callback function for the event (function name is also allowed).
 * Optionally an object can be passed which will be the object the function
 * is applied on.
 * If the callback function returns `false` (means 'interrupt') then the
 * remaining callback functions will not be called.
 *
 * @param   function|string  function   The event handling callback function.
 * @param   obj              object     The object the callback function shall
 *                                      be applied on.
 * @return  void
 */
CustomEvent.prototype.addHandler = function(func, obj) {
	if (typeof func == 'string') {
		func = window[func];
	} // end: if

	if (!obj) {
		obj = null;
	} // end: if

	if (typeof func == 'function') {
		this._handlers.push([func, obj]);
	} // end: if
}; // end: function CustomEvent.prototype.addHandler

/**
 * Trigger the event. Pass any arguments you like. Will passed to the
 * event handlers.
 *
 * @param   *                *          Variable list of arguments.
 *                                      be applied on.
 * @return  null|false                  Returns `false` if any event handler
 *                                      has interrupted the process, otherwise `null`.
 */
CustomEvent.prototype.trigger = function(_someArgs_) {
	var retVal = null;

	// Call each registered handler.
	for (var i = 0; i < this._handlers.length;  ++i) {
		var handler = this._handlers[i];
		var func = handler[0];
		var obj = handler[1];

		// Interrupt on return value `false`.
		if (func.apply(obj, arguments) === false) {
			retVal = false;
			break;
		} // end: if
	} // end: if

	return retVal;
}; // end: function CustomEvent.prototype.trigger

/**
 * Returns an array of the names of all own properties of a given object,
 * without the properties inherited from its prototype.
 *
 * @param   object  obj  Object in question
 * @return  array
 */
function getOwnProperties(obj) {
	var returnValue = [];

	if (obj) {
		for (var prop in obj) {
			if (obj.hasOwnProperty(prop)) {
				returnValue.push(prop);
			} // end: if
		} // end: for
	} // end: if

	return returnValue;
} // end: function getOwnProperties

/**
 * Converts a value to an integer value.
 * If the value is numeric then its rounded value will be returned, otherwise 0.
 *
 * @param   mixed  val  Value in question
 * @return  integer
 */
function toInteger(val) {
	var returnValue = Math.round(val);

	if (isNaN(returnValue) || !isFinite(returnValue)) {
		returnValue = 0;
	} // end: if

	return returnValue;
} // end: function toInteger

/**
 * Converts a value to an integer value or null if not numeric.
 * If the value is numeric then its rounded value will be returned, otherwise null.
 *
 * @param   mixed  val  Value in question
 * @return  integer
 */
function toIntegerOrNull(val) {
	var returnValue = Math.round(val);

	if (isNaN(returnValue) || !isFinite(returnValue)) {
		returnValue = null;
	} // end: if

	return returnValue;
} // end: function toIntegerOrNull

/**
 * Converts a value to an number value.
 * If the value is numeric then its number value will be returned, otherwise 0.
 *
 * @param   mixed  val  Value in question
 * @return  number
 */
function toNumber(val) {
	var returnValue = parseFloat(val);

	if (isNaN(returnValue) || !isFinite(returnValue)) {
		returnValue = 0;
	} // end: if

	return returnValue;
} // end: function toNumber

/**
 * Converts a value to an float value or null if not numeric.
 * If the value is numeric then its number value will be returned, otherwise null.
 *
 * @param   mixed  val  Value in question
 * @return  number
 */
function toNumberOrNull(val) {
	var returnValue = parseFloat(val);

	if (isNaN(returnValue) || !isFinite(returnValue)) {
		returnValue = null;
	} // end: if

	return returnValue;
} // end: function toNumberOrNull

/**
* toggles a image between two states
* call like this: onMouseOver="gfxToogle(this, 'active.gif', 'inactive.gif')" onMouseOut="gfxToogle(this, 'active.gif', 'inactive.gif')"
* image paths and current state are determined automatically.
*
* @access	public
* @param	object		gfx			a DOM object with a .src parameter
* @param	string		active		the filename (no path!) to the active-state image
* @param	string		inactive	the filename (no path!) to the inactive-state image
* @return	void
*/
function gfxToggle(gfx, active, inactive) {

	if (typeof gfx == 'object' && gfx.src) {

		var matches = gfx.src.match(/^(.*)\/([^\/]+)$/);

		switch (matches[2]) {
			case active:
				gfx.src = matches[1] + '/' + inactive;
				break;

			case inactive:
				gfx.src = matches[1] + '/' + active;
				break;

			default:
		} /* end: switch */
	} /* end: if */
}

/**
* toggles visibility of an object
* call like this:
* // for making an object visible
* showHideObject('objctId', true)
*
* // for making an object invisible
* showHideObject('objctId', false)
*
* // for making an object flexible to a checkbox
* // if checkbox checked than show else hide
* <input type="checkbox" onChange="showHideObject('objctId', this.checked)">
*
* @access	public
* @param	string		objectid	of the element to be shown or hidden
* @param	boolean		visibility	of the element to be shown or hidden
* @return	void
*/
function showHideObject(objId, visibility) {

	if (objId) {
		var object = document.getElementById(objId);

		if (object) {

			switch (visibility) {
				case false:
					object.style.visibility = 'hidden';
					object.style.display = 'none';
					break;

				case true:
					object.style.visibility = 'visible';
					object.style.display = 'block';
					break;
			} // end: switch

		} /* end: if */


	} /* end: if */
}
/**
 *	Function to skip some inputs automatically
 *
*/
function nextField(e, source, dest, fieldlen) {
 	if (!e) var e = window.event;

 	// Keine Controlchars
 	if (e.keyCode > 32)
 	{
 		if (source.value.length == fieldlen)
 		{
 			dest.value='';
 			dest.focus();
 		}
 	}
} //function

/**
 *	Function to reset forms
 *
*/
function resetForm(url) {
	window.location.href=url;
}

/**
 * Function to open a layer window containing an iframe
 * that loads a given URL.
 * One and only argument is a property object that contains
 * all properties necessary to build the layer window.
 *
 * Allowed properties are:
 * - url: The URL to load in iframe.
 * - width: Width of the iframe.
 * - height: Height of the iframe.
 * - left: Left position of the layer window.
 * - top: Top position of the layer window.
 * - textClose: Text that shall be shown with the link that closes the layer.
 * - scrollable: Script that indicates whether iframe shall be scrollable.
 * - className: CSS class name of the layer window.
 * - id: ID of the layer window.
 * - onlyOncePerSession: Flag that indicates that this layer window will be
 *                       only once per browser session. If cookies are disabled
 *                       the layer window won't be opened.
 *
 * @param  object  props  Properties of layer window
 */
function openLayerWindow(props) {
	if (typeof props == 'object' && props.url && document.body && document.createElement) {
		// Read attribute from object 'props'.
		var url = props.url;
		var id = props.id;
		var width = parseInt(props.width);
		var height = parseInt(props.height);
		var left = parseInt(props.left);
		var top = parseInt(props.top);
		var textClose = props.textClose;
		var className = props.className;
		var scrollable = !!props.scrollable;
		var onlyOncePerSession = !!props.onlyOncePerSession;

		// Normalize attributes.
		if (typeof id != 'string') {
			id = '';
		} // end: if

		if (typeof textClose != 'string') {
			textClose = '';
		} // end: if

		if (isNaN(width) || width <= 0) {
			width = 400;
		} // end: if

		if (isNaN(height) || height <= 0) {
			height = 300;
		} // end: if

		if (isNaN(left) || left < 0) {
			left = 40;
		} // end: if

		if (isNaN(top) || top < 0) {
			top = 30;
		} // end: if

		if (typeof className != 'string') {
			className = 'layerWindow';
		} // end: if

		// Check whether layer window shall really been shown depending
		// on cookies.
		var showWindow = true;

		if (onlyOncePerSession) {
			if (!navigator.cookieEnabled) {
				showWindow = false;
			} else {
				var cookieName = 'layerWindowHasAlreadyBeenOpened';

				if (id !== '') {
					cookieName += '_' + id;
				} // end: if

				if (document.cookie.indexOf(cookieName + '=true') >= 0) {
					showWindow = false;
				} // end: if
			} // end: if
		} // end: if

		if (showWindow) {
			if (onlyOncePerSession) {
				document.cookie = cookieName + '=true';
			} // end: if

			// Create necessary DOM elements and build layer window.
			var container = document.createElement('div');
			container.style.display = 'none';
			container.id = id;
			container.className = className;
			container.style.position = 'absolute';
			container.style.left = left + 'px';
			container.style.top = top + 'px';

			var pane = document.createElement('div');
			pane.className = className + '_pane';
			container.appendChild(pane);

			var content = document.createElement('div');
			content.className = className + '_content';
			pane.appendChild(content);

			var header = document.createElement('div');
			header.className = className + '_header';
			content.appendChild(header);

			var closeLink = document.createElement('a');
			closeLink.href = '#';
			closeLink.className = className + '_closeLink';
			closeLink.innerHTML = textClose;
			closeLink.style.display = 'block';
			header.appendChild(closeLink);

			closeLink.onclick = function() {
				document.body.removeChild(container);
			} // end: if

			var iframe = document.createElement('iframe');
			iframe.src = url;
			iframe.className = className + '_iframe';
			iframe.frameBorder = '0';
			iframe.marginWidth = '0';
			iframe.marginHeight = '0';
			iframe.style.border = 'none';
			iframe.style.width = width + 'px';
			iframe.style.height = height + 'px';
			iframe.scrolling = (scrollable ? 'yes' : 'no');

			// Show layer window as soon as iframe has loaded.
			iframe.onload = iframe.onreadystatechange = function() {
				if (!iframe.readyState || iframe.readyState == 'complete') {
					container.style.display = 'block';
				} // end: if
			} // end: if

			content.appendChild(iframe);

			// Append layer window delayed to body to prevent freezing.
			setTimeout(function() {
				document.body.appendChild(container);
			}, 0);
		} // end: if
	} // end: if
} // end: function openLayerWindow

/**
 * Add Javascript behavior for collabsable containers (containing header and
 * content DOM element - where content element will be shown or hidden).
 *
 * Argument 'props' is an property object with the following props:
 *   - selectorContainer: jQuery selector for the container box
 *   - selectorHeader: jQuery selector for the header element within the container box
 *   - selectorContent: jQuery selector for the content element within the container box
 *   - classForOpenState: CSS class for the container box if expanded
 *   - classForClosedState: CSS class for the container box if collapsed
 */
function automatizeBoxToggling(props) {
	var $ = jQuery;

	$(function() {
		// Read css selectors for involved DOM elements from argument 'props'.
		var selectorContainer = $.trim(props.selectorContainer);
		var selectorHeader = $.trim(props.selectorHeader);
		var selectorContent = $.trim(props.selectorContent);

		// Read classes for open and close state of container DOM element.
		var classForOpenState = $.trim(props.classForOpenState);
		var classForClosedState = $.trim(props.classForClosedState);

		if (selectorContainer !== '' && selectorHeader !== '' && selectorContent !== '') {
			var containers = $(selectorContainer);

			// Finds out whether a container is collapsed or expanded, sets
			// display style properly and updates CSS class names.
			// If second argument 'toggle' is true then the visibility of the
			// container will be toggled.
			function updateContainer(container, toggle) {
				var content = container.find(selectorContent);
				var hide = (content.css('display') == 'none'
						|| container.hasClass(classForClosedState));

				if (toggle) {
					hide = !hide;
				} // end: if

				if (hide) {
					content.slideUp();
					container.removeClass(classForOpenState);
					container.addClass(classForClosedState);
				} else {
					content.slideDown();
					container.removeClass(classForClosedState);
					container.addClass(classForOpenState);
				} // end: if
			} // end: local function updateContainer

			// Updated container content visibility and add Javascript
			// event handlers for box toggling.
			containers.each(function(index, elem) {
				var container = $(elem);
				var header = container.find(selectorHeader);
				var content = container.find(selectorContent);
				updateContainer(container);
				header.click(function() {updateContainer(container, true)});
			});
		} // end: if
	});
} // end function: automatizeBoxToggling

// --- Direct logic  -----------------------------------------------------------

// Suppress multiple submits on forms.
// To enable this functionality assign the form CSS class 'singleSubmitForm'
// and make sure that the form is NOT submitted via Javascript's
// form.submit function without event onsubmit being involved.
if (typeof jQuery == 'function') {
	jQuery(function() {
		var $ = jQuery;

		// Callback function of onsubmit event that ensures that form can only
		// be submitted once.
		var doOnSubmit = function() {
			var returnValue = null;

			if ($(this).hasClass('formAlreadySubmitted')) {
				returnValue = false;
			} else {
				$(this).addClass('formAlreadySubmitted');
			} // end: if

			return returnValue;
		} // end: local function doOnSubmit

    	$('form.singleSubmitForm').submit(doOnSubmit);
	});
}

// Make info boxes collapsable for selected brands.
if (window.config && config.brandId == 7) {
	automatizeBoxToggling({
			selectorContainer: '.infobox',
			selectorHeader: 'h1',
			selectorContent: 'p',
			classForOpenState: 'open',
			classForClosedState: 'close'
		});
} // end: if

/**
 * Function to find out the type of the popup window
 * a) if its created normally using 'window.open', close window by using 'window.close'
 * b) if is created by thickbox, close the thickbox iframe.
 */
function closeWindow() {
	if (window.opener) {
		// Close the normal popup window.
		window.close();
	} else if (parent && typeof parent.tb_remove == 'function') {
		// Close the thickbox.
		parent.tb_remove();
	} // end: if

	return true;
} // end function: closeWindow

/**
 * Functions from former functions.js
 */

function toggle(obj, imgpath) {

  	obj.src = imgpath;
}


// Main navigation with hover effect for subcategories
function sfHover() {
	var navi = document.getElementById("sfNavi");

	if (navi) {
		var sfEls = document.getElementById("sfNavi").getElementsByTagName("LI");

	    for (var i=0; i<sfEls.length; i++) {
			sfEls[i].onmouseover=function() {
				this.className+=" sfhover";
			}

			sfEls[i].onmouseout=function() {
				this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
			}
		}
	}
}


if (window.attachEvent) window.attachEvent("onload", sfHover);


/**
 * Hide/show specific form fields based on the selection of salutation
 *
 * Case - 1: Show div which has form fields 'Company' & 'Contact Person' upon the selection of "Company" as salutation
 * 			 and hide div which contains form fields 'Firstname' & 'Lastname'
 *
 * Case - 2: For other than 'Company',  show div which contains form fields 'Firstname' & 'Lastname'
 * 			 and hide div which has form fields 'Company' & 'Contact Person' upon the selection of "Company"
 */
if (typeof jQuery == 'function') {
	jQuery(function() {
		var $ = jQuery;

		var updateSalutationDivs = function() {
			var isInitialCall = (arguments.length == 0);

			// select salutation element from the form and identify specific divs
			$('select[id^=salutation]').each(function(id, fieldSalutation) {
				// strip the identifier (get rid of leading 'salutation').
				var identifier = fieldSalutation.id.substr(10);

				// select involved DOM elements
				var divPerson = $('#formFieldsForPerson' + identifier);
				var divCompany = $('#formFieldsForCompany' + identifier);

				var divCompany2 = $('#formFieldsForCompany2' + identifier);
				var divBirthday = $('#formFieldsForBirthday' + identifier);

				var fieldTitle 		= divPerson.find("[name$='[title]']");
				var fieldFirstName 	= divPerson.find("[name$='[firstname]']");
				var fieldLastName 	= divPerson.find("[name$='[lastname]']");

				var fieldCompany 		= divCompany.find("[name$='[company]']");
				var fieldContactPerson 	= divCompany.find('[id^=address2]');

				var fieldDay 	= divBirthday.find('[id^=birthday0]');
				var fieldMonth 	= divBirthday.find('[id^=birthday1]');
				var fieldYear 	= divBirthday.find('[id^=birthday2]');

				// for the case, that the address2 field is not in the divCompany div
				if (fieldContactPerson.size() == 0 && identifier !== '') {
					fieldContactPerson = $('#address2' + identifier);
				} // end: if

				// div size validity
				if (divPerson.size() > 0 && divCompany.size() > 0
						&& fieldFirstName.size() > 0 && fieldLastName.size() > 0
						&& fieldCompany.size() > 0 && fieldContactPerson.size() > 0) {
					// variable to remember user-entered state of hidden
					// text fields
					var oldValCompany = fieldCompany.val();
					var oldValContactPerson = '';
					var oldValContactPersonCompany = fieldContactPerson.val();
					var oldValTitle = fieldTitle.val();
					var oldValFirstName = fieldFirstName.val();
					var oldValLastName = fieldLastName.val();
					var oldValDay = fieldDay.val();
					var oldValMonth = fieldMonth.val();
					var oldValYear = fieldYear.val();

					// show salutation specific divs depending whether
					// salutation is company (= 5) or not
					// and clear value of fields 'lastname' and 'contactperson'
					// if necessary
					if (fieldSalutation.value == 5) {
						if (!isInitialCall) {
							oldValContactPerson = fieldContactPerson.val();

							fieldCompany.val(oldValCompany);
							// Fill contact person with current last name
							fieldContactPerson.val(oldValLastName);

							oldValTitle = fieldTitle.val();
							oldValFirstName = fieldFirstName.val();
							oldValLastName = fieldLastName.val();
							oldValDay = fieldDay.val();
							oldValMonth = fieldMonth.val();
							oldValYear = fieldYear.val();
						} // end: if

						// show/hide divs, clear hidden fields
						fieldTitle.val('');
						fieldLastName.val('');
						fieldFirstName.val('');
						fieldDay.val('');
						fieldMonth.val('');
						fieldYear.val('');
						divPerson.hide();

						divBirthday.hide();
						divCompany.show();

						if (divCompany2) {
							divCompany2.show();
						}

					} else {
						if (!isInitialCall) {
							oldValContactPersonCompany = fieldContactPerson.val();
							fieldTitle.val(oldValTitle);
							fieldFirstName.val(oldValFirstName);
							// Fill last name with current contact person
							fieldLastName.val( (oldValLastName == '') ? oldValContactPersonCompany : oldValLastName );
							fieldDay.val(oldValDay);
							fieldMonth.val(oldValMonth);
							fieldYear.val(oldValYear);
							oldValCompany = fieldCompany.val();
							fieldContactPerson.val(oldValContactPerson);
						} // end: if

						// show/hide divs, clear hidden fields
						// at the shipaddr there is the contactperson for
						// company and person. so we don't have to clear it.
						fieldCompany.val('');
						if (identifier != '_shipaddr') {
							fieldContactPerson.val('');
						}

						divCompany.hide();
						divPerson.show();
						divBirthday.show();

						if (divCompany2) {
							divCompany2.hide();
						}
					} // end: if
				}

				// hide or show specific form fields based on the selection of salutation
				if(isInitialCall) {
					$(fieldSalutation).change(updateSalutationDivs);
				}
			});
		}

		//initial loading of salutation specific form fields
		updateSalutationDivs();
	});
}

function toggleFrame5LinesWithMoreLink(openerElement) {
	// get the frame container
	var container = $(openerElement).parents('.frame5LinesWithMoreLink');
	var cLink = container.children('.opener').find('a');
	var linkNames = cLink.attr('rel').split('_'); //[0]=more [1]=close
	// show full text
	if (cLink.html() == linkNames[0]){
		container.children('.hide').removeAttr('class');
	}else{
		container.children('div:first').attr('class','hide');
	}
	// change button
	cLink.html(cLink.html() == linkNames[0] ? linkNames[1] : linkNames[0]);
}

// functions for Toggle in/out Typo3 Content
$(document).ready(function() {
	// add hover event
	$('.toggleContentMoreBefore').hover(
    function() {
        $(this).css('cursor', 'pointer');
    },
    function() {
        $(this).css('cursor', 'default');
    }
	);
	// add click event
	$('.toggleContentMoreBefore').click( function() {
		var linkNames = $(this).attr('rel').split('_'); //[0]=more [1]=close
		$(this).html($(this).html() == linkNames[0] ? linkNames[1] : linkNames[0]);
		$(this).parents('div:eq(0)').find('.frame103ToggleContent').slideToggle("normal");
	});
});


