
import {Widget} from "widget/Widget";
import {EventHub} from "event/EventHub";
import {MessageType} from "event/MessageType";
import {Event} from "event/Event";
import {Keys} from "hotkey/Keys";
import {ADORE} from "ADORE";
import {Tree} from "widget/tree/Tree";
import {Composite} from "widget/Composite";

export class TreeItem extends Composite {

    private static TemplateNormal = `
        <li class="bold adore_tree" >
            <div class="adore_tree_node_checkbox_simple">	
                <input type="checkbox" class="filled-in">	
                <label style="font-size: 0;line-height: 16px;"></label>
            </div>
            <a href="#" class="waves-effect adore_tree_a adore_tree_simple_a">
                <span></span>
            </a>
        </li>`;

    private static TemplateComplex = `
        <li class="no-padding adore_tree">
            <ul class="collapsible collapsible-accordion adore_tree">
                <li class="bold adore_tree">

                    <div class="adore_tree_node_circle adore_circle waves-effect" expand="false"><div class="adore_addcharpan">+</div></div>

                    <div class="adore_tree_node_checkbox_complex">
                        <input type="checkbox" class="filled-in">
                        <label style="font-size: 0;line-height: 16px;"></label>
                    </div>
                    
                    <a class="collapsible-header waves-effect adore_tree_a adore_tree_complex_a">
                        <span></span>
                        <span class="adore_tree_node_arrow">></span>
                    </a>

                    <div class="collapsible-body adore_tree adore_tree_ul_div">
                        <ul>

                        </ul>
                    </div>
                </li>
            </ul>
        </li>`;

    children = new Array();
    $attachNode: JQuery;
    $a: JQuery;
    hadChildren: boolean;
    isTreeItem: boolean;
    treeId: string;
    text: string;
    $ul: JQuery;
    $checkboxNode: JQuery;
    checkboxId: string;
    $circleNode: JQuery;
    timeoutFunc: number;

    constructor(parentId: string, id: string, style: number) {
        super(parentId, id, style);

        this.children = new Array();
        // init时，是普通节点
        this.$thisNode = $(TreeItem.TemplateNormal).attr("id", this.id);
        this.$attachNode = this.$thisNode;
        this.$a = this.$thisNode.find("a");
        this.hadChildren = false;
        this.isTreeItem = true;
        if (this.parent) {
            this.treeId = (<Tree>this.parent).treeId;
        }

        let itemId = this.id;
        let own = this;
        // 添加click事件
        this.$a.on("click", function (e) {
            clearTimeout(own.timeoutFunc);
            own.timeoutFunc = setTimeout(function () {
                own.handleClick(itemId, own.$attachNode);
            }, 300);
        });
        this.$a.on("dblclick", function (e) {
            clearTimeout(own.timeoutFunc);
            own.handleDBClick(itemId, $(this.parentNode));
        });

        // 完成复选框相关逻辑
        this.$checkboxNode = this.$attachNode.find("div").eq(0);
        this.checkboxId = "";
        // 为复选框添加click事件
        var tmpId = this.treeId;
        this.$checkboxNode.find("input").eq(0).on("click", function (e) {
            own.refreshCheckState();
            EventHub.dispatchEvent(MessageType.WIDGET, {
                id: own.treeId,
                evtType: Event.ON_CHANGE,
                cid: own.id,
                checked: own.$checkboxNode.find("input").eq(0).prop("checked")
            });
        });

    }

    public addChild(child: Widget) {
        this.children.push(child);
    }

    public layout() {
        this.append();
        if (this.parent) {
            let treeNode = (<Tree>this.parent).$thisNode.find(".collapsible");
            if (treeNode) {
                treeNode.collapsible();
            }
        }
    }

    private handleDBClick(itemId: string, $itemNode: JQuery) {
        this.clickCircle(itemId,$itemNode);
        EventHub.dispatchEvent(MessageType.WIDGET, { id: itemId, treeId: this.treeId, evtType: Event.DOUBLE_CLICK });
    }

