﻿// ************************************************************************************************
// ************************************************************************************************
//
// Custom checkboxes
// Written by Matt Gullett (c) 2008
// Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
// You may freely do whatever you want with this code, just leave this header intact EXCEPT
// that you may compress/obsfucate the code for performance reasons which may strip this header
// off.  Basically, I just don't want anyone claiming they wrote it.
//
// This script implements support for simple custom checkboxes on web pages that provide
// an alternative visual effect than the standard checkboxes provided by the browser.
//
// Most checkbox features are implemented including
//  2 States (checked, unchecked)  (* note: no support for tri-state check boxes)
//  enabled / disabled
//  keyboard support including tabbing
//  tooltips
//  simple grouping
//  customizable images for checked/unchecked state at either the whole page level
//      or the individual item level
//  works with standard <input type=checkbox ...> elements
//
// ****
//
//  The basic implementation is somewhat hard to see from the code, so I'll explain a little
//  here.
//
//  The need for this module arose on a complex AJAXian website that used a very custom user
//  interface.  The idea is to have a DIV element that contains the text/image/whatever as the
//  label for the checkbox (as innerHTML).  The DIV element is of a particular CSS class that
//  includes padding on the left (or right, at programmers discretion) to allow a background
//  image to be set that is set to no-repeat and position top-left, or middle-left, or top-right
//  or middle-right (see CSS example below).  When a user clicks on a checkbox, the background
//  image is changed to the checked or unchecked image.  The DIV element that acts as the checkbox
//  can be "synched" to an actual input element, or it can stand alone.  (For AJAXian sites, there
//  may be no need for the INPUT element, so it's not required).
//
//  CSS example
//  <style>
//  div.MTGCheckBox
//  {
//      background-repeat: no-repeat;
//      background-position: top left;
//      padding-left: 20px;
//      border: solid 1px transparent;
//      cursor: pointer;
//  }
//  </style>
//  NOTE: Transparent borders don't work on IE6, this is just an example, use a value that's
//  appropriate to your needs.
//
//  There are several ways to use this checkbox styling.  You can 
//  a) define standard checkboxes and labels on a form and call 
//      checkbox_initFromInputs("YourCSSClassName") to allow this utility to automagically customize 
//      the checkboxes.  
//  b) define DIV elements on your web page of whatever CSS class you want and then call
//      checkbox_initFromDivs("YourCSSClassName") to allow this utility to automagically customize
//      those divs into checkboxes
//  c) Allow JavaScript to "write" the DIVs directly onto the webpage during rendering by calling
//      checkbox_writeNewCheckbox(strClassName, strName, strLabel, bChecked, bDisabled, strTooltip, strGroup)
//  d) Setup DIV elements on the page as place holders can call
//      checkbox_insertNewCheckBox(strDivID, strClassName, strName, strLabel, bChecked, bDisabled, strTooltip, strGroup)
//
//  You pick what method works best for your site/needs.
//
//  All of the "global" variables and methods defined here are prefixed with checkbox_ to try and 
//  prevent problems working with other libraries.
//
//  Some of the code in this class is just helper functions (such as checkAll, uncheckAll, sync,
//  getPostData, etc.  If you want to shrink this somewhat, you can strip out whatever methods you
//  don't need.
// ************************************************************************************************
// ************************************************************************************************
var checkbox_pathToImages = apath+"en/_resources/_images/common/MtcCheckboxes/";
var checkbox_EnabledCheckedImageName = "checkbox_checked_big.png";
var checkbox_EnabledUncheckedImageName = "checkbox_unchecked_big.png";
var checkbox_DisabledCheckedImageName = "checkbox_DisabledChecked_BlackBox.gif";
var checkbox_DisabledUncheckedImageName = "checkbox_DisabledUnchecked_BlackBox.gif";
var checkbox_onExtendMouseOverMethod = null;
var checkbox_onExtendMouseOutMethod = null;
var checkbox_onExtendMouseUpMethod = null;
var checkbox_onExtendMouseDownMethod = null;
var checkbox_onExtendKeyDownMethod = null;
var checkbox_toggleOnMouseUp = true;
var checkbox_isIE = document.all;
var checkbox_includeTabIndexes = true;
var checkbox_objects = new Array();
var checkbox_inputElements = new Array();

