var configurator;
var dependencyRules = new Array();
var incompatibilityRules = new Array();
var sectionLimits = new Array();

function checkboxChange(e)
{
	var target = getEventTarget(e);
	target.name.match(/(section\d*)(Group\d+)(Product\d+)/i);	
	var id = RegExp.$1 + RegExp.$2 + RegExp.$3;
	var group = RegExp.$1 + RegExp.$2;
	var section = RegExp.$1;
	// update  price
	var selectedItemPriceNode = document.getElementById (id + 'Price');
	var selectedItemPrice = getPrice(selectedItemPriceNode);
	if(selectedItemPrice > 0 )
		selectedItemPriceNode.innerHTML = ' [subtract $' + selectedItemPrice + ']';
	else if(selectedItemPrice < 0)
		selectedItemPriceNode.innerHTML = ' [add $' + -selectedItemPrice + ']';
	updatePriceTotal(selectedItemPrice);
	updatePriceSubtotal(section, selectedItemPrice);
	// update cost 
	var selectedItemCostNode = document.getElementById (id + 'Cost');
	if(selectedItemCostNode != null)
	{
		var selectedItemCost = getPrice(selectedItemCostNode);
		if( selectedItemCost > 0 )
			selectedItemCostNode.innerHTML = ' [subtract $' + selectedItemCost + ']';
		else if(selectedItemCost < 0)
			selectedItemCostNode.innerHTML = ' [add $' + -selectedItemCost + ']';
		updateCostTotal(selectedItemCost);
		updateCostSubtotal(section, selectedItemCost);
	}
	// update summary
	var summary = document.getElementById(group + 'Summary');
	if(summary)
	{
		var descriptionNode = document.getElementById(id + 'Description');
		if(target.checked)
		{
			summary.innerHTML += descriptionNode.innerHTML + '<br />';
		}
		else
		{
			summary.innerHTML = summary.innerHTML.replace(descriptionNode.innerHTML, '').replace(/^\s*<br\s*\/?>/, "").replace(/<br\s*\/?>\s*<br\s*\/?>/, "<br \/>");
		}
	}
}

function radioChange(e)
{
	var target = getEventTarget(e);
	target.name.match(/(section\d*)(Group\d+)/i);	
	var id = RegExp.$1 + RegExp.$2;
	var section = RegExp.$1;
	//find the selected option
	var groupNode = document.getElementById(id);
	var options = groupNode.getElementsByTagName('input');
	var checkIndex = 0;
	while(options[checkIndex].checked != true)
		checkIndex++;
	// get the selected options price adjustment
	var selectedItemPriceNode = document.getElementById (id + 'Product' + options[checkIndex].value + 'Price');
	var selectedItemPrice = getPrice(selectedItemPriceNode);
	// get the selected options cost adjustment
	var selectedItemCostNode = document.getElementById (id + 'Product' + options[checkIndex].value + 'Cost');
	if(selectedItemCostNode != null)
		var selectedItemCost = getPrice(selectedItemCostNode);
    // update the total
	updatePriceTotal(selectedItemPrice);
	updatePriceSubtotal(section, selectedItemPrice);
	if(selectedItemCostNode != null)
	{
		updateCostTotal(selectedItemCost);
		updateCostSubtotal(section, selectedItemCost);
    }
	// update summary
	var summary = document.getElementById (id + 'Summary');
	var descriptionNode = document.getElementById (id + 'Product' + options[checkIndex].value + 'Description');
	if(descriptionNode && summary)
		summary.innerHTML = descriptionNode.innerHTML;
    //update option prices
	selectedItemPriceNode.innerHTML = '';
	if(selectedItemCostNode != null)
		selectedItemCostNode.innerHTML = '';
	for(i=0; i < options.length; i++)
	{
		if(i != checkIndex)
		{
		    updatePrice(id + 'Product' + options[i].value + 'Price', selectedItemPrice);
		    if (selectedItemCostNode != null) 
		    {
		        updatePrice(id + 'Product' + options[i].value + 'Cost', selectedItemCost);
		    }
		}	
	}
}

