/*
 * XMLTreeModel.java
 *
 * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard
 *
 * This file is part of BEAST.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership and licensing.
 *
 * BEAST is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 *  BEAST is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BEAST; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

package dr.app.bfe;

import dr.xml.XMLModelFile;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;

/**
 * Package: XMLTreeModel
 * Description:
 * <p/>
 * <p/>
 * Created by
 *
 * @author Alexander V. Alekseyenko (alexander.alekseyenko@gmail.com)
 *         Date: Apr 14, 2009
 *         Time: 11:07:19 PM
 */
public class XMLTreeModel implements TreeModel {
    protected class ElementObject {
        public Element element;
        protected LinkedList<ElementObject> children;
        protected String id;

        ElementObject(Element element) {
            this.element = element;
            id = "";
            Attribute idAttribute = element.getAttribute("id");
            if (idAttribute == null) {
                idAttribute = element.getAttribute("idref");
            }
            if (idAttribute != null) {
                id = idAttribute.getValue();
            }
            children = null;
        }

        public String toString() {
            if (element == null)
                return "<<Empty>>";
            return element.getName() + ":" + id;
        }

        public String getId() {
            return id;
        }

        public LinkedList<ElementObject> getChildren() {
            if (children != null) {
                return children;
            }
            children = new LinkedList<ElementObject>();
            if (element == null)
                return children;
            for (Object child : element.getChildren()) {
                if (child instanceof Element) {
                    children.add(new ElementObject((Element) child));
                }
            }
            return children;
        }

    }

    public ElementObject getRootElement() {
        return rootElement;
    }

    public XMLModelFile getXmlModel() {
        return xmlModel;
    }

    private ElementObject rootElement;
    XMLModelFile xmlModel;

    XMLTreeModel(String filename) {

        SAXBuilder parser = new SAXBuilder();

        Document doc;
        try {
            doc = parser.build(new File(filename));
            rootElement = new ElementObject(doc.getRootElement());
            xmlModel = new XMLModelFile(doc.getRootElement());
        }
        catch (IOException e) {
            System.err.println("Error opening file " + filename);
            rootElement = new ElementObject(null);
        }
        catch (JDOMException e) {
        }
    }

    // TreeModel method implementation
    public Object getRoot() {
        return rootElement;  //AUTOGENERATED METHOD IMPLEMENTATION
    }

    public Object getChild(Object o, int i) {
        if (!(o instanceof ElementObject)) {
            return null;
        }

        if (i < ((ElementObject) o).getChildren().size()) {
            return ((ElementObject) o).getChildren().get(i);
        }
        return null;
    }

    public int getChildCount(Object o) {
        return ((ElementObject) o).getChildren().size();
    }

    public boolean isLeaf(Object o) {
        return ((ElementObject) o).getChildren().size() == 0;  //AUTOGENERATED METHOD IMPLEMENTATION
    }

    public void valueForPathChanged(TreePath treePath, Object o) {
        //AUTOGENERATED METHOD IMPLEMENTATION
    }

    public int getIndexOfChild(Object o, Object o1) {
        LinkedList<ElementObject> children = ((ElementObject) o).getChildren();
        for (int i = 0; i < children.size(); ++i) {
            if (o1 == children.get(i))
                return i;
        }
        return -1;
    }

    public void addTreeModelListener(TreeModelListener treeModelListener) {
        //AUTOGENERATED METHOD IMPLEMENTATION
    }

    public void removeTreeModelListener(TreeModelListener treeModelListener) {
        //AUTOGENERATED METHOD IMPLEMENTATION
    }
}