    private clickCircle(itemId: string, $itemNode: JQuery) {
        let tmpId = this.treeId;
        let tree = $("#" + tmpId);
        tree.find("li.bold").removeClass("adore_tree_node_selected");
        $itemNode.addClass("adore_tree_node_selected");
        let treeNodeCircle = $itemNode.find("div.adore_tree_node_circle").first();
        if (treeNodeCircle.length !== 0) {
            let arrowSpan = $itemNode.find("span.adore_tree_node_arrow").first();
            let circleDiv = treeNodeCircle.find("div");
            //说明是复杂节点，需要展开
            if (treeNodeCircle.attr("expand") === "false") {
                treeNodeCircle.attr("expand", "true");
                treeNodeCircle.removeClass("adore_circle").addClass("adore_mincircle");
                circleDiv.text("-");
                circleDiv.removeClass("adore_addcharpan").addClass("adore_mincharpan");
                arrowSpan.addClass("adore_tree_node_arrow_click");
            } else {
                treeNodeCircle.attr("expand", "false");
                treeNodeCircle.removeClass("adore_mincircle").addClass("adore_circle");
                circleDiv.text("+");
                circleDiv.removeClass("adore_mincharpan").addClass("adore_addcharpan");
                arrowSpan.removeClass("adore_tree_node_arrow_click");
            }
        }
    }

    public handleClick(itemId: string, $itemNode: JQuery) {
        this.clickCircle(itemId,$itemNode);
        EventHub.dispatchEvent(MessageType.WIDGET, { id: itemId, treeId: this.treeId, evtType: Event.CLICK });
    }

    public changeParentStyle() {
        let parent: TreeItem = <TreeItem>this.parent;
        if (!parent.hadChildren) {
            // 取得当前节点的后一个节点
            // let $nextNode = parent.$thisNode.next();
            // 用复杂节点替换原来的普通节点
            parent.$thisNode.remove();
            // 复杂节点
            parent.$thisNode = $(TreeItem.TemplateComplex).attr("id", parent.id);
            parent.$attachNode = parent.$thisNode;
            parent.$a = parent.$thisNode.find("a");
            //let tmpId = this.treeId;
            let own = parent;
            let itemId = parent.id;
            // 找到对应的小圆圈
            parent.$circleNode = parent.$attachNode.find("div.adore_tree_node_circle").first();
            // 添加click事件
            parent.$a.on("click", function (e) {
                clearTimeout(own.timeoutFunc);
                own.timeoutFunc = setTimeout(function () {
                    own.handleClick(itemId, parent.$attachNode);
                });
            });
            parent.$a.on("dblclick", function (e) {
                clearTimeout(own.timeoutFunc);
                own.handleDBClick(itemId, parent.$attachNode);
            });
            parent.$circleNode.on("click", function (e) {
                own.$a.click();
            });

            parent.$ul = parent.$thisNode.find("ul.collapsible").find("ul");
            parent.hadChildren = true;
            if (parent.text) {
                parent.setText({text : parent.text});
                // parent.$a.text(parent.text);
            }
            

            // 完成checkbox相关逻辑
            let display = parent.$checkboxNode.css("display");
            parent.$checkboxNode = $((<TreeItem>this.parent).$attachNode.find("div").get(2));
            parent.refreshCheckId((<TreeItem>this.parent).checkboxId);
            parent.$checkboxNode.css("display", display);
            var tempParent: TreeItem = <TreeItem>this.parent;
            var tmpId = this.treeId;
            parent.$checkboxNode.find("input").eq(0).on("click", function (e) {
                tempParent.refreshCheckState();
                EventHub.dispatchEvent(MessageType.WIDGET, {
                    id: tmpId,
                    evtType: Event.ON_CHANGE,
                    cid: own.id,
                    checked: tempParent.$checkboxNode.find("input").eq(0).prop("checked")
                })
            });

            //append
            if (this.parent.parent) {
                // 如果父亲是树
                if (this.parent.parent instanceof Tree) {
                    (<TreeItem>this.parent).$thisNode.appendTo((<Tree>this.parent.parent).$attachNode);
                } else if (this.parent.parent instanceof TreeItem) {
                    let $liChildNodes = (<TreeItem>this.parent.parent).$ul.children("li");
                    let size = $liChildNodes.length;
                    // 在父元素中的位置
                    let index = this.parent.parent.children.indexOf(this.parent);
                    if (index < size) {
                        (<TreeItem>this.parent).$thisNode.insertBefore($liChildNodes.eq(index));
                    } else {
                        (<TreeItem>this.parent).$thisNode.appendTo((<TreeItem>this.parent.parent).$ul);
                    }
                }
            } else {
                (<TreeItem>this.parent).$thisNode.appendTo(document.body);
            }
        }
    }