function dropdownChange(e)
{
	var target = getEventTarget(e);
	target.id.match(/(section\d*)(Group\d+)/i);	
	var id = RegExp.$1 + RegExp.$2;
	var section = RegExp.$1;
	//find the selected option
	var dropdown = document.getElementById (id + 'Select');
	var selectedItemNode = dropdown.options[dropdown.selectedIndex];

	var parts = selectedItemNode.text.split('[');
	var selectedItemPrice = 0;
	var selectedItemText = parts[0];
	if(parts[1])
	{
		selectedItemPrice = parseInt(parts[1].replace(/\D/g, ''));
		if(parts[1].search(/subtract/) >= 0)
			selectedItemPrice = -selectedItemPrice;
		if(selectedItemPrice == NaN)
			selectedItemPrice = 0;
	}
	var selectedItemCost = 0;
	if(parts[2])
	{
		selectedItemCost = parseInt(parts[2].replace(/\D/g, ''));
		if(parts[2].search(/subtract/) >= 0)
			selectedItemCost = -selectedItemCost;
		if(selectedItemCost == NaN)
			selectedItemCost = 0;
	}
	
	// update the total
	updatePriceTotal(selectedItemPrice);
	updatePriceSubtotal(section, selectedItemPrice);
	if(selectedItemCostNode != null)
	{
		updateCostTotal(selectedItemCost);
		updateCostSubtotal(section, selectedItemCost);
	}
	// update summary
	var summary = document.getElementById (id + 'Summary');
	descriptionNode = document.getElementById (id + 'Product' + selectedItemText);
	if(descriptionNode && summary)
		summary.innerHTML = selectedItemText;
	//update option prices
	selectedItemNode.text = selectedItemText;

	for(i=0; i < dropdown.options.length; i++)
	{
		if(i != dropdown.selectedIndex)
		{
			updateDropdownProductValues(dropdown.options[i], selectedItemPrice, selectedItemCost);
		}	
	}
}

function updateDropdownProductValues(option, price, cost)
{
	var parts = option.text.split('[');
	var itemPrice = 0;
	var text = parts[0];
	if(parts[1])
	{
		itemPrice = parseInt(parts[1].replace(/\D/g, ''));
		var t = parts[1].replace(/\D/, '');
		if(parts[1].search(/subtract/) >= 0)
			itemPrice = -itemPrice;
		if(itemPrice == NaN)
			itemPrice = 0;
	}
	var itemCost = 0;
	if(parts[2])
	{
		itemCost = parseInt(parts[2].replace(/\D/g, ''));
		if(parts[2].search(/subtract/) >= 0)
			itemCost = -itemCost;
		if(itemCost == NaN)
			itemCost = 0;
	}	
	itemPrice -=  price;
	itemCost -= cost;	
		
		
	var priceText = '';
	if(itemPrice > 0)
		priceText = ' [add $' + itemPrice + '] ';
	else if(itemPrice < 0)
		priceText = ' [subtract $' + -itemPrice + '] ';
	var costText = '';
	if(itemCost > 0)
		costText = ' [add $' + itemCost + '] ';
	else if(itemCost < 0)
		costText = ' [subtract $' + -itemCost + '] ';
	option.text = text + priceText + costText;
}

function updatePriceTotal(priceAdjustment)
{
	var totalPriceNode = document.getElementById ('totalPrice');
	var totalPrice = parseInt(totalPriceNode.innerHTML.replace(/[^\d]/gi, ''));
	totalPriceNode.innerHTML = '$' + (totalPrice + priceAdjustment);
}

function updateCostTotal(priceAdjustment)
{
	var totalPriceNode = document.getElementById ('totalCost');
	var totalPrice = parseInt(totalPriceNode.innerHTML.replace(/[^\d]/gi, ''));
	totalPriceNode.innerHTML = ' ($' + (totalPrice + priceAdjustment) + ')';
}

