function Filax(host)
{
	// Private
	var _host = host;
	var _xsl = null;
	var _select = new Array();
	var _handlerMkdir = new HandlerMkdir();
	var _handlerUpload = new HandlerUpload();
	var _handlerRename = new HandlerRename();
	var _handlerRemove = new HandlerRemove();
	
	// Public
	this.addSelect = __addSelect;
	this.xsl = __xsl;
	this.cd = __cd;
	this.ls = __ls;
	this.mkdir = __mkdir;
	this.mv = __mv;
	this.rm = __rm;
	this.dl = __dl;
	this.ul = __ul;
	this.showMkdir = __showMkdir;
	this.showUpload = __showUpload;
	this.showRename = __showRename;
	this.showRemove = __showRemove;
	
	function __addSelect(path, select)
	{
		_select[path] = select;
	}
	
	function __xsl()
	{
		try
		{
			var query = new KQuery(_host + "?xsl", __callbackXsl);
		}
		catch (e)
		{
			alert(e.message);
		}
	}
	
	function __callbackXsl(status, responseXML, responseText)
	{
		switch (status)
		{
			case EQueryStatus.Done:
				_xsl = responseXML;
			break;
		}
	}
	
	function __cd(path)
	{
		try
		{
			var query = new KQuery(_host + "?cd&path=" + path, __callbackCd);
		}
		catch (e)
		{
			alert(e.message);
		}
	}
		
	function __callbackCd(status, responseXML, responseText)
	{
		switch (status)
		{
			case EQueryStatus.Done:
			{
				__ls("*");
			}
			break;
		}
	}
	
	function __ls(pattern)
	{
		try
		{
			var query = new KQuery(_host + "?ls&pattern=" + pattern, __callbackLs);
		}
		catch (e)
		{
			alert(e.message);
		}
	}
		
	function __callbackLs(status, responseXML, responseText)
	{
		switch (status)
		{
			case EQueryStatus.Done:
			{
				_select = new Array();
				var xslt = new KXSLT();
				var content = document.getElementById("content");
				xslt.transform(_xsl, responseXML, content);
			}
			break;
		}
	}
	
	function __mkdir(name)
	{
		try
		{
			var query = new KQuery(_host + "?mkdir&name=" + name, __callbackMkdir);
		}
		catch (e)
		{
			alert(e.message);
		}
	}
		
	function __callbackMkdir(status, responseXML, responseText)
	{
		switch (status)
		{
			case EQueryStatus.Done:
			{
				__ls("*");
				_handlerMkdir.close();
			}
			break;
		}
	}
	
	function __mv(oldPath, newPath)
	{
		try
		{
			var query = new KQuery(_host + "?mv&oldPath=" + oldPath + "&newPath=" + newPath);
		}
		catch (e)
		{
			alert(e.message);
		}
	}
	
	function __rm(path)
	{
		try
		{
			var query = new KQuery(_host + "?rm&path=" + path);
		}
		catch (e)
		{
			alert(e.message);
		}
	}
	
	function __dl(path)
	{
		document.location.href = _host + "?dl&path=" + path;
	}
	
	function __ul()
	{
		try
		{
			var query = new KQuery(_host + "?ul", __callbackUl);
		}
		catch (e)
		{
			alert(e.message);
		}
	}
		
	function __callbackUl(status, responseXML, responseText)
	{
		switch (status)
		{
			case EQueryStatus.Done:
			{
				__ls("*");
				_handlerUpload.close();
			}
			break;
		}
	}
	
	function __showMkdir()
	{
		var windowMkdir = new KWindow("Make a new directory");
		_handlerMkdir.setWindow(windowMkdir);
		
		var label = new KLabel("Please choose a name for the new directory.");
		windowMkdir.addWidget(label, ELayout.Top);
		
		var inputText = new KInputText("Name:", "");
		windowMkdir.addWidget(inputText, ELayout.Middle);
		_handlerMkdir.setInput(inputText);
		
		var buttonCancel = new KButton("Cancel", windowMkdir.close);
		windowMkdir.addWidget(buttonCancel, ELayout.Bottom);
		
		var buttonOk = new KButton("Ok", _handlerMkdir.send);
		windowMkdir.addWidget(buttonOk, ELayout.Bottom);
		
		windowMkdir.showModal();
	}
	
	function __showUpload(filax)
	{
		_handlerUpload.setFilax(filax);
		
		var windowUpload = new KWindow("Upload");
		_handlerUpload.setWindow(windowUpload);
		
		var label = new KLabel("Please choose the file you want to upload.");
		windowUpload.addWidget(label, ELayout.Top);
		_handlerUpload.setLabel(label);
		
		var inputFile = new KInputFile(_host);
		windowUpload.addWidget(inputFile, ELayout.Middle);
		_handlerUpload.setInputFile(inputFile);
		
		var buttonCancel = new KButton("Cancel", windowUpload.close);
		windowUpload.addWidget(buttonCancel, ELayout.Bottom);
		_handlerUpload.setButtonCancel(buttonCancel);
		
		var buttonOk = new KButton("Ok", _handlerUpload.send);
		windowUpload.addWidget(buttonOk, ELayout.Bottom);
		_handlerUpload.setButtonOk(buttonOk);
		
		windowUpload.showModal();
	}
	
	function __showRename()
	{
		var inputs = new Array();
		var nbSelected = 0;
		
		for (path in _select)
		{
			if (_select[path].getIsChecked())
			{
				inputs[path] = new KInputText("", path);
				nbSelected++;
			}
		}
		
		if (nbSelected == 0)
		{
			return;
		}
		
		var windowRename = new KWindow("Rename");
		_handlerRename.setWindow(windowRename);
		
		var label = new KLabel("Please choose a new name.");
		windowRename.addWidget(label, ELayout.Top);
		
		for (path in inputs)
		{
			windowRename.addWidget(inputs[path], ELayout.Middle);
			_handlerRename.setInputs(inputs);
		}
		
		var buttonCancel = new KButton("Cancel", windowRename.close);
		windowRename.addWidget(buttonCancel, ELayout.Bottom);
		
		var buttonOk = new KButton("Ok", _handlerRename.send);
		windowRename.addWidget(buttonOk, ELayout.Bottom);
		
		windowRename.showModal();
	}
	
	function __showRemove()
	{
		var str = "";
		var nbSelected = 0;
		
		for (path in _select)
		{
			if (_select[path].getIsChecked())
			{
				str += path + "; ";
				nbSelected++;
			}
		}
		
		if (nbSelected == 0)
		{
			return;
		}
		
		var windowRemove = new KWindow("Remove");
		_handlerRemove.setWindow(windowRemove);
		
		var label = new KLabel("Are you sure you want to remove?");
		windowRemove.addWidget(label, ELayout.Top);
		
		var message = new KLabel(str);
		windowRemove.addWidget(message, ELayout.Middle);
		
		var buttonCancel = new KButton("Cancel", windowRemove.close);
		windowRemove.addWidget(buttonCancel, ELayout.Bottom);
		
		var buttonOk = new KButton("Ok", _handlerRemove.send);
		windowRemove.addWidget(buttonOk, ELayout.Bottom);
		
		windowRemove.showModal();
	}
	
	function HandlerMkdir()
	{
		// Private
		var _window = null;
		var _input = null;
		
		// Public
		this.setInput = __setInput;
		this.setWindow = __setWindow;
		this.send = __send;
		this.close = __close;
		
		function __setInput(input)
		{
			_input = input;
		}
		
		function __setWindow(window)
		{
			_window = window;
		}
		
		function __send()
		{
			__mkdir(_input.getValue());
		}
		
		function __close()
		{
			_window.close();
		}
	}
	
	function HandlerUpload()
	{
		// Private
		var _label = null;
		var _inputFile = null;
		var _window = null;
		var _buttonOk = null;
		var _buttonCancel = null;
		var _filax = null;
		this.close = __close;
		
		// Public
		this.setLabel = __setLabel;
		this.setInputFile = __setInputFile;
		this.setWindow = __setWindow;
		this.setButtonOk = __setButtonOk;
		this.setButtonCancel = __setButtonCancel;
		this.setFilax = __setFilax;
		this.send = __send;
		
		function __setLabel(label)
		{
			_label = label;
		}
		
		function __setInputFile(inputFile)
		{
			_inputFile = inputFile;
		}
		
		function __setWindow(window)
		{
			_window = window;
		}
		
		function __setFilax(filax)
		{
			_filax = filax;
		}
		
		function __setButtonOk(buttonOk)
		{
			_buttonOk = buttonOk;
		}
		
		function __setButtonCancel(buttonCancel)
		{
			_buttonCancel = buttonCancel;
		}
		
		function __send()
		{
			var myform = document.createElement("form");
			myform.method = "post";
			myform.action = _inputFile.getHost();
			myform.enctype = "multipart/form-data";
			myform.target = "target_upload";
			
			var command = document.createElement("input");
			command.type = "hidden";
			command.name = "ul";
			command.value = "ul";
			
			var input = _inputFile.getRoot();
			input.name = "file";
			
			var target = document.createElement("iframe");
			target.id = "target_upload";
			target.name = "target_upload";
			
			document.getElementById("div_upload").appendChild(myform);
			myform.appendChild(command);
			myform.appendChild(input);
			myform.appendChild(target);
			
			_label.getRoot().innerHTML = "Please wait while file is being uploaded...";
			_buttonOk.getRoot().style.visibility = "hidden";
			_buttonCancel.getRoot().style.visibility = "hidden";
			
			myform.submit();
			
			filax.ul();
		}
		
		function __close()
		{
			_window.close();
		}
	}
	
	function HandlerRename()
	{
		// Private
		var _inputs = null;
		var _window = null;
		
		// Public
		this.setInputs = __setInputs;
		this.setWindow = __setWindow;
		this.send = __send;
		
		function __setInputs(inputs)
		{
			_inputs = inputs;
		}
		
		function __setWindow(window)
		{
			_window = window;
		}
		
		function __send()
		{
			for (path in _inputs)
			{
				__mv(path, _inputs[path].getValue());
			}
			
			__ls("*");
			__ls("*");
			_window.close();
		}
	}
	
	function HandlerRemove()
	{
		// Private
		var _window = null;
		
		// Public
		this.setWindow = __setWindow;
		this.send = __send;
		
		function __setWindow(window)
		{
			_window = window;
		}
		
		function __send()
		{
			for (path in _select)
			{
				if (_select[path].getIsChecked())
				{
					__rm(path);
				}
			}
			
			__ls("*");
			__ls("*");
			_window.close();
		}
	}
}

