(function(jQuery) {
    jQuery.fn.checkboxTree = function(settings) {

        settings = jQuery.extend({
            collapsedarrow: "img-arrow-collapsed.gif",
            expandedarrow: "img-arrow-expanded.gif",
            blankarrow: "img-arrow-blank.gif",
            activeClass: "checkboxtreeactive",
            hoverClass: "over",
            checkchildren: false,
            checkparents: true,
            collapsed: true,
            hidecbwithjs: false,
            checkedClass: "checked"
        }, settings);

        var $group = this;
        var $labels = jQuery(":checkbox + label", $group)
        var $checkboxes = jQuery(":checkbox", $group)

        //set up the tree
        jQuery("li", $group).each(function() {

            var $this = jQuery(this)
            var $collapseImage;

            if (settings.checkparents) {
                var checkedchildren = jQuery("ul li input:checked", $this).length
                var $firstcheckbox = $this.children("input:checkbox:first")

                if ((!$this.children("input:checkbox:first").is(":checked")) && (checkedchildren > 0)) {
                    $firstcheckbox.attr("checked", "checked")
                }
            }

            if ($this.is(":has(ul)")) {
                if (settings.collapsed) {
                    $this.find("ul").hide();
                    $collapseImage = jQuery('<img class="checkboxtreeimage" src="' + settings.collapsedarrow + '" / >')
                    $collapseImage.data("collapsedstate", 0)
                } else {
                    $collapseImage = jQuery('<img class="checkboxtreeimage" src="' + settings.expandedarrow + '" / >')
                    $collapseImage.data("collapsedstate", 1)
                }
            } else {
                $collapseImage = jQuery('<img src="' + settings.blankarrow + '" / >')
            }
            $this.prepend($collapseImage);

        })

        //add class signifying the tree has been setup
        $group.addClass(settings.activeClass);

        $group.bind("click.checkboxtree", function(e, a) {
            var $clicked = jQuery(e.target)
            var $clickedcheck = $clicked.prev()
            var $currrow = $clicked.parents("li:first")
            var $clickedparent = $currrow.parents("li:first").find(":checkbox:first");
            var $clickedparentlabel = $clickedparent.next("label");
            var clickedlabel = false;
            var clickedimage = false;
            if ($clicked.is(":checkbox + label")) {
                clickedlabel = true;
            }
            if ($clicked.is("img.checkboxtreeimage")) {
                clickedimage = true;
            }
            //when the label is clicked, set the checkbox to the opposite clicked state, and toggle the checked class
            if (clickedlabel) {

                $clicked.prev().attr({ checked: !$clickedcheck.attr("checked") }).end().toggleClass(settings.checkedClass);
                //check parents if that option is set
                if (settings.checkparents) {
                    var checkedchildren = jQuery("input:checked", $currrow).length

                    if ((!$clickedparent.is(":checked")) && (checkedchildren > 0)) {
                        $clickedparentlabel.trigger("click.checkboxtree", ["checkparents"])
                    }
                }
                //check child checkboxes if settings say so
                if (settings.checkchildren && a !== "checkparents") {
                    $currrow.find(":checkbox + label").prev().attr({ checked: $clickedcheck.attr("checked") ? "checked" : "" })
					.next()
					.addClass($clicked.hasClass(settings.checkedClass) ? settings.checkedClass : "")
					.removeClass($clicked.hasClass(settings.checkedClass) ? "" : settings.checkedClass)

                }

                if ($clickedcheck.attr("checked") == false) {
                    $currrow.find("input:checkbox:checked").each(function() {
                        //alert($(this).attr("id"));
                        $(this).removeAttr("checked");
                        $(this).parent("li").find("label:first").removeClass("checked");
                    });
                }
            }
            //handle expanding of levels
            if (clickedimage) {
                var clickstate = $clicked.data("collapsedstate");
                if (clickstate === 0) {
                    var cobject = childrenobject($currrow.find("input:first:checkbox").attr("id"));
                    if (cobject != null) {

                        var childrentree = $("\"" + treeview(cobject) + "\"");
                        var child = $currrow.children("ul");
                        if (child.html() == "") {
                            child.append(childrentree);
                        }
                        if (!child.is(":has(img)")) {
                            child.find("li").each(function() {

                                var $this = $(this);
                                var $collapseImage;

                                if ($this.is(":has(ul)")) {
                                    if (settings.collapsed) {
                                        $this.find("ul").hide();
                                        $collapseImage = jQuery('<img class="checkboxtreeimage" src="' + settings.collapsedarrow + '" / >');
                                        $collapseImage.data("collapsedstate", 0);
                                    } else {
                                        $collapseImage = jQuery('<img class="checkboxtreeimage" src="' + settings.expandedarrow + '" / >');
                                        $collapseImage.data("collapsedstate", 1);
                                    }
                                } else {
                                    $collapseImage = jQuery('<img src="' + settings.blankarrow + '" / >');
                                }

                                $this.prepend($collapseImage);

                            });
                        }
                        var currTxt = $('#' + $("#txtType").html()).val();
                        //if (currTxt != undefined && currTxt != "" && $clickedcheck.attr("checked") == true) {
                        if (currTxt != undefined && currTxt != "") {
                            child.find("label").each(function() {

                                if (currTxt.indexOf($(this).text()) != -1) {
                                    $(this).prev().attr("checked", "checked").next().addClass("checked");
                                }
                            });

                        }
                        child.show();
                        $currrow.children("img").attr("src", settings.expandedarrow);
                        $clicked.data("collapsedstate", 1);

                    }
                } else if (clickstate === 1) {
                    $currrow.children("ul").hide();
                    $currrow.children("img").attr("src", settings.collapsedarrow);
                    $clicked.data("collapsedstate", 0);
                }

            }
        })

        //set the class correctly for the labels that contain checked checkboxes
        jQuery("input:checked + label", $group).addClass(settings.checkedClass)

        //add hover class for labels if is ie 6
        if (jQuery.browser.msie && jQuery.browser.version < 7) {
            $labels.hover(
				function() { jQuery(this).addClass(settings.hoverClass) },
				function() { jQuery(this).removeClass(settings.hoverClass); }
			)
        }

        //hide the checkboxes with js if set option set to true
        if (settings.hidecbwithjs) {
            $checkboxes.hide();
        }


        return $group;
    };

    jQuery.fn.clearAllChecked = function() {
        this.find("input:checkbox:checked").each(function() {
            $(this).removeAttr("checked");
            $(this).parent("li").find("label:first").removeClass("checked");
        });
    };

    jQuery.fn.collaspedall = function() {
        this.find("li").each(function() {
            if ($(this).is(":has(ul)")) {
                $(this).find("ul").hide();
                $collapseImage = $(this).find("img:first").attr("src", "/images/checkboxtree/img-arrow-collapsed.gif");

                $collapseImage.data("collapsedstate", 0);

            }

        });
    };

    jQuery.fn.getAllCheckedText = function() {
        var allPathTxt = "";
        var pathArr = [];
        this.find("input:checkbox:checked").each(function() {

            var pathTxt = $(this).parents("li")
              .map(function() {
                  var txt = $(this).find("input:first:checkbox").val();
                  return txt;
              })
              .get().reverse().join(">");
            pathArr.push(pathTxt);
        });
        var pathStr = pathArr.join(";");
        var rtnArr = [];
        for (p = 0; p < pathArr.length; p++) {
            if (pathStr.replace(pathArr[p], "").match(pathArr[p]) == null)
                rtnArr.push(pathArr[p]);
        }
        return rtnArr.join(";");
    };

    jQuery.fn.getAllCheckedValue = function() {
        var allPathTxt = "";
        var pathArr = [];
        this.find("input:checkbox:checked").each(function() {

            var pathTxt = $(this).parents("li")
              .map(function() {
                var txt = $(this).find("input:first:checkbox").attr("id");
                  return txt;
              })
              .get().reverse().join(">");
            pathArr.push(pathTxt);
        });
        var pathStr = pathArr.join(";");
        var rtnArr = [];
        for (p = 0; p < pathArr.length; p++) {
            if (pathStr.replace(pathArr[p], "").match(pathArr[p]) == null)
                rtnArr.push(pathArr[p]);
        }
        return rtnArr.join(";");
    };

    jQuery.fn.setAllCheckedValue = function(txt) {

    };

})(jQuery);

