/**
 * function to toggle the disabled state of a text input field
 * requirements:
 * 		the element to be toggled, needs to have the same id of the container for the checkbox
 * 		suffixed by "Text"
 * see /solutionsplus/fields-tag.xhtml for usage
 * @param element
 */
function toggleTextfield(elmObject) {
	var elmId = elmObject.id;
	var removeIndex = elmId.indexOf("Text",0);
	var baseId = elmId.substr(0,elmId.length-2);
	var textId = baseId+"Text";
	var textInputElm = document.getElementById(textId);
	var checkboxElm = document.getElementById(baseId);
	if(elmObject.value == "Andere") {
		if(textInputElm.disabled == false) {
			textInputElm.disabled = true;
		} else {
			textInputElm.disabled=false;
		}
	}
}

/**
 * function to toggle open/closed state of navigation / filter elements in sidebar (blue header, grey listbox)
 * requirements:
 * 		the element to be toggled needs to have an ID "sidebarNavContent"+contentName parameter
 * 		the element to trigger the movement needs to have an ID "triggerSidbarNav"+contentName parameter
 * 		the images representing the toggle trigger are
 * 			/r/images/solutionsplus/sidebar/btn_sidebarnav_open.png
 * 			/r/images/solutionsplus/sidebar/btn_sidebarnav_close.png
 * 
 * see product_details_layout.xhtml for example use
 * 
 * @contentName defines the ID of the content to be toggled and of the trigger arrow to toggle
 */
function toggleSidebarList(contentName) {
	var listElmId = 'sidebarNavContent'+contentName;
	var triggerElmId = 'triggerSidebarNav'+contentName;
	var listElm = document.getElementById(listElmId);
	var triggerElm = document.getElementById(triggerElmId);
	if(listElm.style.display == 'block') {
		jQuery(listElm).slideUp(400, "linear");
		triggerElm.src = '/r/images/solutionsplus/sidebar/btn_sidebarnav_open.png';
	} else {
		jQuery(listElm).slideDown(400, "linear");
		triggerElm.src = '/r/images/solutionsplus/sidebar/btn_sidebarnav_close.png';
	}
}

/** function to open the next possible filter box
 * in display advisor, function is called oncomplete of each onchange ajax request
 * necessary since filter criteria vary depending on selected advisor category
 * 
 * retrieves all known sideNavContents
 * (since function is called oncomplete of request, new boxes are already known in dom)
 * 
 * @param callerName name of calling element to specify ID
 */
function openNextFilterBox(callerName, alreadySelected) {
	var listElementsArray = getElementsByIdSubstring('sidebarNavContent', 'div', 'sidebarNavContent');
	var triggerElementsArray = getElementsByIdSubstring('sideBarNavBtn', 'img', 'triggerSidebarNav');
	var lastIdx = listElementsArray.size()-1;
	var lastTriggerIdx = triggerElementsArray.size()-1;
	var currentName = listElementsArray[lastIdx].id.replace("sidebarNavContent", "");
	
	if (lastIdx - 2 >= 0 && currentName != callerName && alreadySelected == 'false') {
		jQuery(listElementsArray[lastIdx - 2]).css("display", "block");
		jQuery(listElementsArray[lastIdx - 2]).slideUp(400, "linear");
	}
	
	if (currentName == callerName || alreadySelected == 'true') {
		jQuery(listElementsArray[lastIdx]).css("display", "block");
	} else {
		jQuery(listElementsArray[lastIdx]).slideDown(400, "linear");
	}
	jQuery(listElementsArray[lastIdx - 1]).css("display", "block");
	triggerElementsArray[lastTriggerIdx].src = '/r/images/solutionsplus/sidebar/btn_sidebarnav_close.png';
	triggerElementsArray[lastTriggerIdx - 1].src = '/r/images/solutionsplus/sidebar/btn_sidebarnav_close.png';
}

/** function to set a filter box specified by caller name visible
 * since showBox is called on the last visible box, no effect is used
 * otherwise effect would be doubled
 * 
 * @param callerName name of calling element to specifiy ID
 */
function showBox(callerName) {
	var listElmId = 'sidebarNavContent'+callerName;
	var triggerElmId = 'triggerSidebarNav'+callerName;
	var listElm = document.getElementById(listElmId);
	var triggerElm = document.getElementById(triggerElmId);
	jQuery(listElm).removeClass("sidebarNavContent");
	jQuery(listElm).addClass("sidebarNavContentVisible");
	listElm.style.display = 'block';
	triggerElm.src = '/r/images/solutionsplus/sidebar/btn_sidebarnav_close.png';
}