function updatePriceSubtotal(section, priceAdjustment)
{
	var subtotalPriceNode = document.getElementById (section + 'PriceSubtotal');
	if(subtotalPriceNode)
	{
		var priceNode = document.getElementById (section + 'Price');
		var totalPrice = parseInt(subtotalPriceNode.innerHTML.replace(/[^\d]/gi, ''));
		subtotalPriceNode.innerHTML = '$' + (totalPrice + priceAdjustment);
		if(priceNode)
			priceNode.innerHTML = ' [subtract $' + (totalPrice + priceAdjustment) + ']';
	}
	var sectionPriceNode = document.getElementById (section + 'Price');
	if(sectionPriceNode)
	{
		var priceNode = document.getElementById (section + 'Price');
		var totalPrice = parseInt(sectionPriceNode.innerHTML.replace(/[^\d]/gi, ''));
		sectionPriceNode.innerHTML = '$' + (totalPrice + priceAdjustment);
		if(priceNode)
			priceNode.innerHTML = ' [subtract $' + (totalPrice + priceAdjustment) + ']';
	}
}

function updateCostSubtotal(section, priceAdjustment)
{
	var subtotalPriceNode = document.getElementById (section + 'CostSubtotal');
	if(subtotalPriceNode)
	{
		var priceNode = document.getElementById (section + 'Cost');
		var totalPrice = parseInt(subtotalPriceNode.innerHTML.replace(/[^\d]/gi, ''));
		subtotalPriceNode.innerHTML = ' ($' + (totalPrice + priceAdjustment) + ')';
		if(priceNode)
			priceNode.innerHTML = ' [subtract $' + (totalPrice + priceAdjustment) + ']';
	}
}

function updatePrice(nodeID, priceAdjustment)
{
	//find this options current price adjustment
    var itemPriceNode = document.getElementById(nodeID);
    var itemPrice = getPrice(itemPriceNode);
    itemPrice -= priceAdjustment;
    if (itemPrice > 0) 
    {
        itemPriceNode.innerHTML = ' [add $' + itemPrice + ']';
    }
    else 
    {
        itemPriceNode.innerHTML = ' [subtract $' + (itemPrice * -1) + ']';
    }
}

function getPrice(itemPriceNode)
{
	var itemPrice = parseInt(itemPriceNode.innerHTML.replace(/[^\d]/gi, ''));
	if (isNaN(itemPrice))
		itemPrice = 0;
	if(itemPriceNode.innerHTML.match("subtract") && itemPrice > 0 )
		itemPrice = -itemPrice;
	return itemPrice;
}

function editSection(e)
{
	var target = getEventTarget(e);
	var sectionID = target.id.replace(/[^\d]/gi, '');
	//close any open editors
	closeSections();
	//open the selected editor
	var sectionSummary = document.getElementById ('section' + sectionID + 'Summary');
	sectionSummary.style.display = 'none';
	var sectionEditor = document.getElementById ('section' + sectionID + 'Editor');
	sectionEditor.style.display = '';
	var sectionNotSelected = document.getElementById ('section' + sectionID + 'NotSelected');
	if(sectionNotSelected)
		sectionNotSelected.style.display = 'none';
	var sectionOpen = document.getElementById ('section' + sectionID + 'open');
	sectionOpen.style.display = 'none';
	var sectionClose = document.getElementById ('section' + sectionID + 'close');
	sectionClose.style.display = '';
    // count sections
	var sectionTemplate = document.getElementById('section' + sectionID);
	var title = sectionTemplate.getElementsByTagName('legend');
	var sections = 0;
	var sectionTitles = configurator.getElementsByTagName('legend');
	for (var i = 0; i < sectionTitles.length; i++) 
	{
	    if (title[0].innerHTML == sectionTitles[i].innerHTML)
	        sections++;
	}
	var sectionOptional = document.getElementById('section' + sectionID + 'Optional');
	if (sections > 1 || sectionOptional.value == 'true') 
	{
	    var sectionRemove = document.getElementById('section' + sectionID + 'remove');
	    sectionRemove.style.display = '';
	}

}