function treeview(data) {
    var htm = "";
    for (b = 0; b < data.length; b++) {
        var binfo = data[b];
        var bID = binfo['id'];
        var bTxt = binfo['text'];
        var bChecked = binfo['selected'];
        var bChildren = binfo['children'];
        
        htm += "<li><input type='checkbox' id='" + bID + "' value='" + bTxt + "'/><label>" + bTxt + "</label>";

        if (bChildren != null) {
            htm += "<ul></ul>";
        }
        htm += "</li>";
    }
    return htm;
}

function childrenobject(id) {
    var children = null;
    var data = jsondata;    
    for (b = 0; b < data.length; b++) {
        var binfo = data[b];
        var bID = binfo['id'];
        var bChildren = binfo['children'];
        if (bID == id)
            children = bChildren;
        else if (bChildren != null) {            
            for (m = 0; m < bChildren.length; m++) {

                var minfo = bChildren[m];
                var mid = minfo["id"];            
                var mchildren = minfo["children"];
                if (mid == id)
                    children = mchildren;            
            }            
        }
    }
    return children;
}

function getIDFromTxt(txt) {
    var data = jsondata;
    
    for (b = 0; b < data.length; b++) {
        var binfo = data[b];
        var bID = binfo['id'];
        var bTxt = binfo['text'];
        var bChildren = binfo['children'];

        if (bTxt == txt)
            return bID;
        else if (bChildren != null) {
            for (m = 0; m < bChildren.length; m++) {

                var minfo = bChildren[m];
                var mid = minfo["id"];
                var mtxt = minfo["text"];
                var mChildren = minfo["children"];
                if (mtxt == txt)
                    return mid;
                else if (mChildren != null) {
                    for (s = 0; s < mChildren.length; s++) {
                        var sinfo = mChildren[s];
                        var sid = sinfo["id"];
                        var stxt = sinfo["text"];
                        var sChildren = sinfo["children"];
                        if (stxt == txt)
                            return sid;
                    }
                }
            }
        }
    }
    
}


