var required = [
    {name: 'email', valid: /^[a-zA-Z0-9][a-zA-Z0-9\-\_\.]*@[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,6}$/},
    {name: 'phone', valid: /[-a-z0-9]/i},
    {name: 'name', valid: /.+/i}
];

var values = {
servers: [
    {name: 'Entry level'},
    {name: 'SME'},
    {name: 'Enterprise'}
],
cpus: [
    {name: '2.4GHz', parent1: 'Entry level'},
    {name: '2.8GHz', parent1: 'Entry level'},
    {name: '3.0GHz', parent1: 'Entry level'},
    
    {name: 'Core2Duo 2*1.86GHz', parent1: 'SME'},
    {name: 'Core2Duo 2*2.00GHz', parent1: 'SME'},
    {name: 'Core2Duo 2*2.40GHz', parent1: 'SME'},
    {name: 'Core2Duo 2*2.66GHz', parent1: 'SME'},
    
    {name: 'Dual Xeon 5110 2*1.6GHz', parent1: 'Enterprise'},
    {name: 'Dual Xeon 5130 2*2.00GHz', parent1: 'Enterprise'},
    {name: 'Dual Xeon 5150 2*2.66GHz', parent1: 'Enterprise'},
    {name: 'Dual Xeon 5160 2*3.0GHz', parent1: 'Enterprise'}
],
hdnumber: [
    {name: '2', parent1: ['Entry level', 'SME', 'Enterprise']},
    {name: '3', parent1: ['SME', 'Enterprise']},
    {name: '4', parent1: ['SME', 'Enterprise']}
],
hds: [
    {name: '120GB', parent1: 'Entry level'},
    {name: '200GB', parent1: ['Entry level', 'SME', 'Enterprise']},
    {name: '250GB', parent1: ['SME', 'Enterprise']},
    {name: '500GB', parent1: ['SME', 'Enterprise']}
],
raids: [
    {name: 'No RAID', parent1: ['Entry level', 'SME', 'Enterprise'], parent2: ['2', '3', '4']},
    {name: 'RAID1', parent1: ['SME', 'Enterprise'], parent2: ['2', '3', '4']},
    {name: 'RAID1 + hot spare', parent1: ['SME', 'Enterprise'], parent2: ['3', '4']},
    {name: 'RAID1 + hot spare + backup', parent1: ['SME', 'Enterprise'], parent2: '4'},
    {name: 'RAID1 + backup', parent1: ['SME', 'Enterprise'], parent2: ['3', '4']},
    {name: 'RAID5', parent1: ['SME', 'Enterprise'], parent2: ['3', '4']},
    {name: 'RAID5 + hot spare', parent1: ['SME', 'Enterprise'], parent2: '4'},
    {name: 'RAID5 + backup', parent1: ['SME', 'Enterprise'], parent2: '4'},
    {name: 'RAID6', parent1: ['SME', 'Enterprise'], parent2: '4'}
],
rams: [
    {name: '512mb', parent1: 'Entry level'},
    {name: '1GB', parent1: ['Entry level', 'SME', 'Enterprise']},
    {name: '2GB', parent1: ['Entry level', 'SME', 'Enterprise']},
    {name: '4GB', parent1: ['SME', 'Enterprise']},
    {name: '6GB', parent1: ['SME', 'Enterprise']},
    {name: '8GB', parent1: ['SME', 'Enterprise']}
],
cps: [
    {name: 'None', parent1: ['CentOS', 'Windows']},
    {name: 'cPanel', parent1: 'CentOS'},
    {name: 'Helm', parent1: 'Windows'}
]
};

var hdmatching = [
    {name: 'RAID1', hdnumber: '2', match: 2},
    {name: 'RAID1 + backup', hdnumber: '3', match: 2},
    
    {name: 'RAID1', hdnumber: '3', match: 3},
    {name: 'RAID1 + backup', hdnumber: '4', match: 3},
    {name: 'RAID1 + hot spare', hdnumber: '3', match: 3},
    {name: 'RAID1 + hot spare + backup', hdnumber: '4', match: 3},
    {name: 'RAID5', hdnumber: '3', match: 3},
    {name: 'RAID5 + backup', hdnumber: '4', match: 3},
    
    {name: 'RAID1', hdnumber: '4', match: 4},
    {name: 'RAID1 + hot spare', hdnumber: '4', match: 4},
    {name: 'RAID5', hdnumber: '4', match: 4},
    {name: 'RAID5 + hot spare', hdnumber: '4', match: 4},
    {name: 'RAID6', hdnumber: '4', match: 4}
];


