package cnp.ew.list;

import java.awt.*;
import java.util.*;
import cnp.ew.util.*;
import cnp.ew.displayer.*;
import cnp.ew.converter.*;
import cnp.ew.properties.*;

public class CpDefaultTreeModel extends CpDefaultObservable implements CpTreeModel
{
    Vector flatList;

    public CpDefaultTreeModel(Vector itemList)
    {
        CpTreeItem item;

        flatList = new Vector();

        for (int i = 0; i < itemList.size(); i++) {
            item = (CpTreeItem)itemList.elementAt(i);
            flatList.addElement(new CpTreeItemHolder(item, 0, false));
        }
    }

    public Object getItem(int index)
    {
        return ((CpTreeItemHolder)flatList.elementAt(index)).getItem();
    }

    public void setItem(int index, Object o)
    {
        flatList.setElementAt(o, index);
    }

    public int getSize()
    {
        return flatList.size();
    }

    public Object getProperty(int index, CpProperty property)
    {
        CpListItem item = (CpListItem)getItem(index);
        return item.getProperty(property);
    }

    public void setProperty(int index, CpProperty property, Object o)
    {
        CpListItem item = (CpListItem)getItem(index);
        item.setProperty(property, o);
    }

    public CpModelSelectableDisplayable getDisplayer(int index, CpProperty property)
    {
        return property.getType().getDefaultDisplayer();
    }

    public CpToStringConverter getConverter(int index, CpProperty property)
    {
        return property.getType().getDefaultConverter();
    }

    public int getIndentLevel(int index)
    {
        return ((CpTreeItemHolder)flatList.elementAt(index)).getIndentLevel();
    }

    public boolean getIsExpanded(int index)
    {
        return ((CpTreeItemHolder)flatList.elementAt(index)).getIsExpanded();
    }

    public boolean getHasChildren(int index)
    {
        return ((CpTreeItem)getItem(index)).getHasChildren();
    }

    public void expandIndex(int index)
	{
	    int removed = 0;

	    CpTreeItemHolder itemHolder = (CpTreeItemHolder)flatList.elementAt(index);
	    CpTreeItemHolder tempItemHolder;

        if (getIsExpanded(index)) {
            itemHolder.setIsExpanded(false);
			do {
				tempItemHolder = (CpTreeItemHolder)flatList.elementAt(index + 1);
				if (tempItemHolder.getIndentLevel() > itemHolder.getIndentLevel()) {
					flatList.removeElementAt(index + 1);
					removed++;
				}
			} while ((index + 1 < getSize()) && (tempItemHolder.getIndentLevel() > itemHolder.getIndentLevel()));
			if (removed > 0) {
			    // Probably should not be a Point.  Some kind of "Range" or something
			    notifyObservers(CpEvent.LISTMODEL_DELETE, new Point(index + 1, removed));
			}
        } else if (getHasChildren(index)) {
			itemHolder.setIsExpanded(true);

			Vector children = ((CpTreeItem)getItem(index)).getChildren();
			for (int i = children.size(); i > 0; i--) {
			    tempItemHolder = new CpTreeItemHolder((CpTreeItem)children.elementAt(i - 1), itemHolder.getIndentLevel() + 1, false);
				flatList.insertElementAt(tempItemHolder, index + 1);
			}
			notifyObservers(CpEvent.LISTMODEL_INSERT, new Point(index + 1, children.size()));
		}
	}
}

