import std.stdio;
import std.string;
import std.conv : to;


import gtk.Main;
import gtk.MainWindow;
import gtk.TreeView;
import gtk.ListStore;
import gtk.TreeViewColumn;
import gtk.TreeIter;
import gtk.Label;
import gtk.Entry;
import gtk.CellRenderer;
import gtk.CellRendererText;
import gtk.CellRendererSpin;

void[] Serialize(VT...)(VT data){
	void[] ret;
	foreach(d ; data){
		ret~=cast(void[])([d]);
	}
	return ret;
}

void main(string[] args)
{
	auto twoda = new TwoDA("test.2da");


	Main.init(args);

	auto window = new MainWindow("Test");


	auto store = new ListStore([GType.STRING,GType.STRING,GType.STRING]);

	auto tree = new TreeView(store);
	window.add(tree);
	tree.setHeadersVisible(true);
	tree.setEnableSearch(true);
	tree.setModel(store);

	foreach(index, s ; twoda.header){

		CellRenderer cr;
		writeln(index);
		if(index==0){
			cr = new CellRendererSpinner();
			cr.setProperty("pulse", 1);
			cr.setProperty("active", true);
		}	
		else{
			cr = new CellRendererText();
			cr.setProperty("editable", true);
		}
		
		//cr.setSensitive(true);

		auto col = new TreeViewColumn(s, cr, "text", index);
		col.setResizable(true);
		//if(index!=0) col.setReorderable(true);
		tree.appendColumn(col);
	}

	TreeIter iter = store.createIter();


	for(int i=0 ; i<=twoda.lastLine ; i++){
		store.setValue(iter, 0, i);

		if(i in twoda.values){
			foreach(index, v ; twoda.values[i]){
				store.setValue(iter, index+1, v);
			}
		}
		else{
			foreach(index ; 1..twoda.header.length){
				store.setValue(iter, index+1, "_");
			}
		}
		store.append(iter);

	}

	tree.columnsAutosize();


	window.showAll();
	Main.run();
}



class TwoDA{
	import std.regex;
	import std.file;

	this(string filepath){
		lastLine = 0;
		foreach(index, line ; readText(filepath).splitLines()){
			
			string data[]; 

			auto results = matchAll(line, rgxField);
			foreach(res ; results){
				string s;
				if(res[0][0]=='"')	data~= res[2];
				else				data~= res[1];
			}

			if(index==0){
				header = data;
				//writeln(header);
			}
			else{
				int nLine = data[0].to!int;
				values[nLine] = data[1..$];
				//writeln(values[nLine]);

				if(nLine > lastLine)
					lastLine = nLine;
			}

		}

	}


	string[] header;
	string[][uint] values;
	uint lastLine;
	enum rgxField = ctRegex!"(?:\\b([^\\s]+?)\\b|\"([^\"]+?)\")";
}

