/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.ctecinf.swing;

import br.com.ctecinf.event.SelectEvent;
import br.com.ctecinf.event.SelectListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.Serializable;
import javax.swing.JTree;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author Cássio Conceição
 * @since 03/07/2019
 * @version 201907
 * @see http://ctecinf.com.br/
 */
public class TreeFile extends JTree {

    private SelectListener listener;

    public TreeFile(String path) {
        this(new File(path));
    }

    public TreeFile(File root) {

        setModel(new Model(root));

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    if (listener != null) {
                        listener.onSelected(new SelectEvent(TreeFile.this, e.getID(), getSelectedFile()));
                    }
                }
            }
        });
    }

    public void addSelectListener(SelectListener sl) {
        listener = sl;
    }

    protected File getSelectedFile() {
        return (File) getSelectionPath().getLastPathComponent();
    }

    public void expandAll() {
        expandAll(0, getRowCount());
    }

    private void expandAll(int startingIndex, int rowCount) {

        for (int i = startingIndex; i < rowCount; ++i) {
            expandRow(i);
        }

        if (getRowCount() != rowCount) {
            expandAll(rowCount, getRowCount());
        }
    }

    protected class Model implements TreeModel, Serializable {

        protected File root;

        public Model(String path) {
            this(new File(path));
        }

        public Model(File root) {
            this.root = root;
        }

        @Override
        public Object getRoot() {
            return root;
        }

        @Override
        public boolean isLeaf(Object node) {
            return ((File) node).isFile();
        }

        @Override
        public int getChildCount(Object parent) {

            String[] children = ((File) parent).list();

            if (children == null) {
                return 0;
            }

            return children.length;
        }

        @Override
        public Object getChild(Object parent, int index) {

            String[] children = ((File) parent).list();

            if ((children == null) || (index >= children.length)) {
                return null;
            }

            return new File((File) parent, children[index]) {
                @Override
                public String toString() {
                    return getName();
                }
            };
        }

        @Override
        public int getIndexOfChild(Object parent, Object child) {

            String[] children = ((File) parent).list();

            if (children == null) {
                return -1;
            }

            String childname = ((File) child).getName();

            for (int i = 0; i < children.length; i++) {
                if (childname.equals(children[i])) {
                    return i;
                }
            }

            return -1;
        }

        @Override
        public void valueForPathChanged(TreePath path, Object newvalue) {
        }

        @Override
        public void addTreeModelListener(TreeModelListener listener) {
        }

        @Override
        public void removeTreeModelListener(TreeModelListener l) {
        }

    }
}
