function sqTree(treeElementId) {
    this.treeElementId = treeElementId;
    this.items = [];
    this.itemsData = {};
    this.xhr = null;
    this.httpLastRequestUrl = "";
    this.appendItems = {
        id: -1,
        item: []
    };
    this.checkboxesEnabled = false;
    this.onCheckChanged = null;
    this.init();
}

sqTree.fn = sqTree.prototype;

sqTree.fn.init = function () {
    this.treeElement = document.getElementById(this.treeElementId);
    if (this.treeElement == undefined) {
        return;
    }
    this.treeElement.sqTree = this;
    this.treeElement.innerHTML = "";
    this.treeElement.classList.add("sq-tree");
    this.treeElementInner = document.createElement("div");
    this.treeElementInner.classList.add("sq-tree-inner");
    this.treeElement.appendChild(this.treeElementInner);
    var thisComponent = this;
    this.treeElementInner.addEventListener("dblclick", function (e) {
        e.stopPropagation();
        thisComponent.dblClickCallback(e);
    });
    this.treeElementInner.addEventListener("click", function (e) {
        e.stopPropagation();
        thisComponent.clickCallback(e);
    });
    this.treeElementInner.addEventListener("mousemove", function (e) {
        thisComponent.mousemoveCallback(e);
    });
    this.redraw();
};

sqTree.fn.enableCheckboxes = function (enable) {
    this.checkboxesEnabled = (enable || enable == undefined);
};

sqTree.fn.load = function (url, callback) {
    var thisComponent = this;
    this.makeHttpRequest(url, function (data) {
        var dataJson = JSON.parse(data);
        if ("item" in dataJson) {
            thisComponent.items = dataJson.item;
        } else {
            thisComponent.items = [];
        }
        thisComponent.redraw();
        if (callback) {
            callback();
        }
    });
}


sqTree.fn.loadJson = function (dataJson) {
    if ("item" in dataJson) {
        this.items = dataJson.item;
    } else {
        this.items = [];
    }
    this.redraw();
}

sqTree.fn.dblClickCallback = function (e) {
    if (e.target.classList.contains("item")) {
        var name = e.target.innerText;
        var id = e.target.getAttribute('data-id');
        var fileType = e.target.getAttribute('data-type');
        var filePath = e.target.getAttribute('data-path');
        if (this.onDblClick != undefined) {
            this.onDblClick(fileType, filePath, id, name);
        }
    }
}

sqTree.fn.clickCallback = function (e) {
    if (e.target.classList.contains("sq-tree-checkbox")) {
        e.stopPropagation();
        $(e.target.parentElement).next(".items-level").find(".sq-tree-checkbox").prop('checked', e.target.checked);
        if (this.onCheckChanged != null) {
            this.onCheckChanged();
        }
        return;
    }
    var element = false;
    if (e.target.classList.contains("item")) {
        element = e.target;
    } else if (e.target.parentElement.classList.contains("item")) {
        element = e.target.parentElement;
    }
    if (element) {
        var name = element.innerText;
        var id = element.getAttribute('data-id');
        var fileType = element.getAttribute('data-type');
        var filePath = element.getAttribute('data-path');
        $(this.treeElementInner).find(".item.selected").removeClass("selected");
        element.classList.add("selected");
        if (this.onClick != undefined) {
            this.onClick(fileType, filePath, id, name, element, e);
        }
        if (element.classList.contains("hasfiles")) {
            if (element.classList.contains("expanded")) {
                element.classList.remove("expanded");
            } else {
                element.classList.add("expanded");
            }
        }
    }
    /* if (this.onClick != undefined) {
        this.onClick();
    } */
}


sqTree.fn.mousemoveCallback = function (e) {
    if (e.target.classList.contains("item")) {
        var name = e.target.innerText;
        var id = e.target.getAttribute('data-id');
        var fileType = e.target.getAttribute('data-type');
        var filePath = e.target.getAttribute('data-path');
        if (this.mouseIn != undefined) {
            this.mouseIn(fileType, filePath, id, name, e.target);
        }
    } else if (e.target.parentElement.classList.contains("item")) {
        var name = e.target.parentElement.innerText;
        var id = e.target.parentElement.getAttribute('data-id');
        var fileType = e.target.parentElement.getAttribute('data-type');
        var filePath = e.target.parentElement.getAttribute('data-path');
        if (this.mouseIn != undefined) {
            this.mouseIn(fileType, filePath, id, name, e.target);
        }
    } else {
        if (this.mouseOut != undefined) {
            this.mouseOut();
        }
    }
}

sqTree.fn.expandAll = function () {
    $(this.treeElementInner).find(".item.hasfiles").addClass("expanded");
}