function closeSections()
{
	var fieldsets = document.getElementsByTagName('fieldset');
	for(var i = 0; i < fieldsets.length; i++ )
	{
		if(fieldsets[i].id.search(/^section[\d]+$/) >= 0)
		{
			var sectionEditor = document.getElementById (fieldsets[i].id + 'Editor');
			if(sectionEditor && sectionEditor.style.display == '')
			{
				var sectionEnabled = document.getElementById (fieldsets[i].id + 'enabled');
				
				sectionEditor.style.display = 'none';
				
				if(sectionEnabled && sectionEnabled.checked == false)
				{
					var sectionNotSelected = document.getElementById (fieldsets[i].id + 'NotSelected');
					sectionNotSelected.style.display = '';
				}
				else
				{
					var sectionSummary = document.getElementById (fieldsets[i].id + 'Summary');
					sectionSummary.style.display = '';
				}

				var sectionOpen = document.getElementById (fieldsets[i].id + 'open');
				sectionOpen.style.display = '';
				var sectionClose = document.getElementById (fieldsets[i].id + 'close');
				sectionClose.style.display = 'none';
				var sectionRemove = document.getElementById(fieldsets[i].id + 'remove');
				sectionRemove.style.display = 'none';
			}
		}
	}
}

function addSection(e)
{
	var target = getEventTarget(e);
	var sectionID = target.id.replace(/[^\d]/gi, '');
	// count sections
	var sectionTemplate = document.getElementById ('section' + sectionID);
	var title = sectionTemplate.getElementsByTagName('legend');
	var sections = 0;
	var sectionTitles = configurator.getElementsByTagName('legend');
	for(var i = 0; i < sectionTitles.length; i++)
	{
		if(title[0].innerHTML == sectionTitles[i].innerHTML)
			sections++;
	}
	if(sections < sectionLimits[sectionID])
	{
		closeSections();
		var defaultSection = document.getElementById ('section' + sectionID)
		if(defaultSection.style.display == 'none')
			defaultSection.style.display = '';
		else
		{
			//find an unused section id
			var fieldsets = document.getElementsByTagName('fieldset');
			var ids = ',';
			for(var i = 0; i < fieldsets.length; i++ )
				ids += fieldsets[i].id.replace(/[^\d]/gi, '') + ',';
			var newSectionID = 1;
			while(ids.search(',' + newSectionID + ',') >= 0)
				newSectionID++;
			var clone = document.getElementById ('section' + sectionID).cloneNode(true);
			clone.id = 'section' + newSectionID;
			// fix ids and names and add event listeners
			var clonedDivs = clone.getElementsByTagName('div');
			for(var i = 0; i < clonedDivs.length; i++ )
				clonedDivs[i].id = clonedDivs[i].id.replace('section' + sectionID, 'section' + newSectionID);
			var clonedLinks = clone.getElementsByTagName('a');
			for(var i = 0; i < clonedLinks.length; i++ )
			{
				clonedLinks[i].id = clonedLinks[i].id.replace('section' + sectionID, 'section' + newSectionID);
				if(clonedLinks[i].id.search(/section\d+open/) >= 0)
					addEvent(clonedLinks[i], 'click', editSection);
				else if(clonedLinks[i].id.search(/section\d+close/) >= 0)
					addEvent(clonedLinks[i], 'click', closeSections);
				else if(clonedLinks[i].id.search(/section\d+remove/) >= 0)
					addEvent(clonedLinks[i], 'click', removeSection);
			}
			var clonedInputs = clone.getElementsByTagName('input');
			for(var i = 0; i < clonedInputs.length; i++ )
			{
				var input = clonedInputs[i];
				clonedInputs[i].id = clonedInputs[i].id.replace('section' + sectionID, 'section' + newSectionID);
				clonedInputs[i].name = clonedInputs[i].name.replace('section' + sectionID, 'section' + newSectionID);
				switch(clonedInputs[i].type)
				{
					case 'radio':
						addEvent(clonedInputs[i], 'change', radioChange);
						break;
					case 'checkbox':
						addEvent(clonedInputs[i], 'change', checkboxChange);
						break;
		            case 'button':
		                if (clonedInputs[i].id.search(/section\d+open/) >= 0)
		                    addEvent(clonedInputs[i], 'click', editSection);
		                else if (clonedInputs[i].id.search(/section\d+close/) >= 0)
		                    addEvent(clonedInputs[i], 'click', closeSections);
		                else if (clonedInputs[i].id.search(/section\d+remove/) >= 0)
		                    addEvent(clonedInputs[i], 'click', removeSection);
		                break;
					
				}
			}
			var clonedSpans = clone.getElementsByTagName('span');
			for(var i = 0; i < clonedSpans.length; i++ )
				clonedSpans[i].id = clonedSpans[i].id.replace('section' + sectionID, 'section' + newSectionID);
			var clonedSelects = clone.getElementsByTagName('select');
			for(var i = 0; i < clonedSelects.length; i++)
			{
				clonedSelects[i].id = clonedSelects[i].id.replace('section' + sectionID, 'section' + newSectionID);
				clonedSelects[i].name = clonedSelects[i].name.replace('section' + sectionID, 'section' + newSectionID);
				addEvent(clonedSelects[i], 'change', dropdownChange);
			}
			// insert the cloned node in the document
			var addLink = document.getElementById ('section' + sectionID + 'add');
			addLink.parentNode.insertBefore(clone, addLink);
		}
		// update the totals
		var subtotalPriceNode = document.getElementById('section' + sectionID + 'Price');
		if (subtotalPriceNode != null) 
		{
		    var sectionPrice = parseInt(subtotalPriceNode.innerHTML.replace(/[^\d]/gi, ''));
		    updatePriceTotal(sectionPrice);
		}
		var subtotalCostNode = document.getElementById ('section' + sectionID + 'Cost' + sectionID);
		if(subtotalCostNode != null)
		{
			var sectionCost = parseInt(subtotalCostNode.innerHTML.replace(/[^\d]/gi, ''));
			updateCostTotal(sectionCost);
		}
	}
	else
	{
		alert('You can not add any additional ' + title[0].innerHTML + ' sections.');
	}
}