// inititlizes all the checkboxes within a document (from INPUT elements)
function checkbox_initFromInputs(strClassName)
{
    // get all the divs in the document
    var objInputElements = document.getElementsByTagName("input");
    var iIndex = 0;
    
    // serch all the divs
    for (iIndex = 0; iIndex < objInputElements.length; iIndex++)
    {
        // only modify those with the class name for our custom checkboxes
        if (objInputElements[iIndex].getAttribute("type").toLowerCase() == "checkbox")
        {
            // find the label associated with the checkbox
            var objLabel = checkbox_findLabelElement(objInputElements[iIndex].getAttribute("name"));
            
            // hide the input element and it's associated label
            objInputElements[iIndex].style.display = "none";
            if (objLabel) objLabel.style.display = "none";
        
            // create a new div
            var objDiv = document.createElement("div");
            objDiv.className = strClassName;
            objDiv.setAttribute("inputname", objInputElements[iIndex].getAttribute("name"));
            objDiv.innerHTML = "";
            if (objLabel) objDiv.innerHTML = objLabel.innerHTML;

            checkbox_objects.push(objDiv);
            
            // add the new div element to the page before the input element we hid
            objInputElements[iIndex].parentNode.insertBefore(objDiv, objInputElements[iIndex]);

            // init the item            
            checkbox_initItem(objDiv);
        }
    }
}

// initializes all the checkboxes within the document (from DIV elements)
function checkbox_initFromDivs(strClassName)
{  
    // get all the divs in the document
    var objDivs = document.getElementsByTagName("div");
    var iIndex = 0;
    
    // serch all the divs
    for (iIndex = 0; iIndex < objDivs.length; iIndex++)
    {   
        // only modify those with the class name for our custom checkboxes
        if (objDivs[iIndex].className == strClassName)
        {   
            // add to our object array
            checkbox_objects.push(objDivs[iIndex]);
            checkbox_initItem(objDivs[iIndex]);
        }
    }
}

// initialize a single item
function checkbox_initItem(objDiv)
{
    // capture any current event handlers that we are about to override
    // so that they can be called by our override methods
    objDiv.original_onmouseover = objDiv.onmouseover;
    objDiv.original_onmouseout = objDiv.onmouseover;
    objDiv.original_onmouseup = objDiv.onmouseover;
    objDiv.original_onmousedown = objDiv.onmouseover;
    objDiv.original_onkeydown = objDiv.onmouseover;

    // set custom event handlers
    objDiv.onmouseover = checkbox_onMouseOver;
    objDiv.onmouseout = checkbox_onMouseOut;
    objDiv.onmouseup = checkbox_onMouseUp;
    objDiv.onmousedown = checkbox_onMouseDown;
    objDiv.onkeydown = checkbox_onKeyDown;
    
    // prevent an uncontrolled recursive call
    if (objDiv.original_onmouseover == objDiv.onmouseover) objDiv.original_onmouseover = null;
    if (objDiv.original_onmouseout == objDiv.onmouseover) objDiv.original_onmouseout = null;
    if (objDiv.original_onmouseup == objDiv.onmouseover) objDiv.original_onmouseup = null;
    if (objDiv.original_onmousedown == objDiv.onmouseover) objDiv.original_onmousedown = null;
    if (objDiv.original_onkeydown == objDiv.onmouseover) objDiv.original_onkeydown = null;
    
    // if inputname is specified, sync up the checked flags
    if (objDiv.getAttribute("inputname") && objDiv.getAttribute("inputname") != "")
    {
        var objInput = checkbox_findInputElement(objDiv.getAttribute("inputname"));
        if (objInput)
        {
            checkbox_inputElements.push(objInput);
        
            if (objInput.checked)
                objDiv.setAttribute("checked", "1");
            else
                objDiv.setAttribute("checked", "0");
        }
    }
    
    // if no checked attribute is set, set it now to zero (unchecked)
    if (!objDiv.getAttribute("checked"))
        objDiv.setAttribute("checked", "0")

    // the checked attribute can only be a one or a zero, nothing else                
    if (objDiv.getAttribute("checked") != "0" && objDiv.getAttribute("checked") != "1")
        objDiv.setAttribute("checked", "0")

    // set the appropriate background image
    checkbox_setAppropriateBackgroundImage(objDiv);
    
    // if include tab indexes is requested, force each div to have a tabIndex value of zero.
    // the part of the if condition (objDiv.tabIndex == 0) is there to make sure that
    // the tabIndex isn's already set to something other than zero.  As far as I can tell, IE
    // returns zero for tabIndex, even when no tabIndex is set, that's why I force tabIndex
    // when it's zero
    if (checkbox_includeTabIndexes && ((checkbox_isIE && objDiv.tabIndex == 0) || (!checkbox_isIE && objDiv.tabIndex == -1)))
        objDiv.tabIndex = 0;
}