sqTree.fn.collapseAll = function () {
    $(this.treeElementInner).find(".item.hasfiles.expanded").removeClass("expanded");
}

sqTree.fn.expandItemWithName = function (itemName) {
    $(this.treeElementInner).find(".item.hasfiles:contains('" + itemName + "')").addClass("expanded");
}

sqTree.fn.expandLevels = function (levelToExpand) {
    if (levelToExpand == undefined) {
        levelToExpand = 0;
    }
    var preStrings = ".sq-tree-inner>";
    var selectorArray = [];
    for (var i = 0; i < levelToExpand; i++) {
        selectorArray.push(".items-level");
        var selectorString = preStrings + selectorArray.join(">") + ">.item.hasfiles";
        $(this.treeElement).find(selectorString).addClass("expanded");
    }
}

sqTree.fn.appendItemsTo = function (id, items) {
    this.appendItems = {
        id: id,
        item: items
    };
}

sqTree.fn.redraw = function () {
    this.itemsData = {};
    this.treeElementInner.innerHTML = this.drawOneLevel(this.items);
}

sqTree.fn.drawOneLevel = function (items) {
    var html = "";
    html += "<div class=\"items-level\">";
    for (var i = 0; i < items.length; i++) {
        var fileType = "";
        var filePath = "";
        var additionalClass = "";
        if (this.appendItems.id == items[i].id) {
            items[i].item = this.appendItems.item;
            this.appendItems = {
                id: -1,
                item: []
            };
        }
        this.itemsData[items[i].id] = {};
        if ("userdata" in items[i]) {
            for (var j = 0; j < items[i].userdata.length; j++) {
                if (items[i].userdata[j].name == "fileType") {
                    fileType = items[i].userdata[j].content;
                }
                if (items[i].userdata[j].name == "file") {
                    filePath = items[i].userdata[j].content;
                }
                this.itemsData[items[i].id][items[i].userdata[j].name] = items[i].userdata[j].content;
            }
        }
        additionalClass += " " + fileType;
        var icoClass = "";
        if ("im0" in items[i] && items[i].im0 != "") {
            var icoClass = " " + items[i].im0.split(".")[0];
        }
        if ("item" in items[i] || icoClass == " folderClosed") {
            additionalClass += " hasfiles";
        }

        if (icoClass == " leaf") {
            additionalClass += " file";
        }
        var htmlCheckbox = "";
        if (this.checkboxesEnabled) {
            htmlCheckbox = "<input type=\"checkbox\" id=\"sq-tree-checkbox-" + items[i].id + "\" class=\"sq-tree-checkbox\" />";
        }
        html += "<div class=\"item" + additionalClass + "\" data-id=\"" + items[i].id + "\" data-type=\"" + fileType + "\" data-path=\"" + filePath + "\" data-text=\"" + encodeURI(items[i].text) + "\">" + htmlCheckbox + "<span class=\"ico" + icoClass + "\"></span>" + items[i].text + "</div>";
        if ("item" in items[i]) {
            html += this.drawOneLevel(items[i].item);
        }
    }
    html += "</div>";
    return html;
}

sqTree.fn.getUserData = function (id, itemName) {
    if (id in this.itemsData && itemName in this.itemsData[id]) {
        return this.itemsData[id][itemName];
    } else {
        return false;
    }
}

sqTree.fn.findIdByUserData = function (userDataName, userDataValue) {
    for (singleId in this.itemsData) {
        if (this.itemsData[singleId][userDataName] && this.itemsData[singleId][userDataName]==userDataValue) {
            return singleId;
        }
    }
    return -1;
}

sqTree.fn.makeHttpRequest = function (url, callback) {
    /*     if (this.httpLastRequestUrl == url) {
            this.redraw();
            return;
        } */

    this.httpLastRequestUrl = url;

    if (this.xhr != null) {
        this.xhr.abort();
    }

    this.xhr = new XMLHttpRequest();
    this.xhr.onreadystatechange = function () {
        if (this.readyState == 4) {
            if (this.status == 200) {
                callback(this.responseText);
            } else {
                // if (errorCallback) errorCallback();
            }
        }
    };
    this.xhr.open("GET", url, true);
    this.xhr.send(null);
};

sqTree.fn.getCheckedItems = function () {
    var checkBoxes = $(this.treeElementInner).find(".sq-tree-checkbox:checkbox:checked");
    var returnArray = [];
    for (var i = 0; i < checkBoxes.length; i++) {
        if (checkBoxes[i].parentElement.classList.contains("hasfiles")) {
            continue;
        }
        returnArray.push(checkBoxes[i].parentElement.getAttribute('data-id'));
    }
    return returnArray;
}