/**
 * function to toggle open/closed state of box in content (plain box, no header)
 * requirements:
 * 		element to be toggled needs to have an ID "toggleContent"+contentName parameter and styleClass "toggleContent" or "toggleContentOverlay"
 * 		element to trigger the movement needs to have an ID "triggerArrow"+contentName parameter
 * 	
 * element to be toggled is retrieved by getElementsByIdSubstring since elements within richfaces have their ID altered
 * 
 * @contentName defines the ID of the container to be toggled and trigger arrow ID
 */
function toggleContentBox(contentName) {
	var toggleElmId = 'toggleContent'+contentName;
	var triggerElmId = 'triggerArrow'+contentName;
	var toggleElm = document.getElementById(toggleElmId);
	var triggerElm = document.getElementById(triggerElmId);
	if(toggleElm == null) {
		var elementsArray = getElementsByIdSubstring('toggleContent', 'div', contentName);
		if(elementsArray.size() < 1) {
			elementsArray = getElementsByIdSubstring('toggleContentOverlay', 'div', contentName);
			toggleElm = elementsArray[0];
		} else {
			toggleElm = elementsArray[0];
		}
	}
	if(toggleElm.style.display == 'block') {
		jQuery(toggleElm).slideUp(400, "linear");
		triggerElm.src = '/r/images/interface/openPanel.png';
	} else {
		jQuery(toggleElm).slideDown(400, "linear");
		triggerElm.src = '/r/images/interface/closePanel.png';
	}
}


function showProductFeaturesTooltip(contentUrl, elementID) {
	var tipElement = document.getElementById(elementID);
	new Tip(tipElement,  {
		ajax: {
			url: contentUrl
		},
		stem: 'topLeft',
		offset: { x: 0, y: 15 },
		style: 'lightgrey',
		width: 190
	});
}


/** --------------------- tooltip functions --------------------- **/
/**
 * Method adds a tooltip to given element
 * 
 * @param element required param which contains either the object itself or the id of the object to which the tooltip should be added
 * @param text the string value which should be shown within the tooltip, may be null if contentId is given instead
 * @param contentId the id of one object, whose (innerHTML) content should be shown within the tooltip
 * @style styleclass to be used for tooltip
 * 
 * 	contentId should be used as alternative to the text parameter, if there is more tooltip content needed than a simple String value.
 * 	If both parameters 'text' and 'contentId' are not null, the value of the contentId object (if it exists) is preferred to the text value.
 *  If the element to which the tooltip should be added and/or the text which should be shown aren't existing, no tooltip is created.
 */
function addTooltip(element, text, contentId, style) {
  if ((style == null) || (style == '')) {
	  style = 'lightgrey';
  }
  if (element.tagName == undefined) {
	  element = document.getElementById(element);
  }
  if ((contentId != null) && (contentId != '')) {
	var content = document.getElementById(contentId);
	if (content) {
	  text = content.innerHTML;
	}
  }
  if ((element != null) && (text != null) && (text != '')) {
	new Tip(element, text, {
	  style: style
	});
  }
}


/**
 * Automatically closes open tooltips on mouse click.
 */
document.observe('click', function() { Tips.hideAll(); });


/**
 * Shows an ajax toolip. Must be called in the "onmouseup"-eventhandler
 * of a node, and you MUST return false at the end of the call, so that
 * call should look like this:
 *
 * <img class="toggleAjaxPrototip" onmouseup="showAjaxTooltip('#{productOverlayUrl}', this.id); return false;" id="prototip#{tableIdentifier}#{i}" src="..." style="vertical-align: middle;padding-right: 5px;" />
 *
 * @param ajaxURI the URI to load the AJAX data from
 * @param the element to add the prototip
 * @return
 */
function showAjaxTooltip(ajaxURI, elementID) {
	var element = document.getElementById(elementID);

	if (!element.tip) {
		addAjaxPrototip(element, ajaxURI, 'lightgreySwitching');
	}
}


/**
 * Makes the given element having an AJAX driven prototip. If you
 * wanna use it "automatically", use the <img />-tag as described
 * in the initAjaxPrototips() method above!
 *
 * @param element the element to set an ajax tooltip for
 * @param contentUrl the (ajax request) URL to obtain the tooltip content from
 * @param style the prototip-style to be used
 * @return nothing
 */
function addAjaxPrototip(element, contentUrl, style) {
	if ((style == null) || (style == '')) {
		style = 'lightgrey';
	}
	if (element.tagName == undefined) {
		element = document.getElementById(element);
	}

	if ((element != null) && (contentUrl != null) && (contentUrl != '')) {
		element.canBeShown = false;

		element.tip = new Tip(element, {
			ajax: {
				url: contentUrl
			},
			style: style
		});

		prepareAjaxTooltipTarget(element, element.tip.wrapper);

	}
}