// write out a new checkbox
function checkbox_writeNewCheckbox(strClassName, strName, strLabel, bChecked, bDisabled, strTooltip, strGroup)
{
    if (bDisabled == null) bDisabled = false;
    if (strTooltip == null) strTooltip = "";
    if (strGroup == null) strGroup = "";

    if (!bDisabled)
    {
        if (bChecked)
            document.write("<input type=checkbox name=\"" + strName + "\" style=\"display: none;\" CHECKED>");
        else
            document.write("<input type=checkbox name=\"" + strName + "\" style=\"display: none;\">");
    }
    else
    {
        if (bChecked)
            document.write("<input type=checkbox name=\"" + strName + "\" style=\"display: none;\" CHECKED disabled=\"disabled\">");
        else
            document.write("<input type=checkbox name=\"" + strName + "\" style=\"display: none;\" disabled=\"disabled\">");
    }
    document.write("<div id=\"div_" + strName + "\" class=\"" + strClassName + "\" inputname=\"" + strName + "\" title=\"" + strTooltip + "\"");
    if (strGroup != "")
        document.write(" checkboxGroup=\"" + strGroup + "\"");
    document.write(">");
    document.write(strLabel);
    document.write("</div>");
}

// inserts a checkbox object into the document within a specific element (ID=strDivID)
function checkbox_insertNewCheckBox(strDivID, strClassName, strName, strLabel, bChecked, bDisabled, strTooltip, strGroup)
{
    if (bDisabled == null) bDisabled = false;
    if (strTooltip == null) strTooltip = "";
    if (strGroup == null) strGroup = "";

    var objInsertAt = document.getElementById(strDivID);
    
    if (objInsertAt)
    {
        var objInput = document.createElement("input");
        objInput.setAttribute("type", "checkbox");
        objInput.setAttribute("name", strName);
        if (bChecked)
           objInput.checked = true;
        else
           objInput.checked = false;
        if (bDisabled)
            objInput.setAttribute("disabled", "disabled");
        objInput.style.display = "none";
        
        var objDiv = document.createElement("div");
        objDiv.id = "div_" + strName;
        objDiv.className = strClassName;
        objDiv.setAttribute("inputname", strName);
        objDiv.setAttribute("title", strTooltip);
        if (strGroup != "") objDiv.setAttribute("checkboxGroup", strGroup);
        objDiv.innerHTML = strLabel;

        checkbox_objects.push(objDiv);
        
        objInsertAt.appendChild(objInput);
        objInsertAt.appendChild(objDiv);
        
        // I'd prefer that this was up where the rest of the objInput attributes
        // are set, but due to a bug in IE, I have to do this here.
        if (bChecked)
           objInput.checked = true;
        else
           objInput.checked = false;
        
        checkbox_initItem(objDiv);
        
        return objDiv;
    }
    else
    {
        // error??
    }
}

// call this function to add a single DIV style checkbox (already compatible with
// this class) to the checkbox management
function checkbox_insertExistingCheckBox(objCheckbox)
{
    checkbox_initItem(objCheckbox);
    checkbox_objects.push(objCheckbox);
}

