/*
 * ICESOFT COMMERCIAL SOURCE CODE LICENSE V 1.1
 *
 * The contents of this file are subject to the ICEsoft Commercial Source
 * Code License Agreement V1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of the
 * License at
 * http://www.icesoft.com/license/commercial-source-v1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * Copyright 2009-2015 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 */
package com.icesoft.faces.facelets.component.treetable;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.event.ActionEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

import com.icesoft.faces.component.dragdrop.DropEvent;
import com.icesoft.faces.component.tree.IceUserObject;

public class TreeTableNode implements Serializable {

    //colours used for the different treeTable levels
    protected String[] levelColours = {"#FFCC00", "#FFCC66", "#FFCC99", "#FFCCCC", "#FFCCFF"};
    protected TreeTable treeTable;
    protected IceUserObject userObject;
    protected DefaultMutableTreeNode treeNodeRef;
    protected TreeModel treeModel;
    protected Object data;
    private TreeTableNode parent;
    private List children;

    public TreeTableNode(TreeTable treeTable, Object data) {
        treeNodeRef = new DefaultMutableTreeNode();
        this.treeModel = new DefaultTreeModel(treeNodeRef);
        this.treeTable = treeTable;
        initializeTreeNode();
        this.data = data;
        this.children = new ArrayList();
    }

    public TreeTableNode(TreeTableNode parent, Object data) {
        treeNodeRef = new DefaultMutableTreeNode();
        parent.treeNodeRef.add(treeNodeRef);
        this.treeModel = parent.getTreeModel();
        parent.userObject.setLeaf(false);
        initializeTreeNode();
        this.data = data;
        this.parent = parent;
        this.parent.children.add(this);
        this.children = new ArrayList();
    }

    private void initializeTreeNode() {
        userObject = new IceUserObject(treeNodeRef);
        treeNodeRef.setUserObject(userObject);
        userObject.setLeafIcon("/xmlhttp/css/xp/css-images/tree_document.gif");
        userObject.setBranchContractedIcon(
                "/xmlhttp/css/xp/css-images/tree_folder_close.gif");
        userObject.setBranchExpandedIcon("/xmlhttp/css/xp/css-images/tree_folder_open.gif");
        userObject.setLeaf(true);
    }

    public TreeModel getTreeModel() {
        return treeModel;
    }


    public void appendNode(TreeTableNode child) {
        userObject.setLeaf(false);
        child.parent = this;
        treeNodeRef.add(child.treeNodeRef);
        this.children.add(child);
    }

    public void removeChildNode(TreeTableNode child) {
        child.treeNodeRef.removeFromParent();
        this.children.remove(child);
    }

    public String getStyle() {
        return "background-color: " + levelColours[treeNodeRef.getDepth()] + ";";
    }

    public void toggleRow(ActionEvent evt) {
        if (!treeNodeRef.isLeaf()) {
            userObject.setExpanded(!userObject.isExpanded());
            getTreeTable().rebuildList();
        }
    }

    public void nodeMoved(DropEvent evt) {
        TreeTableNode target = (TreeTableNode) evt.getTargetDragValue();
        if (treeNodeRef.isNodeAncestor(target.treeNodeRef)) {
            return;
        }

        ITreeTableListener listener = getTreeTable().getListener();
        if (listener == null || listener.isNodeMoveAllowed(this, target)) {
            target.parent.removeChildNode(target);
            this.appendNode(target);
            userObject.setExpanded(true);
            getTreeTable().rebuildList();
        }
        getTreeTable().updateTimestamp();
    }

    private TreeTable getTreeTable() {
        TreeTableNode node = this;
        while (node.parent != null) {
            node = node.parent;
        }
        return node.treeTable;
    }

    public List getChildren() {
        return children;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public List getLevelList() {
        List list = new ArrayList();
        for (int i = 0; i < treeNodeRef.getLevel(); i++) {
            list.add(new Object());
        }
        return list;
    }

    public boolean isLeaf() {
        return userObject.isLeaf();
    }

    public String getIcon() {
        return userObject.getIcon();
    }

    public int getLevel() {
        return treeNodeRef.getLevel();
    }

    public boolean isExpanded() {
        return userObject.isExpanded();
    }

    public void setExpanded(boolean expanded) {
        this.userObject.setExpanded(expanded);
    }

}