    public append() {
        if (this.parent) {
            if ((<TreeItem>this.parent).isTreeItem) {
                this.changeParentStyle();
                this.$thisNode.appendTo((<TreeItem>this.parent).$ul);
            } else {
                this.$thisNode.appendTo(this.parent.$attachNode);
            }
        } else {
            this.$thisNode.appendTo(document.body);
        }
    }

    public setText(args: { text: string }) {
        this.text = args.text;
        this.$a.find("span").first().text(this.text);
    }

    public setCheckboxId(args: { checkboxId: string }) {
        this.checkboxId = args.checkboxId;
        this.refreshCheckId(this.checkboxId);
    }

    public refreshCheckId(checkboxId: string) {
        this.$checkboxNode.find("input").attr("id", checkboxId);
        this.$checkboxNode.find("label").attr("for", checkboxId);
    }

    public viewCheckbox(args: { viewCheckbox: boolean }) {
        this.refreshViewCheckbox(args.viewCheckbox);
    }

    public refreshViewCheckbox(viewCheckbox: boolean) {
        if (viewCheckbox) {
            this.$checkboxNode.css("display", "block");
        } else {
            this.$checkboxNode.css("display", "none");
        }
    }

    public refreshCheckState() {
        // 更新节点的选中状态
        var $checkbox = this.$checkboxNode.find("input").eq(0);
        var checked = $checkbox.prop("checked");
        // 把所有儿子都设置成为选中状态
        this.$attachNode.find("input").prop("checked", checked);
        this.$attachNode.find("input").prop("indeterminate", false);
        // 更新父亲的状态
        var father = this.parent;
        while (father && father instanceof TreeItem) {
            //  0 永远为true，1永远为false，2中间状态
            var state = -1;
            var $checkboxes = father.$attachNode.find("input");
            // 获取checkbox的数量?????????????????????????????????????????????????????????
            var checkboxSize = $checkboxes.length;
            for (var i = 1; i < checkboxSize; i++) {
                var checkedTmp = $checkboxes.eq(i).prop("checked");
                if (checkedTmp) {
                    if (state == -1) {
                        state = 0;
                    } else if (state != 0) {
                        state = 2;
                        break;
                    }
                } else {
                    if (state == -1) {
                        state = 1;
                    } else if (state != 1) {
                        state = 2;
                        break;
                    }
                }
            }
            var $checoboxTmp = father.$attachNode.find("input").eq(0);
            if (state == 0) {
                $checoboxTmp.prop("checked", true);
                $checoboxTmp.prop("indeterminate", false);
            } else if (state == 1) {
                $checoboxTmp.prop("checked", false);
                $checoboxTmp.prop("indeterminate", false);
            } else {
                $checoboxTmp.prop("checked", false);
                $checoboxTmp.prop("indeterminate", true);
            }
            father = father.parent;
        }
    }

    // 设置节点的checkbox状态
    public setCheckboxState(checkboxState: boolean) {
        this.$checkboxNode.find("input").eq(0).prop("checked", checkboxState);
        this.$checkboxNode.find("input").eq(0).prop("indeterminate", false);
    }

    public needRedForground(args: { needRedForground: boolean }) {
        let needRedForground = args.needRedForground;
        // 然后设置
        if (needRedForground) {
            // 需要变为红色
            this.$a.css("color", "red");
        } else {
            this.$a.css("color", "#444");
        }
    }

}