// check all checkboxes in a given group (or all groups if strGroup == "")
function checkbox_checkAll(strGroup, bFireClickEvents)
{
    // get all the divs in the document
    var iIndex = 0;

    if (!strGroup) strGroup = "";
    
    // serch all the divs
    for (iIndex = 0; iIndex < checkbox_objects.length; iIndex++)
    {
        if (strGroup == "" || (checkbox_objects[iIndex].getAttribute("checkboxGroup") && checkbox_objects[iIndex].getAttribute("checkboxGroup") == strGroup))
        {
            // if FireClickEvents is requested, and we are changing the checkbox from unchecked to check
            // then fire the custom onClickEvent handler for each checkbox (if it has a customOnClickEvent)
            if (bFireClickEvents && checkbox_objects[iIndex].getAttribute("checked") == "0")
            {
                checkbox_objects[iIndex].setAttribute("checked", "1");
                checkbox_setAppropriateBackgroundImage(checkbox_objects[iIndex]);
            
                if (checkbox_objects[iIndex].customOnClickEvent)
                    checkbox_objects[iIndex].customOnClickEvent(objTarget);
            }
            else
            {
                checkbox_objects[iIndex].setAttribute("checked", "1");
                checkbox_setAppropriateBackgroundImage(checkbox_objects[iIndex]);
            }
        }
    }
}

// uncheck all checkboxes in a given group (or all groups if strGroup == "")
function checkbox_uncheckAll(strGroup, bFireClickEvents)
{
    // get all the divs in the document
    var iIndex = 0;

    if (!strGroup) strGroup = "";
    
    // serch all the divs
    for (iIndex = 0; iIndex < checkbox_objects.length; iIndex++)
    {
        if (strGroup == "" || (checkbox_objects[iIndex].getAttribute("checkboxGroup") && checkbox_objects[iIndex].getAttribute("checkboxGroup") == strGroup))
        {
            // if FireClickEvents is requested, and we are changing the checkbox from checked to unchecked
            // then fire the custom onClickEvent handler for each checkbox (if it has a customOnClickEvent)
            if (bFireClickEvents && checkbox_objects[iIndex].getAttribute("checked") == "1")
            {
                checkbox_objects[iIndex].setAttribute("checked", "0");
                checkbox_setAppropriateBackgroundImage(checkbox_objects[iIndex]);
                
                if (checkbox_objects[iIndex].customOnClickEvent)
                    checkbox_objects[iIndex].customOnClickEvent(objTarget);
            }
            else
            {
                checkbox_objects[iIndex].setAttribute("checked", "0");
                checkbox_setAppropriateBackgroundImage(checkbox_objects[iIndex]);
            }
        }
    }
}

// event handler for DIV elements
function checkbox_onMouseOver(e)
{
    var objTarget = null;
    
    if (checkbox_isIE)
        objTarget = window.event.srcElement;
    else
        objTarget = e.target;
    
    // fire custom mouse over method if one was provided
    if (checkbox_onExtendMouseOverMethod)
        checkbox_onExtendMouseOverMethod(objTarget);

    // fire original on mouse over event handler (if one was present)
    if (objTarget.original_onmouseover)
        objTarget.original_onmouseover(e);
}

// event handler for DIV elements
function checkbox_onMouseOut(e)
{
    var objTarget = null;
    
    if (checkbox_isIE)
        objTarget = window.event.srcElement;
    else
        objTarget = e.target;
    
    // fire custom mouse out method if one was provided
    if (checkbox_onExtendMouseOutMethod)
        checkbox_onExtendMouseOutMethod(objTarget);

    // fire original on mouse out event handler (if one was present)
    if (objTarget.original_onmouseout)
        objTarget.original_onmouseout(e);
}

// event handler for DIV elements
function checkbox_onMouseDown(e)
{
    var objTarget = null;
    var bContinue = true;
    
    if (checkbox_isIE)
        objTarget = window.event.srcElement;
    else
        objTarget = e.target;
    
    // fire custom onMouseDownMethod if one is provided.
    // we expect it to return true/false indicating whether
    // or not the process should continue or be aborted
    if (checkbox_onExtendMouseDownMethod)
        bContinue = checkbox_onExtendMouseDownMethod(objTarget);
    
    // toggling can be configured to fire on mouse up or down
    // only do it if on mouse down is set and the custom on mouse
    // down method didn't return false
    if (bContinue && !checkbox_toggleOnMouseUp)
    {
        checkbox_toggle(objTarget);
    
        // if one is provided, fire the objects custom click event handler
        if (objTarget.customOnClickEvent)
            objTarget.customOnClickEvent(objTarget);
    }
    
    // fire original on mouse down event handler (if one was present)
    if (objTarget.original_onmousedown)
        objTarget.original_onmousedown(e);
}