function KXSLT()
{
	// Public
	this.transform = __transform;
	
	function __transform(xsl, xml, target)
	{
		if (window.XSLTProcessor)
		{
			while (target.hasChildNodes())
			{
				target.removeChild(target.firstChild);
			}
			
			var processor = new XSLTProcessor();
			processor.importStylesheet(xsl);
			target.appendChild(processor.transformToFragment(xml, document));
		}
		else if (window.ActiveXObject)
		{
			target.innerHTML = xml.transformNode(xsl);
		}
		else
		{
			throw(new Error("No XSLT support"));
		}
	}
}

var ELayout = { Top: 0, Middle: 1, Bottom: 2 };

function KWindow(title)
{
	// Private
	var _parent = document.getElementsByTagName("body")[0];
	var _root = document.createElement("div");
	var _bar = new KWindowBar(title, _root, __close);
	var _layout = new KWindowLayout(_root);
	
	// Public
	this.addWidget = __addWidget;
	this.showModal = __showModal;
	this.close = __close;
	
	// Constructor
	_root.className = "KWindow";
	_root.style.display = "none";
	_parent.appendChild(_root);
	
	function __addWidget(widget, layout)
	{
		switch (layout)
		{
			case ELayout.Top:
				_layout.getTop().appendChild(widget.getRoot());
			break;
			case ELayout.Middle:
				_layout.getMiddle().appendChild(widget.getRoot());
			break;
			case ELayout.Bottom:
				_layout.getBottom().appendChild(widget.getRoot());
			break;
		}
	}
	
	function __showModal()
	{
		_root.style.display = "block";
	}
	
	function __close()
	{
		_parent.removeChild(_root);
		_root = null;
	}
}