/**
 * Creates the options of a select element based on up to two dependencies
 * Select element - select element to populate
 * array  options - array of options from the values array
 * string parent1 - first dependency
 * string parent2 - optional second dependency
 * string selected - value of the default selected option
**/
function setOptions(element, options, parent1, parent2, selected) {
    element.options.length = 0;
    element.removeAttribute('disabled');
    
    for(var i = 0; i < options.length; i++) {
        if(parent1) {
            if((parent1 && !parent2 && (options[i].parent1 == parent1 || options[i].parent1.contains(parent1)))
            || (parent1 && parent2 && (options[i].parent1 == parent1 || options[i].parent1.contains(parent1)) && (options[i].parent2 == parent2 || options[i].parent2.contains(parent2)))
            ) {
                var op = document.createElement('option');
                op.appendChild(document.createTextNode(options[i].name));
                op.value = options[i].name;
                if(selected && selected == op.value) op.selected = "selected";
                element.appendChild(op);
            }
        }else {
            var op = document.createElement('option');
            op.appendChild(document.createTextNode(options[i].name));
            element.appendChild(op);
        }
    }
}

/**
 * Removes the options of select element and disables the field
 * Select element - the select element to empty and disable
**/
function emptyOptions(element) {
    element.setAttribute('disabled', 'true');
    element.options.length = 0;
}

/**
 * Sets the HD matching according to RAID option and number of HDs
 * string raid - RAID option selected
 * integer hdnumber - number of HDs
**/
function matchHDs() {
    var form = $('form');
    
    var matching;
    for(var i = 0; i < hdmatching.length; i++) {
        if(hdmatching[i].name == form.raid.value && hdmatching[i].hdnumber == form.hdnumber.value) {
            matching = hdmatching[i].match;
            break;
        }
    }
    
    switch(matching) {
        case 2:
            // Match the first two
            if(this.name != "hd3" && this.name != "hd4") {
                form.hd1.selectedIndex = this.selectedIndex;
                form.hd2.selectedIndex = this.selectedIndex;
            }
            break;
        case 3:
            // Match the first three
            if(this.name != "hd4") {
                form.hd1.selectedIndex = this.selectedIndex;
                form.hd2.selectedIndex = this.selectedIndex;
                form.hd3.selectedIndex = this.selectedIndex;
            }
            break;
        case 4:
            // Match the first four
            form.hd1.selectedIndex = this.selectedIndex;
            form.hd2.selectedIndex = this.selectedIndex;
            form.hd3.selectedIndex = this.selectedIndex;
            form.hd4.selectedIndex = this.selectedIndex;
            break;
        default:
            break;
    }
}

/**
 * Resets the options of each HD field
**/
function resetHD() {
    var form = $('form');

    // If the HD values are not valid for the current RAID option, reset all active HD selections.
    if(!checkHD()) {
        setOptions(form.hd1, values.hds, form.server.value);
        setOptions(form.hd2, values.hds, form.server.value);
        if(form.hdnumber.value == "3" || form.hdnumber.value == "4")
            setOptions(form.hd3, values.hds, form.server.value);
        if(form.hdnumber.value == "4")
            setOptions(form.hd4, values.hds, form.server.value);
    }
}

/**
 * Checks if the values of all of the active HDs match
**/
function checkHD() {
    var form = $('form');
        
    var matching = 0;
    for(var i = 0; i < hdmatching.length; i++) {
        if(hdmatching[i].name == form.raid.value && hdmatching[i].hdnumber == form.hdnumber.value) {
            matching = hdmatching[i].match;
            break;
        }
    }
    
    if(matching == 2) {
        return (form.hd1.value == form.hd2.value);
    }else if(matching == 3) {
        return (form.hd1.value == form.hd2.value && form.hd2.value == form.hd3.value);
    }else if(matching == 4) {
        return (form.hd1.value == form.hd2.value && form.hd2.value == form.hd3.value && form.hd3.value == form.hd4.value);
    }else {
        return true;
    }
}

/**
 * Resets the options of the RAID selection
**/
function resetRaid() {
    var form = $('form');
    var selected = form.raid.options[form.raid.selectedIndex].value;
    
    setOptions(form.raid, values.raids, form.server.value, form.hdnumber.value, selected);
}