// event handler for DIV elements
function checkbox_onMouseUp(e)
{
    var objTarget = null;
    var bContinue = true;
    
    if (checkbox_isIE)
        objTarget = window.event.srcElement;
    else
        objTarget = e.target;

    // fire custom onMouseUpMethod if one is provided.
    // we expect it to return true/false indicating whether
    // or not the process should continue or be aborted
    if (checkbox_onExtendMouseUpMethod)
        bContinue = checkbox_onExtendMouseUpMethod(objTarget);
    
    // toggling can be configured to fire on mouse up or down
    // only do it if on mouse up is set and the custom on mouse
    // up method didn't return false
    if (bContinue && checkbox_toggleOnMouseUp)
    {
        checkbox_toggle(objTarget);
    
        // if one is provided, fire the objects custom click event handler
        if (objTarget.customOnClickEvent)
            objTarget.customOnClickEvent(objTarget);
    }

    // fire original on mouse up event handler (if one was present)
    if (objTarget.original_onmouseup)
        objTarget.original_onmouseup(e);
}

// event handler for DIV elements
function checkbox_onKeyDown(e)
{
    var objTarget = null;
    var bContinue = true;
    
    if (checkbox_isIE)
        objTarget = window.event.srcElement;
    else
        objTarget = e.target;
        
    // fire custom onMouseDownMethod if one is provided.
    // we expect it to return true/false indicating whether
    // or not the process should continue or be aborted
    if (checkbox_onExtendKeyDownMethod)
        bContinue = checkbox_onExtendKeyDownMethod(objTarget);
    
    // toggling can be configured to fire on mouse up or down
    // only do it if on mouse down is set and the custom on mouse
    // down method didn't return false
    if (bContinue && ((checkbox_isIE && window.event.keyCode == 32) || (!checkbox_isIE && e.keyCode == 32)))
    {
        checkbox_toggle(objTarget);
    
        // if one is provided, fire the objects custom click event handler
        if (objTarget.customOnClickEvent)
            objTarget.customOnClickEvent(objTarget);
    }
   
    // fire original on key down event handler (if one was present)
    if (objTarget.original_onkeydown)
        objTarget.original_onkeydown(e);
}

// toggle the checkbox checked or not checked
function checkbox_toggle(objTarget)
{
    // disabled checkboxes cannot be toggled
    if (!checkbox_isDisabled(objTarget))
    {
        if (objTarget.getAttribute("checked") == "1")
        {
            objTarget.setAttribute("checked", "0");
            checkbox_setAppropriateBackgroundImage(objTarget);
            
            if (objTarget.getAttribute("inputname") && objTarget.getAttribute("inputname") != "")
            {
                var objInputBox = checkbox_findInputElement(objTarget.getAttribute("inputname"));
                if (objInputBox)
                    objInputBox.checked = false;
                else
                    alert("CheckBox Input Element Not Found: " + objTarget.getAttribute("inputname"));
            }
        }
        else
        {
            objTarget.setAttribute("checked", "1");
            checkbox_setAppropriateBackgroundImage(objTarget);
            
            if (objTarget.getAttribute("inputname") && objTarget.getAttribute("inputname") != "")
            {
                var objInputBox = checkbox_findInputElement(objTarget.getAttribute("inputname"));
                if (objInputBox)
                    objInputBox.checked = true;
                else
                    alert("CheckBox Input Element Not Found: " + objTarget.getAttribute("inputname"));
            }
        }
    }
}