/**
 * Shows an ajax toolip. Must be called in the "onmouseup"-eventhandler
 * of a node, and you MUST return false at the end of the call, so that
 * call should look like this:
 *
 * <span class="toggleAjaxPrototip" onmouseup="showAjaxTooltip('#{productOverlayUrl}', this.id); return false;" id="spanID" >keyword</span>
 *
 * @param ajaxURI the URI to load the AJAX data from
 * @param the element to add the prototip
 * @return
 */
function showSimpleAjaxTooltip(ajaxURI, elementID, style) {
	var element = document.getElementById(elementID);

	if (!element.tip) {
		addSimpleAjaxPrototip(element, ajaxURI, style);
	}
}

/**
 * Makes the given element having an AJAX driven prototip.
 *
 * @param element the element to set an ajax tooltip for
 * @param contentUrl the (ajax request) URL to obtain the tooltip content from
 * @param style the prototip-style to be used
 * @return nothing
 */
function addSimpleAjaxPrototip(element, contentUrl, style) {
	if ((style == null) || (style == '')) {
		style = 'lightgreyClickable';
	}

	if (element.tagName == undefined) {
		element = document.getElementById(element);
	}

	if ((element != null) && (contentUrl != null) && (contentUrl != '')) {

		element.tip = new Tip(element, {
			ajax: {
				url: contentUrl
			},
			style: style,
			width: "400px"
		});
	}
}


/**
 * Prepares the given trigger node (the arrow to click on to open the tooltip)
 * and the tooltip node (the DIV-element prototip creates for being the tooltip)
 * so they can be animated for makeBlindUp() and makeBlindDown().
 *
 * @param triggerNode the DOM NODE of the trigger, must have unique ID
 * @param tipNode the tooltip node, normally equal to triggerNode.tip.wrapper
 *
 * @return nothing
 */
function prepareAjaxTooltipTarget(triggerNode, tipNode) {
	tipNode.id = "wrap" + triggerNode.id;
	tipNode.animationRuns = false;
	tipNode.arrow = triggerNode;

	tipNode.showR = tipNode.show;
	tipNode.hideR = tipNode.hide;

	tipNode.show = function() {
		tipNode.showR();
		tipNode.setStyle("visibility:hidden");
	}

	tipNode.hide = function() {
		if ((!tipNode.isOpened) && (tipNode.animationRuns == false)) {
			tipNode.hideR();
		}
	}

	tipNode.isOpened = false;

	triggerNode.observe('prototip:shown', function(event) {
		if (tipNode.sizeWasStored != true) {
			tipNode.originalSize = tipNode.getDimensions(tipNode);
			tipNode.sizeWasStored = true;
		}

		makeBlindDown(tipNode);
	});

	triggerNode.observe('prototip:hidden', function(event) {
		makeBlindUp(tipNode);
	});
}

/** add some own style definitions to the Prototip.Styles map */
Prototip.Styles['lightgrey'] = {
  className: 'lightgrey',
  border: 3,
  borderColor: '#e7e7e7',
  images: 'styles/lightgrey/',
  radius: 3,
  stem: { position: 'topLeft', height: 12, width: 15 },
  viewport: true,
  hideOthers: true
};

Prototip.Styles['lightgreyClickable'] = {
		  className: 'lightgrey',
		  border: 3,
		  borderColor: '#e7e7e7',
		  images: 'styles/lightgrey/',
		  radius: 3,
		  offset: { x: 5, y: 15 },
		  stem: { position: 'topLeft', height: 12, width: 15 },
		  hideOn: { element: 'closeButton', event: 'click' },
		  hideOthers: true,
		  viewport: true
		};

Prototip.Styles['lightgreyClickable400'] = {
		  className: 'lightgrey',
		  border: 3,
		  borderColor: '#e7e7e7',
		  images: 'styles/lightgrey/',
		  width: '400px',
		  radius: 3,
		  offset: { x: 5, y: 15 },
		  stem: { position: 'topLeft', height: 12, width: 15 },
		  hideOn: { element: 'closeButton', event: 'click' },
		  hideOthers: true,
		  viewport: true
		};

Prototip.Styles['lightgreySwitching'] = {
		  className: 'transparent',
		  border: 0,
		  borderColor: 'transparent',
		  images: 'styles/lightgrey/',
		  offset: { x: -7, y: 19 },
		  fixed: true,
		  showOn: 'click',
		  hideOn: 'click',
		  hideOthers: true,
		  viewport: true
		};

