package adapters;

import hu.swankey.ammo.common.script.yunits.YClass;
import hu.swankey.ammo.common.yggdrasil.Yggdrasil;
import hu.swankey.ammo.common.yggdrasil.basics.ComplexYObject.ComplexYClass;
import hu.swankey.ammo.common.yggdrasil.definition.AttributeDefinition;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.TreeSet;

import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;

public class FieldListModel implements ListModel, TreeModelListener {
	
	private final ComplexYClass yclass;
	private final ArrayList<ListDataListener> listeners = new ArrayList<ListDataListener>();	
	private AttributeDefinition[] fields = new AttributeDefinition[0];

		
	public static FieldListModel create(ComplexYClass yclass, Yggdrasil yggdrasil){
		FieldListModel model = new FieldListModel(yclass);
		yggdrasil.getTreeModel( yclass.getWrapperElement() ).addTreeModelListener(model);
		return model;
	}
	
	private FieldListModel(ComplexYClass yclass){
		this.yclass = yclass;
		regenerate();
	}
		public ComplexYClass getYClass(){
		return yclass;
	}
	
	private void regenerate(){
		TreeSet<AttributeDefinition> sortedset = new TreeSet<AttributeDefinition>(new Comparator<AttributeDefinition>(){
			@Override
			public int compare(AttributeDefinition o1, AttributeDefinition o2) {
				boolean o1Direct = yclass.getFields().contains(o1);
				boolean o2Direct = yclass.getFields().contains(o2);
				
				if (o1Direct == o2Direct)				
					return o1.getName().compareTo(o2.getName());
				else
					return (o1Direct ? -1 : 1);
			}
		});
		
		
		collectFields(yclass, sortedset);
		fields = sortedset.toArray(new AttributeDefinition[sortedset.size()]);
	}
	
	
	private void collectFields(ComplexYClass yclass, Collection<AttributeDefinition> collection){
		collection.addAll(yclass.getFields());
		for(YClass superior: yclass.getSuperiors())
			if (superior instanceof ComplexYClass)
			collectFields((ComplexYClass)superior, collection);
	}

	@Override
	public void addListDataListener(ListDataListener l) {
		listeners.add(l);
	}
	
	@Override
	public void removeListDataListener(ListDataListener l) {
		listeners.remove(l);
	}	

	@Override
	public Object getElementAt(int index) {
		return fields[index];
	}

	@Override
	public int getSize() {
		return fields.length;
	}
	
	public boolean contains(AttributeDefinition varDef){
		for(AttributeDefinition varDef2: fields)
			if (varDef == varDef2)
				return true;
				
		return false;
	}


	@Override
	public void treeNodesChanged(TreeModelEvent e) {
		ListDataEvent event1 = new ListDataEvent(yclass, ListDataEvent.INTERVAL_ADDED, 0 ,fields.length);				
		regenerate();
		ListDataEvent event2 = new ListDataEvent(yclass, ListDataEvent.INTERVAL_ADDED, 0 ,fields.length);
		
		for (ListDataListener l: listeners) {
			l.intervalRemoved(event1);
			l.intervalAdded(event2);
		}
	}

	@Override
	public void treeNodesInserted(TreeModelEvent e) {
	}

	@Override
	public void treeNodesRemoved(TreeModelEvent e) {
	}

	@Override
	public void treeStructureChanged(TreeModelEvent e) {
	}



}