// anytime the checked state of an object is changed, the background image is set
// by this helper function.  This deals with custom images, enabled/disabled state
// checked -vs- non checked
function checkbox_setAppropriateBackgroundImage(objTarget)
{
    var strDisabledCheckedImage = checkbox_pathToImages + checkbox_DisabledCheckedImageName;
    var strDisabledUncheckedImage = checkbox_pathToImages + checkbox_DisabledUncheckedImageName;
    var strEnabledCheckedImage = checkbox_pathToImages + checkbox_EnabledCheckedImageName;
    var strEnabledUncheckedImage = checkbox_pathToImages + checkbox_EnabledUncheckedImageName;
    
    if (objTarget.getAttribute("cbx_disabledCheckedImage") && objTarget.getAttribute("cbx_disabledCheckedImage") != "")
        strDisabledCheckedImage = objTarget.getAttribute("cbx_disabledCheckedImage");
    if (objTarget.getAttribute("cbx_disabledUnCheckedImage") && objTarget.getAttribute("cbx_disabledUnCheckedImage") != "")
        strDisabledCheckedImage = objTarget.getAttribute("cbx_disabledUnCheckedImage");

    if (objTarget.getAttribute("cbx_CheckedImage") && objTarget.getAttribute("cbx_CheckedImage") != "")
        strEnabledCheckedImage = objTarget.getAttribute("cbx_CheckedImage");
    if (objTarget.getAttribute("cbx_UnCheckedImage") && objTarget.getAttribute("cbx_UnCheckedImage") != "")
        strEnabledUncheckedImage = objTarget.getAttribute("cbx_UnCheckedImage");

    if (checkbox_isDisabled(objTarget))
    {
        if (objTarget.getAttribute("checked") == "1")
            objTarget.style.backgroundImage = "url('" + strDisabledCheckedImage + "')";
        else
            objTarget.style.backgroundImage = "url('" + strDisabledUncheckedImage + "')";
    }
    else
    {
        if (objTarget.getAttribute("checked") == "1")
            objTarget.style.backgroundImage = "url('" + strEnabledCheckedImage + "')";
        else
            objTarget.style.backgroundImage = "url('" + strEnabledUncheckedImage + "')";
    }
}

// returns true/false indicating whether or not the input box is disabled.
// this is important for determing whther or not to accept input and which background
// image to set
function checkbox_isDisabled(objTarget)
{
    if (objTarget.getAttribute("inputname") && objTarget.getAttribute("inputname") != "")
    {
        var objInput = checkbox_findInputElement(objTarget.getAttribute("inputname"));
        if (objInput)
        {
            if (objInput.disabled)
                return true;
        }
    }
    
    return false;
}

// find a type=checkbox input element with the given name
// this is used when setting the checked status of a div element so that
// the associated input box can be set as well
function checkbox_findInputElement(strName)
{
    var objInputElements = document.getElementsByTagName("input");
    var iIndex = 0;
    var bFound = false;
    var objReturn = null;
    
    // serch all the divs
    for (iIndex = 0; iIndex < objInputElements.length; iIndex++)
    {
        // only modify those with the class name for our custom checkboxes
        if (objInputElements[iIndex].getAttribute("type").toLowerCase() == "checkbox")
        {
            if (objInputElements[iIndex].getAttribute("name").toLowerCase() == strName.toLowerCase())
            {
                bFound = true;
                objReturn = objInputElements[iIndex];
                break;
            }
        }
    }
    
    return objReturn;
}

// find a label element that is associated with an input type=checkbox element
// (useful when stylizing asp.net pages)
function checkbox_findLabelElement(strName)
{
    var objLabelElements = document.getElementsByTagName("label");
    var iIndex = 0;
    var bFound = false;
    var objReturn = null;
    
    // serch all the divs
    for (iIndex = 0; iIndex < objLabelElements.length; iIndex++)
    {
        // only modify those with the class name for our custom checkboxes
        if (objLabelElements[iIndex].attributes["for"] && objLabelElements[iIndex].attributes["for"].value.toLowerCase() == strName.toLowerCase())
        {
            bFound = true;
            objReturn = objLabelElements[iIndex];
            break;
        }
    }
    
    return objReturn;
}

// this function call is needed if JavaScript is used to set the checked value
// of an input element instead of a user directly clicking/typing/whatever
function checkbox_sync()
{
    var iX = 0;
    var iY = 0;
    
    for (iX = 0; iX < checkbox_inputElements.length; iX++)
    {
        var objInput = checkbox_inputElements[iX];
        var objDiv = null;
        
        iY = 0;
        while (iY < checkbox_objects.length && objDiv == null)
        {
            if (checkbox_objects[iY].getAttribute("inputname") && checkbox_objects[iY].getAttribute("inputname").toLowerCase() == objInput.getAttribute("name").toLowerCase())
                objDiv = checkbox_objects[iY];
        
            iY = iY + 1
        }
        
        if (objDiv != null)
        {
            if (objInput.checked && objDiv.getAttribute("checked") != "1")
            {
                objDiv.setAttribute("checked", "1");
                checkbox_setAppropriateBackgroundImage(objDiv);
            }
            else if (!objInput.checked && objDiv.getAttribute("checked") != "0")
            {
                objDiv.setAttribute("checked", "0");
                checkbox_setAppropriateBackgroundImage(objDiv);
            }
        }
        else
        {
            // this should never happen
            alert("Checkbox sync failing due to non-matching input to div element");
        }        
    }
}