function KWindowBar(title, parent, close)
{
	// Private
	var _root = document.createElement("div");
	var _close = document.createElement("div");
	
	// Public
	this.getRoot = __getRoot;
	
	// Constructor
	_root.className = "KWindowBar";
	_root.innerHTML = title;
	_close.className = "KWindowBar_close";
	_close.onclick = close;
	_root.appendChild(_close);
	parent.appendChild(_root);
	
	function __getRoot()
	{
		return(_root);
	}
}

function KWindowLayout(parent)
{
	// Private
	var _root = document.createElement("div");
	var _top = document.createElement("div");
	var _middle = document.createElement("div");
	var _bottom = document.createElement("div");
	
	// Public
	this.getTop = __getTop;
	this.getMiddle = __getMiddle;
	this.getBottom = __getBottom;
	
	// Constructor
	_root.className = "KWindowLayout";
	_top.className = "KWindowLayout_top";
	_root.appendChild(_top);
	_middle.className = "KWindowLayout_middle";
	_root.appendChild(_middle);
	_bottom.className = "KWindowLayout_bottom";
	_root.appendChild(_bottom);
	parent.appendChild(_root);
	
	function __getTop()
	{
		return(_top);
	}
	
	function __getMiddle()
	{
		return(_middle);
	}
	
	function __getBottom()
	{
		return(_bottom);
	}
}