function removeSection(e)
{
	if(confirm('Are you sure that you want to remove this section?'))
	{
		var target = getEventTarget(e);
		var sectionID = target.id.replace(/[^\d]/gi, '');
		// update the totals
		var subtotalPriceNode = document.getElementById ('section' + sectionID + 'Price' );
		var sectionPrice = parseInt(subtotalPriceNode.innerHTML.replace(/[^\d]/gi, ''));
		updatePriceTotal(-sectionPrice);
		var subtotalCostNode = document.getElementById ('section' + sectionID + 'Cost' + sectionID);
		if(subtotalCostNode != null)
		{
			var sectionCost = parseInt(subtotalCostNode.innerHTML.replace(/[^\d]/gi, ''));
			updateCostTotal(-sectionCost);
		}
		
		// remove section
		var sectionNode = document.getElementById('section' + sectionID);
		var sectionType = sectionNode.getElementsByTagName('legend')[0].innerHTML;
		var sectionTypes = configurator.getElementsByTagName('legend');
		var sectionCount = 0;
		for(var i = 0; i < sectionTypes.length; i++)
		{
			if(sectionTypes[i].innerHTML == sectionType)
				sectionCount++;
		}
		if(sectionCount > 1)
			sectionNode.parentNode.removeChild(sectionNode);
		else
			sectionNode.style.display = 'none';
	}
}

