/*
 * EnableCondition - jQuery plugin 1.0.0
 *
 * Copyright (c) 2009 Squins
 */

;(function($) {
    $.fn.extend({
    	handleEnableCondition: function() {
            return this.each(function() {
                new $.EnableConditionHandler(this);
            });
        }
    });
    
    $.EnableConditionHandler = function (element) {
    	// Create variable
    	var element;
    	
    	// Check condition
    	var condition = $("object.enableCondition > param", $(element))[0].value;
    	
    	// Register to every event and run it on the load of the page
		$(document).bind(($.browser.msie ? "click" : "change"), function(event) {
			handleEnableCondition(condition);
    	});	
    	handleEnableCondition(condition);
    	
    	// Handle the condition
    	function handleEnableCondition(aCondition) {
    		if (evaluateEnableCondition(aCondition)) {
    		    
    			if (element.tagName.toLowerCase() == "div" && $(element).hasClass("group") && $(element).parents("div.group_collection").length > 0) {
					$(element).enableTab();
    			} else {
    			    $(element).css("display", "block");
    			}
			} else {
			    if (element.tagName.toLowerCase() == "div" && $(element).hasClass("group") && $(element).parents("div.group_collection").length > 0) {
                    $(element).disableTab();
                } else {
                    $(element).css("display", "none");
                }
			}
    	}
    	
    	// Evaluate the condition
    	function evaluateEnableCondition(aCondition) {
    		var aCondition;
    		
    		// Check if the string is stackable
    		if (substr_count(aCondition, "(") == substr_count(aCondition, ")")) {
    			
    			// If non brackets are present, the string is easy to split
    			// Example: a AND b
    			if (substr_count(aCondition, "(") === 0) {
    				if (aCondition.indexOf(" AND ") == -1 && aCondition.indexOf(" OR ") == -1) {
    					return evaluateCondition(aCondition);
    				} else {
    					return splitCondition(aCondition);
    				}
    			} else {
    		        // All brackets are on the outside
    		        // Example: (a AND b)
    				characterCount = substr_count(aCondition, "(");
    				allOpenCharactersAtStart = (aCondition.substr(0, characterCount) == str_repeat("(", characterCount));
    				allCloseCharactersAtEnd = (aCondition.substr(aCondition.length-characterCount, characterCount) == str_repeat(")", characterCount));
    				if (allOpenCharactersAtStart && allCloseCharactersAtEnd) {
    					aCondition = aCondition.substr(characterCount, aCondition.length-characterCount-1);
    					return evaluateEnableCondition(aCondition);
    					
       				// Not all brackets are on the outside
    				} else {
    		            // If the first character is not an openCharacter, it can
    		            // be split normally
    		            // Example: a AND (b OR c)
    					if (aCondition.indexOf("(") !== 0) {
    						return splitCondition(aCondition);
    						
						// If the first character is an openCharacter, the
		                // string should be checked
		                // Example: (a AND b) OR c
		                // Example: (a AND (b OR c))
		                // Example: (a AND b) OR (c AND d)	
    					} else {
    		                // Find out the lowest level; with a AND b the lowest
    		                // level is 0, with (a AND b), the lowest level is 1,
    		                // with (a AND (b AND c)) the lowest level is still 1,
    		                // etc.
    						var lowestLevel = false;
    						var currentLevel = 1;
    						for(var i=0; i<aCondition.length; i++) {
    							if (aCondition[i] == "(" && i>0) {
    								currentLevel++;
    							} else if (aCondition[i] == ")") {
    								currentLevel--;
    							} else if (lowestLevel === false && i>0) {
    								lowestLevel = currentLevel;
    								var firstLowestLevelPosition = i
    							} else {
    								if (currentLevel < lowestLevel) {
    									firstLowestLevelPosition = i;
    								}
    								if (currentLevel < lowestLevel) {
    									lowestLevel = currentLevel;
    								}
    							}
    						}
    						
    		                // If $lowestLevel > 0, there are excess open and close
    		                // characters, so they should be stripped
    		                if (lowestLevel > 0) {
    		                    aCondition = aCondition.substr(lowestLevel, aCondition.length-lowestLevel-1);
    		                    firstLowestLevelPosition -= lowestLevel;
    		                }
    		                return splitCondition(aCondition, firstLowestLevelPosition);
    					}
    				}
    			}
    		} else {
    			alert("Not stackable; number of open-characters and close-characters are not equal")
    		}
    	}
    	
    	// Split the condition
    	function splitCondition(aCondition, anOffset) {
    		var aCondition;
    		if (anOffset != undefined) {
    			var firstAnd = aCondition.indexOf(" AND ", anOffset);
    			var firstOr = aCondition.indexOf(" OR ", anOffset);
    		} else {
    			var firstAnd = aCondition.indexOf(" AND ");
    			var firstOr = aCondition.indexOf(" OR "); 			
    		}
    		
    		if (firstAnd == -1) {
    			var splitOperator = " OR ";
    		} else if (firstOr == -1) {
    			var splitOperator = " AND ";
    		} else {
    			if (firstAnd < firstOr) {
    				var splitOperator = " AND ";	
    			} else {
    				var splitOperator = " OR ";    				
    			}
    		}
    		if(anOffset == undefined) {
    		    anOffset = 0;
    		}
    		var nonSplitable = aCondition.substring(0, anOffset);
    		var splitable = aCondition.substring(anOffset);
    		var left = nonSplitable+splitable.substr(0, splitable.indexOf(splitOperator));
    		var right = splitable.substr(splitable.indexOf(splitOperator)+splitOperator.length);
    		
    		if (splitOperator == " AND ") {
    			return (evaluateEnableCondition(left) && evaluateEnableCondition(right));
    		} else {
    			return (evaluateEnableCondition(left) || evaluateEnableCondition(right));
    		}
    	}
    	
    	// Evaluate condition
    	function evaluateCondition(aCondition) {
    		var aCondition;
    		var regex = /([a-z0-9_]+)=\'([a-z0-9\-_\\', ]+)\'/i;
    		var result = aCondition.match(regex);
    		if ($("[name='"+result[1]+"']").length > 0) {
    		    if ($("[name='"+result[1]+"']")[0].tagName == "INPUT" && $("[name='"+result[1]+"']")[0].type == "radio") {
    		        return (escapeValue($("input[name='"+result[1]+"']:checked").val()) == result[2]);
    		    } else {
    		        return (escapeValue($("#"+result[1]).val()) == result[2]);    
    		    }
    		}
    	}
    	
    	function escapeValue(aString) {
    	    aString = aString.replace("\\", "\\\\");
    	    aString = aString.replace("'", "\\'");
    	    return aString;
    	}
    };
})(jQuery);

/**
 * SQUINS Find all fields with the enableCondition and apply it
 */
$(document).ready(function() {
    function addEnableConditions(context) {
        $("div.enableCondition:not(.enableCondition-enabled)", context.getElement()).each(function() {
            // Add a class to prevent duplicate execution
            $(this).addClass("enableCondition-enabled");

            // Handle the EnableCondition
            $(this).handleEnableCondition();
        });
    }
    PageRequest.addOnPageStructureChangeEvent(addEnableConditions);
});