function KLabel(label)
{
	// Private
	var _root = document.createElement("div");
	
	// Public
	this.getRoot = __getRoot;
	
	// Constructor
	_root.className = "KLabel";
	_root.innerHTML = label;
	
	function __getRoot()
	{
		return(_root);
	}
}

function KButton(label, onclick)
{
	// Public
	var _root = document.createElement("div");
	var _label = document.createElement("div");
	
	// Private
	this.getRoot = __getRoot;
	
	// Constructor
	_root.className = "KButton";
	_root.onclick = onclick;
	_label.className = "KButton_label";
	_label.innerHTML = label;
	_root.appendChild(_label);
	
	function __getRoot()
	{
		return(_root);
	}
}

function KCheckBox(label, parent)
{
	// Public
	var _root = document.createElement("div");
	var _checkbox = document.createElement("div");
	var _label = document.createElement("div");
	
	// Private
	this.getRoot = __getRoot;
	this.getIsChecked = __getIsChecked;
	
	// Constructor
	_root.className = "KCheckBox";
	_root.onclick = __onClick;
	_checkbox.className = "KCheckBox_checkbox-off";
	_label.className = "label";
	_label.innerHTML = label;
	_root.appendChild(_checkbox);
	_root.appendChild(_label);
	parent.appendChild(_root);
	
	function __getRoot()
	{
		return(_root);
	}
	
	function __getIsChecked()
	{
		return(_checkbox.className == "KCheckBox_checkbox-on");
	}
	
	function __onClick()
	{
		_checkbox.className = __getIsChecked() ? "KCheckBox_checkbox-off" : "KCheckBox_checkbox-on";
	}
}


function KInputText(label, value)
{
	// Private
	var _root = document.createElement("div");
	var _input = document.createElement("input");
	var _label = document.createElement("span");
	
	// Public
	this.getRoot = __getRoot;
	this.getValue = __getValue;
	
	// Constructor
	_root.className = "KInputText";
	_input.type = "text";
	_input.value = value;
	_label.innerHTML = label;
	_root.appendChild(_label);
	_root.appendChild(_input);
	
	function __getRoot()
	{
		return(_root);
	}
	
	function __getValue()
	{
		return(_input.value);
	}
}

function KInputFile(host)
{
	// Private
	var _root = document.createElement("input");
	var _host = document.createElement("input");
	
	// Public
	this.getRoot = __getRoot;
	this.getHost = __getHost;
	
	// Constructor
	_root.type = "file";
	_root.className = "KInputFile";
	_host = host;
	
	function __getRoot()
	{
		return(_root);
	}
	
	function __getHost()
	{
		return(_host);
	}
}

var EQueryStatus = { Closed: 0, Opened: 1, Sent: 2, Receiving: 3, Done: 4 };

function KQuery(url, callback)
{
	// Private
	var _xhr;
	var _callback = callback;
	
	// Public
	this.callback = __callback;
	
	// Constructor
	if (window.XMLHttpRequest)
	{
		_xhr = new XMLHttpRequest();
	}
	else if (window.ActiveXObject)
	{
		try
		{
			_xhr = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{
			_xhr = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	else
	{
		throw(new Error("No XMLHttpRequest support"));
	}

	_xhr.open("GET", url, true);
	_xhr.onreadystatechange = __callback;
	_xhr.send(null);
	
	function __callback()
	{
		try
		{
			if (_xhr.status != 200)
			{
				throw(new Error("Server error"));
			}
		}
		catch (e)
		{
		}
		
		if (_callback)
		{
			_callback(_xhr.readyState, _xhr.responseXML, _xhr.responseText);
		}
	}
}

