kPartial = 0;
kChecked = 1;
kUnchecked = 2;


TristateCheckboxes = {
    oldClicks: {},
    oldChecks: {},
    mouseTarget: null,
    coldImages: [],
    hotImages: [],
    disabledImages: [],
    isHot: false,

    Initialize: function () {
        var checkboxes = document.getElementsByTagName("input");
        var replace = [];
        for (var i=0; i<checkboxes.length; ++i) {
            if (checkboxes[i].type == "checkbox") {
                replace.push(checkboxes[i]);
            }
        }

        var img = document.createElement('img');
        img.src = "/static/images/checkboxPartial.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.coldImages.push(img);
        document.body.appendChild(img);
        img = document.createElement('img');
        img.src = "/static/images/checkboxChecked.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.coldImages.push(img);
        document.body.appendChild(img);
        img = document.createElement('img');
        img.src = "/static/images/checkboxUnchecked.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.coldImages.push(img);
        document.body.appendChild(img);

        img = document.createElement('img');
        img.src = "/static/images/checkboxHotPartial.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.hotImages.push(img);
        document.body.appendChild(img);
        img = document.createElement('img');
        img.src = "/static/images/checkboxHotChecked.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.hotImages.push(img);
        document.body.appendChild(img);
        img = document.createElement('img');
        img.src = "/static/images/checkboxHotUnchecked.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.hotImages.push(img);
        document.body.appendChild(img);

        img = document.createElement('img');
        img.src = "/static/images/checkboxDisabledPartial.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.disabledImages.push(img);
        document.body.appendChild(img);
        img = document.createElement('img');
        img.src = "/static/images/checkboxDisabledChecked.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.disabledImages.push(img);
        document.body.appendChild(img);
        img = document.createElement('img');
        img.src = "/static/images/checkboxDisabledUnchecked.gif";
        img.style.visibility = "hidden";
        img.style.display = "none";
        this.disabledImages.push(img);
        document.body.appendChild(img);

        for (var i=0; i<replace.length; ++i) {
            this.ReplaceWithTristate(replace[i]);
        }
    },

    ReplaceWithTristates: function (rootElement) {
        var checkboxes = rootElement.getElementsByTagName("input");
        var replace = [];
        for (var i=0; i<checkboxes.length; ++i) {
            if (checkboxes[i].type == "checkbox") {
                replace.push(checkboxes[i]);
            }
        }
        for (var i=0; i<replace.length; ++i) {
            this.ReplaceWithTristate(replace[i]);
        }
    },

    ReplaceWithTristate: function (element) {
        var newElement = document.createElement('img');
        newElement.alt = "checkbox";
        newElement.className = "tristateCheckbox"

        if (element.disabled) {
            var images = this.disabledImages;
        } else {
            var images = this.coldImages;
        }

        if (element.indeterminate) {
            newElement.src = images[kPartial].src;
            newElement.checked = true;
            newElement.indeterminate = true;
        } else if (element.checked) {
            newElement.src = images[kChecked].src;
            newElement.checked = true;
            newElement.indeterminate = false;
        } else {
            newElement.src = images[kUnchecked].src;
            newElement.checked = false;
            newElement.indeterminate = false;
        }
        var name = element.name;
        var id = element.id;
        var tag = "";

        if (name == "") {
            tag = id;
        } else {
            tag = name;
        }
        element.id = "";
        element.style.display = "none";
        this.oldChecks[tag] = element;
        element.parentNode.insertBefore(newElement, element);
        //element.parentNode.replaceChild(newElement, element);
        if (element.onclick) {
            this.oldClicks[tag] = element.onclick;
        }
        newElement.name = name;
        newElement.id = id;
        newElement.disabled = (element.disabled)?true:false;
        newElement.onmousedown = this.MouseDownTristate;
        newElement.onmouseover = this.MouseOverTristate;
        newElement.onmouseout = this.MouseOutTristate;
        newElement.onmouseup = this.MouseUpTristate;
        newElement.onclick = this.ClickTristate;
    },

    MouseDownTristate: function (e) {
        var evt = e || window.event;
        var evtTarget = evt.target || evt.srcElement;
        //console.log("MOUSEDOWN" + evtTarget);
        TristateCheckboxes.mouseTarget = evtTarget;
        TristateCheckboxes.MakeHot(evtTarget);
        return false;
    },

    MouseOverTristate: function (e) {
        var evt = e || window.event;
        var evtTarget = evt.target || evt.srcElement;
        if (evtTarget == TristateCheckboxes.mouseTarget) {
            TristateCheckboxes.MakeHot(evtTarget);
            //console.log("MOUSEOVER" + evtTarget);
        }
    },

    MouseOutTristate: function (e) {
        var evt = e || window.event;
        var evtTarget = evt.target || evt.srcElement;
        if (evtTarget == TristateCheckboxes.mouseTarget) {
            TristateCheckboxes.MakeCold(evtTarget);
            //console.log("MOUSEOUT" + evtTarget);
        }
    },

    MouseUpTristate: function (e) {
        var evt = e || window.event;
        var evtTarget = evt.target || evt.srcElement;
        if (evtTarget == TristateCheckboxes.mouseTarget) {
            //console.log("MOUSEUP" + evtTarget);
            TristateCheckboxes.MakeCold(evtTarget);
            TristateCheckboxes.mouseTarget = null;
        }
    },

    MakeHot: function (elem) {
        this.isHot = true;
        if (!elem.disabled) {
            if (elem.indeterminate) {
                elem.src = this.hotImages[kPartial].src;
            } else if (elem.checked) {
                elem.src = this.hotImages[kChecked].src;
            } else {
                elem.src = this.hotImages[kUnchecked].src;
            }
        }
    },

    MakeCold: function (elem) {
        this.isHot = false;
        if (!elem.disabled) {
            if (elem.indeterminate) {
                elem.src = this.coldImages[kPartial].src;
            } else if (elem.checked) {
                elem.src = this.coldImages[kChecked].src;
            } else {
                elem.src = this.coldImages[kUnchecked].src;
            }
        }
    },

    ToggleCheck: function (elem) {
        if (elem.indeterminate) {
            elem.indeterminate = false;
        } else {
            elem.checked = !elem.checked;
        }
        if (elem.checked) {
            elem.src = this.coldImages[kChecked].src;
        } else {
            elem.src = this.coldImages[kUnchecked].src;
        }
        this.FixOldCheck(elem);
    },

    FixOldCheck: function (elem) {
        var tag = "";
        if (elem.name == "") {
            tag = elem.id;
        } else {
            tag = elem.name;
        }
        if (this.oldChecks[tag]) {
            this.oldChecks[tag].checked = elem.checked;
        }
    },

    ClickTristate: function (e) {
        var evt = e || window.event;
        var evtTarget = evt.target || evt.srcElement;

        if (!evtTarget.disabled) {
            // console.log("CLICK" + evtTarget.name);
            TristateCheckboxes.ToggleCheck(evtTarget);

            var tag = "";
            
            if (evtTarget.name == "") {
                tag = evtTarget.id;
            } else {
                tag = evtTarget.name;
            }

            if (tag && TristateCheckboxes.oldClicks[tag]) {
                return TristateCheckboxes.oldClicks[tag](e);
            }
        }
    },

    Update: function (elem) {
        var images = null;

        this.FixOldCheck(elem);

        if (elem.disabled) {
            images = this.disabledImages;
        } else  if (this.isHot) {
            images = this.hotImages;
        } else {
            images = this.coldImages;
        }

        if (elem.nodeName.toLowerCase() == "img") {
            if (elem.indeterminate) {
                elem.src = images[kPartial].src;
            } else if (elem.checked) {
                elem.src = images[kChecked].src;
            } else {
                elem.src = images[kUnchecked].src;
            }
        }
    }
};


function InitializeTristates() {
    TristateCheckboxes.Initialize()
}

