var checkedGraphic   = '/images/i_tick_sml_g.gif';
var unCheckedGraphic = '/images/unchecked.jpg';
var imageSize        = 18;

// Called when a checkbox changes:
// image.onClick and checkbox.onChange
// Paramaters:
//    id:  the id of the checkbox
//    fromCheckbox: true if this event was triggered by the checkbox (false if it's from the image)
function checkBoxHandler(checkbox, image, fromCheckbox) {
    checked  = checkbox.checked;

    if (!fromCheckbox) {
        // if this was triggered by the image we need to toggle the checked status manually
        checked = checkbox.checked = !checkbox.checked;
    }

    if (checked) {
        image.src = checkedGraphic;
    } else { 
        image.src = unCheckedGraphic;
    }
}

// Called when a radiobutton changes:
// image.onClick and radio.onChange
// Paramaters:
//    id:  the id of the radio button
//    fromRadio: true if this event was triggered by the radio button (false if it's from the image)
function radioButtonHandler(radio, image, fromRadio) {
	radio.checked = true;
    radioImages = radioBoxes[radio.name.toLowerCase()]; // Get the radio buttons in this group
    for (index = 0; index < radioImages.length; index++) {
        // Loop through all the images in this group and uncheck them
        radioImages[index].src = unCheckedGraphic;
    }
    image.src = checkedGraphic; // Now check the current radiobutton
}

// This variable stores a list of all the radio buttons
// The group name is used as the key
// Each item is an array of IDs for the images in the group
var radioBoxes = {};

// Sets up the graphical checkboxes
// Loops through each checkbox in the document and:
// * assigns a unique id if it doesn't have one
// * adds the checkBox() event handler above
// * hides it and
// * creates an associated image tag with the checkBox() event handler
function initCheckboxes() {
    inputs = document.getElementsByTagName('input');
    for (index = 0; index < inputs.length; index++) {
        checkbox = inputs[index];
        type = checkbox.type.toLowerCase();

        if (type != 'checkbox' && type != 'radio') continue;

        // hide the checkbox and set it to 0px wide so it doesn't leave a gap
        // currently labels aren't functioning in IE - FIXME
        checkbox.style.visibility = 'hidden'; 
        checkbox.style.width = checkbox.style.height = '0px';
        
        link = document.createElement('a'); // Create the link wrapper
        if (checkbox.tabIndex) {
            link.setAttribute('tabIndex', checkbox.tabIndex);
        }
        link.href = 'javascript:void(0)'; // Prevent submission when using the keyboard
        link.className = 'checkbox';
        checkbox.parentNode.insertBefore(link, checkbox.nextSibling); // Add the link after the checkbox

        image = document.createElement('img'); // Create the checkbox image
        if (checkbox.checked) { // Assign the graphic
            image.setAttribute('src', checkedGraphic);
        } else {
            image.setAttribute('src', unCheckedGraphic);
        }
        image.setAttribute('type', 'image');
        image.setAttribute('height', imageSize);
        image.setAttribute('width', imageSize);
        link.appendChild(image); // Link the image

        function makeHandler(checkbox, image, handlerFunction) {
            return function(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) targ = targ.parentNode; // defeat Safari bug
                    handlerFunction(checkbox, image, targ.type && targ.type.toLowerCase() == 'checkbox');
                    return false; // prevent submission
                };
        }
        checkbox.onchange = link.onclick = makeHandler(checkbox, image, type == 'radio' ? radioButtonHandler : checkBoxHandler);

/*        checkbox.parentNode.insertBefore(image, checkbox.nextSibling); // Insert the image into the DOM after the checkbox, to avoid an infinite loop*/

        if (type == 'radio') {
            // If this is a radio button the id needs to be associated with the group name
            if (!radioBoxes[checkbox.name.toLowerCase()]) radioBoxes[checkbox.name.toLowerCase()] = [];
            radioBoxes[checkbox.name.toLowerCase()].push(image);
        }
    }
}

// Helper function to check a box from JS, to make sure onChange is called
function check(id, checked) {
    if (checked == undefined) checked = true;
    box = document.getElementById(id);
    box.checked = checked;
    box.onchange();
}
$(initCheckboxes);