function dependencyRule(id, products, dependencies, quantity, message)
{
	this.id = id;
	this.products = products;
	this.dependencies = dependencies;
	this.quantity = quantity;
	this.message = message;
}

function evaluateDependencies(e)
{
	var target = getEventTarget(e);
	target.id.match(/Product(\d+)/i);	
	var productID = RegExp.$1;
	for(var i = 0; i < dependencyRules.length; i++)
	{
		// check rules that apply to this product
		for(var j = 0; j < dependencyRules[i].products.length; j++)
		{
			if(dependencyRules[i].products[j] == productID)
				checkDependencyRule(dependencyRules[i]);
		}
		// check rules that  this product is a requirement for
		for(var j = 0; j < dependencyRules[i].dependencies.length; j++)
		{
			if(dependencyRules[i].dependencies[j] == productID)
				checkDependencyRule(dependencyRules[i]);
		}
	}
}

function checkDependencyRule(rule)
{
	// check to see if the dependencies for this rule are met
	var reqirementMet = true;
	var quantity = 0;
	var inputs = configurator.getElementsByTagName('input');
	var selects = configurator.getElementsByTagName('select');
	for(var i = 0; i < inputs.length; i++)
	{
		if(inputs[i].checked && inputs[i].value > 0)
		{
			for(var j = 0; j < rule.products.length; j++)
			{
				if(inputs[i].value == rule.products[j])
				{
					quantity++;
				}
			}
		}
	}
	for(var i = 0; i < selects.length; i++)
	{
		if(selects[i].value > 0)
		{
			for(var j = 0; j < rule.products.length; j++)
			{
				if(selects[i].value == rule.products[j] )
				{
					quantity++;
				}
			}
		}
	}
	if(quantity >= rule.quantity )
	{
		reqirementMet = false;
		for(var i = 0; i < inputs.length; i++)
		{
			for(var j = 0; j < rule.dependencies.length; j++)
			{
				if(inputs[i].value > 0 &&inputs[i].value == rule.dependencies[j] && inputs[i].checked)
					reqirementMet = true;
			}
		}
		for(var i = 0; i < selects.length; i++)
		{
			for(var j = 0; j < rule.dependencies.length; j++)
			{
				if(selects[i].value == rule.dependencies[j] && selects[i].value > 0)
					reqirementMet = true;
			}
		}
	}
	if(reqirementMet == false)
	{
		// dependencies are not met so add an error message if it is not all ready there
		var configurationErrors = document.getElementById('configurationErrors');
		var errorMessage = document.getElementById('dependencyRule' + rule.id + 'Error');
		if(errorMessage == null)
		{
			errorMessage = document.createElement('div');
			errorMessage.id = 'dependencyRule' + rule.id + 'Error';
			errorMessage.innerHTML = rule.message;
			errorMessage.className = 'error'; 
			configurationErrors.appendChild(errorMessage);
		}
	}
	else
	{
		// dependencies are met so remove any associated error messages
		var errorMessage = document.getElementById('dependencyRule' + rule.id + 'Error');
		if(errorMessage)
		{
			errorMessage.parentNode.removeChild(errorMessage);
		}
	}
}

function incompatibilityRule(id, products, incompatibleProducts, quantity, message)
{
	this.id = id;
	this.products = products;
	this.incompatibleProducts = incompatibleProducts;
	this.quantity = quantity;
	this.message = message;
}