Window.onDomReady(function() {
    var form = $('form');
    
    // On server change
    form.server.onchange = function() {
        var form = $('form');
        
        // Set the CPU options
        setOptions(form.cpu, values.cpus, this.value);
        
        // Set the options for HD number
        setOptions(form.hdnumber, values.hdnumber, this.value);
        
        // Set the RAID options
        resetRaid();
        
        // Set the HD options
        setOptions(form.hd1, values.hds, this.value);
        setOptions(form.hd2, values.hds, this.value);
        emptyOptions(form.hd3);
        emptyOptions(form.hd4);
        
        // Set the RAM options
        setOptions(form.ram, values.rams, this.value);
        
        // Toggle fields for "Entry level" server type
        if(this.value == "Entry level") {
            form.raid.setAttribute('disabled', 'true');
            form.hdnumber.setAttribute('disabled', 'true');
        }else {
            form.raid.removeAttribute('disabled');
            form.hdnumber.removeAttribute('disabled');
        }
    }
    
    // Toggle disabled property of HD options depending on selected HD number
    form.hdnumber.onchange = function() {
        var form = $('form');
        if(this.value == '4') {
            if(form.hd3.options.length == 0) setOptions(form.hd3, values.hds, form.server.value);
            if(form.hd4.options.length == 0) setOptions(form.hd4, values.hds, form.server.value);
        }else if(this.value == '3') {
            if(form.hd3.options.length == 0) setOptions(form.hd3, values.hds, form.server.value);
            emptyOptions(form.hd4);
        }else if(this.value == '2') {
            emptyOptions(form.hd3);
            emptyOptions(form.hd4);
        }        

        // Set possible RAID options based on HD number
        resetRaid();
        
        resetHD();
    }
    
    // On RAID change
    form.raid.onchange = function() {
        resetHD();
    }
    
    form.hd1.onchange = matchHDs;
    form.hd2.onchange = matchHDs;
    form.hd3.onchange = matchHDs;
    form.hd4.onchange = matchHDs;
    
    // On OS change
    form.operating_system.onchange = function() {
        var form = $('form');
        // Set CP options depending on OS
        setOptions(form.control_panel, values.cps, this.value);
    }
    
    // Toggle visibility and disabled properties of Backup-related fields
    form.backups.onchange = function() {
        var nas = $('nas_backup');
        var cdp = $('cdp_backup');
        var form = $('form');
        
        if(this.value == "No thanks") {
            nas.style.display = "none";
            cdp.style.display = "none";
            
            form.nas_backup_gb.setAttribute('disabled', 'true');

            form.cdp_frequency.setAttribute('disabled', 'true');
            form.cdp_details.setAttribute('disabled', 'true');
        }else if(this.value == "NAS Back-up") {
            nas.style.display = "block";
            cdp.style.display = "none";
            
            form.nas_backup_gb.removeAttribute('disabled');
            
            form.cdp_details.setAttribute('disabled', 'true');
            form.cdp_frequency.setAttribute('disabled', 'true');
        }else if(this.value == "CDP") {
            nas.style.display = "none";
            cdp.style.display = "block";
            
            form.nas_backup_gb.setAttribute('disabled', 'true');
            
            form.cdp_frequency.removeAttribute('disabled');
        }
    }
    
    form.cdp_frequency.onchange = function() {
        var form = $('form');
        if(this.value == "Other (please note)") {
            $('cdp_details').style.display = "block";
            form.cdp_details.removeAttribute('disabled');
        }else {
            $('cdp_details').style.display = "none";
            form.cdp_details.setAttribute('disabled', 'true');
        }
    }
    
    form.bandwidth.onchange = function() {
        var form = $('form');
        if(this.value == "Other (please note)") {
            $('bandwidth_details').style.display = "block";
            form.bandwidth_details.removeAttribute('disabled');
        }else {
            $('bandwidth_details').style.display = "block";
            form.bandwidth_details.setAttribute('disabled', 'true');
        }
    }
    
    form.onsubmit = function() {
        // Validation based on "required" array in "values" array
        var errors = new Array();
        var first;
        for(var i = 0; i < required.length; i++) {
            var field = eval("form." + required[i].name);
            if(!field.value.match(required[i].valid)) {
                errors.push("Please fill-in the " + required[i].name + " field.");
                first = required[i].name;
            }
        }
        
        if(errors.length) {
            alert(errors.join('\n'));
            eval("form." + first).focus();
            return false;
        }
        return true;
    }
});