Prototip.Styles['transparentDontHideOthers'] = {
		  className: 'transparent',
		  border: 0,
		  borderColor: 'transparent',
		  images: 'styles/lightgrey/',
		  radius: 0,
		  offset: { x: 10, y: 10 },
		  viewport: true
		};

Prototip.Styles['transparent'] = {
		  className: 'transparent',
		  border: 0,
		  borderColor: 'transparent',
		  images: 'styles/lightgrey/',
		  radius: 0,
		  offset: { x: 10, y: 10 },
		  hideOthers: true,
		  viewport: true
		};

Prototip.Styles['smartTagTooltip'] = {
		  className: 'lightgrey',
		  border: 3,
		  borderColor: '#e7e7e7',
		  images: 'styles/lightgrey/',
		  radius: 3,
		  offset: { x: 5, y: 15 },
		  stem: { position: 'topLeft', height: 12, width: 15 },
		  hideOn: { element: 'closeButton', event: 'click' },
		  hideOthers: true,
		  viewport: true,
		  fixed: true
		};
/** end of own style definitions for Prototip.Styles map */
/** --------------------- END Tooltip Functions -------------------------------------- */

/** --------------------- basic helper functions --------------------- **/
/**
	function to get elements defined by a specific class attribute
	params:
		className = class name attribute
		tag = elements to be checked (use "*" to check all)
		node = node container to be checked (use "document" to check full page)
		subCheck = boolean deciding between a full match or partial match
*/
function getElementsByClass(className, tag, node, subCheck) {
	var matchingElements = new Array();
	if(node != 'document') {
		node = document.getElementById(node);
	} else {
		node = document;
	}
	var elements = node.getElementsByTagName(tag);
	for(var i=0;i<elements.length;i++) {
		var item = elements.item(i);
		var itemClass = item.className;
		if(subCheck == true) {
			if(itemClass.indexOf(className,0) >= 0) {
				matchingElements.push(elements[i]);
			}
		} else {
			if(itemClass == className) {
				matchingElements.push(elements[i]);
			}
		}
	}
	return matchingElements;
}

/**
 * function to get elements defined by tag and a substring of the ID
 * useful if the tags are not standard but richfaces elements,
 * rf sometimes adds prefixes to the defined IDs
 * 
 * retrieves all elements matching the class, checks the ID for occurence of substring
 * 
 * @param classname styleclass attribute
 * @param tag elements to be checked
 * @param substring substring in ID attribute to check
 * @return array of matching elements
 */
function getElementsByIdSubstring(classname, tag, substring) {
	var matchingElements = new Array();
	var checkElms = getElementsByClass(classname, tag, 'document');
	for(i=0;i<checkElms.size();i++) {
		var checkElm = checkElms[i];
		var testId = checkElm.id;
		if(testId.indexOf(substring,0) >= 0) {
			matchingElements.push(checkElm);
		}
	}
	return matchingElements;
}

/**
 * Splits up the given path + filename to an array
 * of size 2. Returned array contains path (including trailing slash)
 * at array[0], which can be empty in case of no leading folders,
 * and array[1] the file name. Ex: splitFilePath('gfx/bla.gif') returns
 * ['gfx/', 'bla.gif'].
 * params:
 *   path = string holding a filepath (folderpath->optional) and a 
 *   filename (mandatory)
 */
function splitFilePath(path) {
  var result = [];
  var lastSlash = path.lastIndexOf('/');
  
  if (lastSlash == -1) {
    result.push('');
  } else {
    result.push(path.substring(0, lastSlash + 1));
  }
  
  result.push(path.substring(lastSlash + 1));
  
  return result;
} // end splitFilePath(path)

/**
 * Checks whether or not the given point (x,y) with the client viewport as origin
 * is inside or outside the given element, assuming the given pixel-tolerance to
 * be applied. The 'tolerance' is the width/height in pixels in which an 'outside'
 * is assumed even if only 'tolerance' pixels away from nearst border.
 * params:
 *   x = the client viewport x-position
 *   y = the client viewport y-position
 *   element = the element node to use for inside/outside decision
 *   tolerance = the positive tolerance, 3 seems to be a good decision to handle IE7s
 *               inaccurate mouseout event positions
 */
function pointOutsideElement(x, y, element, tolerance) {
  var p = element.viewportOffset();
  var s = element.getDimensions();
  
  if ((x < (p.left + tolerance)) || (x >= (p.left + s.width - tolerance)) ||
      (y < (p.top + tolerance)) || (y >= (p.top + s.height - tolerance))) {
    return true;
  }
  
  return false;
} // end pointOutsideElement(x, y, element, tolerance)