function evaluateIncompatibilities(e)
{
	var target = getEventTarget(e);
	target.id.match(/Product(\d+)/i);	
	var productID = RegExp.$1;
	for(var i = 0; i < incompatibilityRules.length; i++)
	{
		// check rules that apply to this product
		for(var j = 0; j < incompatibilityRules[i].products.length; j++)
		{
			if(incompatibilityRules[i].products[j] == productID)
				checkIncompatibilityRule(incompatibilityRules[i]);
		}
		// check rules that  this product is a requirement for
		for(var j = 0; j < incompatibilityRules[i].incompatibleProducts.length; j++)
		{
			if(incompatibilityRules[i].incompatibleProducts[j] == productID)
				checkIncompatibilityRule(incompatibilityRules[i]);
		}
	}	
}

function checkIncompatibilityRule(rule)
{
	var ruleActive = false;
	var quantity = 0;
	// check if any products this rule applies to are selected
	var inputs = configurator.getElementsByTagName('input');
	var selects = configurator.getElementsByTagName('select');
	for(var i = 0; i < inputs.length; i++)
	{
		for(var j = 0; j < rule.products.length && ruleActive == false; j++)
		{
			if(rule.products[j] > 0 &&inputs[i].value == rule.products[j] && inputs[i].checked)
			{
				ruleActive = true;
			}
		}
	}
	for(var i = 0; i < selects.length; i++)
	{
		for(var j = 0; j < rule.products.length && ruleActive == false; j++)
		{
			if(rule.products[j] > 0 && selects[i].value == rule.products[j] )
			{
				ruleActive = true;
			}
		}
	}
	if(ruleActive)
	{
		for(var i = 0; i < inputs.length; i++)
		{
			if(inputs[i].checked && inputs[i].value > 0)
			{
				for(var j = 0; j < rule.incompatibleProducts.length; j++)
				{
					if(inputs[i].value == rule.incompatibleProducts[j])
					{
						quantity++;
					}
				}
			}
		}
		for(var i = 0; i < selects.length; i++)
		{
			if(selects[i].value > 0)
			{
				for(var j = 0; j < rule.incompatibleProducts.length; j++)
				{
					if(selects[i].value == rule.incompatibleProducts[j] )
					{
						quantity++;
					}
				}
			}
		}
	}
	if(ruleActive && quantity >= rule.quantity)
	{
		// incompatibilities are present so add an error message if it is not all ready there
		var configurationErrors = document.getElementById('configurationErrors');
		var errorMessage = document.getElementById('incompatibilityRule' + rule.id + 'Error');
		if(errorMessage == null)
		{
			errorMessage = document.createElement('div');
			errorMessage.id = 'incompatibilityRule' + rule.id + 'Error';
			errorMessage.innerHTML = rule.message;
			errorMessage.className = 'error'; 
			configurationErrors.appendChild(errorMessage);
		}	
	}
	else
	{
		// no incompatibility exisits for this rule so remove any associated error messages
		var errorMessage = document.getElementById('incompatibilityRule' + rule.id + 'Error');
		if(errorMessage)
		{
			errorMessage.parentNode.removeChild(errorMessage);
		}
	}
}

