package com.gaubert.test;

import java.util.ArrayList;
import java.util.List;

import com.trolltech.qt.core.QModelIndex;
import com.trolltech.qt.core.Qt.DropAction;
import com.trolltech.qt.core.Qt.DropActions;
import com.trolltech.qt.core.Qt.ItemDataRole;
import com.trolltech.qt.core.Qt.ItemFlag;
import com.trolltech.qt.core.Qt.ItemFlags;
import com.trolltech.qt.gui.QAbstractItemView;
import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QTreeModel;
import com.trolltech.qt.gui.QTreeView;

public class DraggableTreeModel extends QTreeModel {

	private List<List<String>> tree;
	
	public DraggableTreeModel(){
		super();
		tree = new ArrayList<List<String>>();
		for(int i=0;i<3;++i){
			ArrayList<String> node = new ArrayList<String>();
			tree.add(i, node);
			for(int j=0;j<5;++j){
				node.add(j, "leaf("+i+","+j+")");
			}
		}

	}

	@SuppressWarnings("unchecked")
	@Override
	public Object child(Object parent, int row) {
		Object result = null;
		
		if(parent==null){
			result = tree.get(row);
		} else if(parent instanceof List){
			List<String> listParent = (List<String>) parent;
			result = listParent.get(row);
		}
		
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public int childCount(Object parent) {
		int result = 0;
		
		if(parent==null){
			result = tree.size();
		} else if(parent instanceof List){
			List<String> listParent = (List<String>) parent;
			result = listParent.size();
		}
		
		return result;
	}

	@Override
	public String text(Object value) {
		return null;
	}

	@Override
	public Object data(Object value, int role) {
		Object result = null;
		switch(role){
			case ItemDataRole.DisplayRole :
				if(value instanceof String){
					result = value;
				} else {
					result = "node";
				}
				break;
			default :
				result = null;
		}
		return result;
	}
	
	@Override
	public Object data(QModelIndex index, int role) {
		/**
		 * I know it's not necessary to reimplement 
		 * but this shows that the problem comes
		 * from indexToValue()
		 */
		Object value = indexToValue(index);
		return data(value,role);
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean setData(QModelIndex index, Object value, int role) {
		switch(role){
			case ItemDataRole.DisplayRole :
				String castedValue = (String) value;
				if(index != null && index.parent() != null &&
						indexToValue(index.parent()) instanceof List){
					List<String> parentList = (List<String>) indexToValue(index.parent());
					parentList.set(index.row(), castedValue);
					dataChanged.emit(index,index);

					System.out.println("data set");
					System.out.println(tree.get(0));
					System.out.println(tree.get(1));
					System.out.println(tree.get(2));
				}
				break;
			default:
				break;
				
		}
	
		return true;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean removeRows(int row, int count, QModelIndex parent) {
		boolean result = true;
		
		if(parent!=null && indexToValue(parent) instanceof List){
			for(int i = row;i<row+count;++i){
				List<String> parentList = (List<String>) indexToValue(parent);
				parentList.remove(i);
				
				System.out.println("row removed");
				System.out.println(tree.get(0));
				System.out.println(tree.get(1));
				System.out.println(tree.get(2));
			}
			result = true;
		} else {
			result = false;
		}
		
		childrenRemoved(parent, row, row + count - 1);
		return result;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean insertRows(int row, int count, QModelIndex parent) {
		boolean result = true;
		
		if(parent!=null && indexToValue(parent) instanceof List){
			for(int i = row;i<row+count;++i){
				List<String> parentList = (List<String>) indexToValue(parent);
				parentList.add(i, "Foo");
				
				System.out.println("row inserted");
				System.out.println(tree.get(0));
				System.out.println(tree.get(1));
				System.out.println(tree.get(2));
				
				childrenInserted(parent, row, row + count - 1);
			}
			result = true;
		} else {
			result = false;
		}
		
		return result;
	}
	
	@Override
	public DropActions supportedDropActions() {
		DropActions result = new DropActions(DropAction.MoveAction);
		return result;
	}
	
	@Override
	public ItemFlags flags(QModelIndex index) {
		ItemFlags result = new ItemFlags();

		if (index != null && index.parent() == null ){ // node
			result.set(
					ItemFlag.ItemIsDropEnabled,
					ItemFlag.ItemIsEnabled,
					ItemFlag.ItemIsSelectable);
		} else if (indexToValue(index) instanceof String){ // leaf
			result.set(
					ItemFlag.ItemIsDragEnabled,
					ItemFlag.ItemIsEnabled,
					ItemFlag.ItemIsSelectable);
		} 
		else { //autre
			result.set(
					ItemFlag.ItemIsEnabled,
					ItemFlag.ItemIsSelectable);
		}

		return result;
	}
	
	/**
	 * 
	 *  The main
	 */
	public static void main(String[] args) {
		//init app
		QApplication.initialize(args);
		
		//init view
	    QTreeView myTestView = new QTreeView();
	    myTestView.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection);
	    myTestView.setDragEnabled(true);
	    myTestView.setAcceptDrops(true);
	    myTestView.setDropIndicatorShown(true);

	    //init model
		DraggableTreeModel myTestModel = new DraggableTreeModel();
		
		//set view with model
		myTestView.setModel(myTestModel);
		myTestView.show();
		myTestView.expandAll();
//		myTestView.resize(200, 400);
//		myTestView.move(2300, 550);
		
		//launch app
		QApplication.exec();
	}
}