// useful in AJAX applications to quickly retrieve the needed post data for
// the checkboxes
function checkbox_getPostData(bForceReturnUnchecked)
{
    var iX = 0;
    var strReturn = "";
    
    if (bForceReturnUnchecked == null) bForceReturnUnchecked = false;
    
    // just to be safe, we synchronize so that any programatically set
    // checkbox values are not "lost"
    checkbox_sync();
    
    for (iX = 0; iX < checkbox_objects.length; iX++)
    {
        var objDiv = checkbox_objects[iX];
        
        var strVarName = "";
        var strValue = "1";
        
        if (objDiv.getAttribute("inputname") && objDiv.getAttribute("inputname") != "")
        {
            strValue = "on";
            strVarName = objDiv.getAttribute("inputname");
            var objInput = checkbox_findInputElement(strVarName);
            if (objInput)
            {
                if (objInput.getAttribute("value") && objInput.getAttribute("value") != "")
                    strValue = objInput.getAttribute("value");
            }
        }
        if (strVarName == "" && objDiv.getAttribute("name")) strVarName = objDiv.getAttribute("name");
        if (strVarName == "" && objDiv.id) strVarName = objDiv.id;
        
        if (strVarName != "")
        {
            if (objDiv.getAttribute("checked") == "1")
            {
                if (strReturn != "") strReturn += "&"
                strReturn += strVarName + "=" + strValue;
            }
            else if (bForceReturnUnchecked)
            {
                if (strValue == "on")
                    strValue = "off";
                else if (strValue == "1")
                    strValue = "0";
                else
                    strValue = "";
            
                if (strReturn != "") strReturn += "&"
                strReturn += strVarName + "=" + strValue;
            }
        }
        else
        {
            // this should never happen
            //alert("Checkbox post data incomplete due to missing object identification.");
        }
    }
    
    return strReturn;
}

// property set helper method
function checkbox_setOption_IncludeTabIndexes(bValue)
{
    checkbox_includeTabIndexes = bValue;
}

// property set helper method
function checkbox_setOption_PathToImages(strPath)
{
    checkbox_pathToImages = strPath;
}

// property set helper method
function checkbox_setOption_EnabledCheckedImageName(strName)
{
    checkbox_EnabledCheckedImageName = strName;
}

// property set helper method
function checkbox_setOption_EnabledUnCheckedImageName(strName)
{
    checkbox_EnabledUncheckedImageName = strName;
}

// property set helper method
function checkbox_setOption_DisabledCheckedImageName(strName)
{
    checkbox_DisabledCheckedImageName = strName;
}

// property set helper method
function checkbox_setOption_DisabledUnCheckedImageName(strName)
{
    checkbox_DisabledUncheckedImageName = strName;
}

// property set helper method
function checkbox_setOption_ToggleOnMouseUp(bValue)
{
    checkbox_toggleOnMouseUp = bValue;
}

// property set helper method
function checkbox_setOption_CustomMouseOverMethod(fnMethod)
{
    checkbox_onExtendMouseOverMethod = fnMethod;
}

// property set helper method
function checkbox_setOption_CustomMouseOutMethod(fnMethod)
{
    checkbox_onExtendMouseOutMethod = fnMethod;
}

// property set helper method
function checkbox_setOption_CustomMouseUpMethod(fnMethod)
{
    checkbox_onExtendMouseUpMethod = fnMethod;
}

// property set helper method
function checkbox_setOption_CustomMouseDownMethod(fnMethod)
{
    checkbox_onExtendMouseDownMethod = fnMethod;
}

// property set helper method
function checkbox_setOption_CustomKeyDownMethod(fnMethod)
{
    checkbox_onExtendKeyDownMethod = fnMethod;
}