function initialize()
{
	configurator = document.getElementById('configurator');
	if(configurator)
	{
		loadRules();
		/*var links = configurator.getElementsByTagName('a');
		for(var i = 0; i < links.length; i++)
		{
			if(links[i].id.search(/section\d+close/) >= 0)
				addEvent(links[i], 'click', closeSections);
			else if(links[i].id.search(/section\d+open/) >= 0)
				addEvent(links[i], 'click', editSection);
			else if(links[i].id.search(/section\d+remove/) >= 0)
				addEvent(links[i], 'click', removeSection);
			else if(links[i].id.search(/section\d+add/) >= 0)
				addEvent(links[i], 'click', addSection);
		}*/
		var links = configurator.getElementsByTagName('input');
		for(var i = 0; i < links.length; i++)
		{
			if(links[i].id.search(/section\d+close/) >= 0)
				addEvent(links[i], 'click', closeSections);
			else if(links[i].id.search(/section\d+open/) >= 0)
				addEvent(links[i], 'click', editSection);
			else if(links[i].id.search(/section\d+remove/) >= 0)
				addEvent(links[i], 'click', removeSection);
			else if(links[i].id.search(/section\d+add/) >= 0)
				addEvent(links[i], 'click', addSection);
		}
		var inputs = configurator.getElementsByTagName('input');
		for(var i = 0; i < inputs.length; i++)
		{
			// add event to update prices
			switch(inputs[i].type)
			{
				case 'radio':
					addEvent(inputs[i], 'click', radioChange);
					break;
				case 'checkbox':
					addEvent(inputs[i], 'click', checkboxChange);
					break;
			}
			// add events to test dependency rules
			for(var j = 0; j < dependencyRules.length; j++)
			{
				for(var k = 0; k < dependencyRules[j].products.length; k++)
				{
					if(inputs[i].id.search('Product' + dependencyRules[j].products[k]) > 0 )
					{
						addEvent(inputs[i], 'click', evaluateDependencies);
					}
				}
				for(var k = 0; k < dependencyRules[j].dependencies.length; k++)
				{
					if(inputs[i].id.search('Product' + dependencyRules[j].dependencies[k]) > 0 )
					{
						addEvent(inputs[i], 'click', evaluateDependencies);
					}
				}
			}
			// add events to test incompatibility rules
			for(var j = 0; j < incompatibilityRules.length; j++)
			{
				for(var k = 0; k < incompatibilityRules[j].products.length; k++)
				{
					if(inputs[i].id.search('Product' + incompatibilityRules[j].products[k]) > 0 )
					{
						addEvent(inputs[i], 'click', evaluateIncompatibilities);
					}
				}
				for(var k = 0; k < incompatibilityRules[j].incompatibleProducts.length; k++)
				{
					if(inputs[i].id.search('Product' + incompatibilityRules[j].incompatibleProducts[k]) > 0 )
					{
						addEvent(inputs[i], 'click', evaluateIncompatibilities);
					}
				}
			}
		}
		// add event to update prices
		var selects = configurator.getElementsByTagName('select');
		for(var i = 0; i < selects.length; i++)
			addEvent(selects[i], 'change', dropdownChange);
		// add events to test dependency rules
		var options = configurator.getElementsByTagName('option');
		for(var i = 0; i < options.length; i++)
		{
			for(var j = 0; j < dependencyRules.length; j++)
			{
				for(var k = 0; k < dependencyRules[j].products.length; k++)
				{
					if(options[i].value == dependencyRules[j].products[k])
					{
						addEvent(options[i].parentNode, 'change', evaluateDependencies);
					}
				}
				for(var k = 0; k < dependencyRules[j].dependencies.length; k++)
				{
					if(options[i].value == dependencyRules[j].dependencies[k])
					{
						addEvent(options[i].parentNode, 'change', evaluateDependencies);
					}
				}
			}
		}
		// add events to test incompatibility rules
		for(var i = 0; i < options.length; i++)
		{
			for(var j = 0; j < incompatibilityRules.length; j++)
			{
				for(var k = 0; k < incompatibilityRules[j].products.length; k++)
				{
					if(options[i].value == incompatibilityRules[j].products[k])
					{
						addEvent(options[i].parentNode, 'change', evaluateIncompatibilities);
					}
				}
				for(var k = 0; k < incompatibilityRules[j].incompatibleProducts.length; k++)
				{
					if(options[i].value == incompatibilityRules[j].incompatibleProducts[k])
					{
						addEvent(options[i].parentNode, 'change', evaluateIncompatibilities);
					}
				}
			}
		}
	}
}

function getEventTarget(e)
{
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
	return targ;
}

function addEvent(obj, evType, fn)
{ 
	if (obj.addEventListener)
	{ 
		obj.addEventListener(evType, fn, true); 
		return true; 
	} 
	else if (obj.attachEvent)
	{
		var r = obj.attachEvent("on"+evType, fn); 
		return r; 
	} 
	else 
		return false; 
}

addEvent(window, 'load', initialize);