/*
	Copyright (c) 2006-2007, The Xooki project
	http://xooki.sourceforge.net/

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
	
	Some code is largely inspired by code found in the dojo toolkit, 
	see http://dojotoolkit.org/ for more information.
*/

// this file is included only in edit mode

xooki.url.include("tiddly/util.js");

if (typeof xooki.io == "undefined") {
    xooki.io = {};
}

xooki.io.removeFile = function (filePath) {
	var r = null;
	if((r == null) || (r == false))
		r = xooki.io.mozillaRemoveFile(filePath);
	if((r == null) || (r == false))
		r = xooki.io.ieRemoveFile(filePath);
	return(r);
}

xooki.io.mozillaRemoveFile = function(filePath) {
	if(window.Components)
		try
			{
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
			var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
			file.initWithPath(filePath);
			if (!file.exists())
				return null;
			file.remove(false);
			return(true);
			}
		catch(e)
			{
			return(false);
			}
	return(null);
}

xooki.io.ieRemoveFile = function(filePath) {
	try
		{
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		}
	catch(e)
		{
		//alert("Exception while attempting to save\n\n" + e.toString());
		return(null);
		}
	fso.DeleteFile(filePath, false);
	return(true);
}

// fix EOL characters in text to use native characters
xooki.io.fixEOL = function(text) {
	var nativeEOL = navigator.platform.indexOf('Win') != -1 ? '\r\n' : '\n';
	return text.replace(/\r?\n/g, nativeEOL);
}


if (typeof xooki.string == "undefined") {
    xooki.string = {};
}

xooki.string.escapeString = function(str) {
// borrowed from dojo
//summary:
//	Adds escape sequences for non-visual characters, double quote and backslash
//	and surrounds with double quotes to form a valid string literal.
	return ('"' + str.replace(/(["\\])/g, '\\$1') + '"'
		).replace(/[\f]/g, "\\f"
		).replace(/[\b]/g, "\\b"
		).replace(/[\n]/g, "\\n"
		).replace(/[\t]/g, "\\t"
		).replace(/[\r]/g, "\\r"); // string
};

if (typeof xooki.json == "undefined") {
    xooki.json = {};
}

xooki.json.serialize = function (o, indent) {
        // borrowed and adapted from dojo
    	// summary:
    	//		Create a JSON serialization of the object.
    	// return:
    	//		a String representing the serialized version of the passed object
    	if (!indent) {
    	   indent = "";
        }
		var objtype = typeof(o);
		if(objtype == "undefined"){
			return "undefined";
		}else if((objtype == "number")||(objtype == "boolean")){
			return o + "";
		}else if(o === null){
			return "null";
		}
		if (objtype == "string") { return xooki.string.escapeString(o); }
		if(objtype == "function"){
		    // do not encode functions
			return null;
		}
		// recurse
		var me = arguments.callee;
		// short-circuit for objects that support "json" serialization
		// if they return "self" then just pass-through...
		var newObj;
		// array
		if(objtype != "function" && typeof(o.length) == "number"){
			var res = [];
			for(var i = 0; i < o.length; i++){
				var val = me(o[i], indent+"  ");
				
				if(typeof(val) != "string"){
					val = "undefined";
				}
				res.push(val);
			}
			return " [\n" + res.join(",\n") + "\n"+indent+"]\n";
		}
		// generic object code path
		res = [];
		for (var k in o){
		    if ("meta" == k) {
		      continue;
            }
            // let a chance to the object to define its transient keys, using a meta.isTransient function
            if (typeof o.meta != 'undefined' 
                && typeof o.meta.isTransient == 'function'
                && o.meta.isTransient(k)) {
                continue;
            }
			var useKey;
			if (typeof(k) == "number"){
				useKey = '"' + k + '"';
			}else if (typeof(k) == "string"){
				useKey = xooki.string.escapeString(k);
			}else{
				// skip non-string or number keys
				continue;
			}
            val = o[k];
            // let a chance to the object to define its serialized value
            if (typeof o.meta != 'undefined' 
                && typeof o.meta.getSerializeValue == 'function') {
                val = o.meta.getSerializeValue(o, k);
            }
			val = me(val, indent+"    ");
			if(typeof(val) != "string"){
				// skip non-serializable values
				continue;
			}
			res.push(indent+"  "+useKey + ":" + val);
		}
		return indent+"{\n" + res.join(",\n") + indent+"}";
};

xooki.component.toolbar = function () {
	return	'<div style="position:absolute;top:2px;right:30px;" id="xooki-toolbar">'
				+ '<a href="javascript:xooki.action.toggleEdit()"><img src="'+xooki.u('images/edit.gif')+'" title="toggle edit'+(xooki.c.browser.NS?' (CTRL+E)':'')+'"/></a>'
				+ '<a href="javascript:xooki.action.saveChanges()"><img src="'+xooki.u('images/save.gif')+'" title="save'+(xooki.c.browser.NS?' (CTRL+S)':'')+'"/></a>'
				+ '<a href="javascript:xooki.action.remove()"><img src="'+xooki.u('images/delete.gif')+'" title="remove"/></a>'
				+ '<a href="javascript:xooki.action.createChild()"><img src="'+xooki.u('images/addchild.gif')+'" title="create child"/></a>'
				+ '<a href="javascript:xooki.action.movePageUp()"><img src="'+xooki.u('images/up.gif')+'" title="move page up in TOC"/></a>'
				+ '<a href="javascript:xooki.action.movePageDown()"><img src="'+xooki.u('images/down.gif')+'" title="move page down in TOC"/></a>'
				+ (xooki.c.debug?'<a href="javascript:xooki.action.toggleDebug()"><img src="'+xooki.u('images/debug.gif')+'" title="toggle xooki debug mode"/></a>':'')
			+ '</div>';
};
    
xooki.component.editZone = function () {
    return '<div id="xooki-edit" style="display:none">'
        + '<table border="0"><tr><td valign="top">Title</td><td><input id="xooki-input-title" type="text" value="'+xooki.page.title+'"></input></td></tr>'
        + '<tr><td valign="top">Content</td><td><textarea rows="20" cols="80" id="xooki-source">'+xooki.input.source()+'</textarea></td></tr>'
        + '<tr><td colspan="2" align="right"><input type="button" value="Save" onclick="javascript:xooki.action.saveChanges()"/> <input type="button" value="Preview" onclick="javascript:xooki.action.previewChanges()"/> <input type="button" value="Discard" onclick="javascript:xooki.action.discardChanges()"/></td></tr></table></div>';
}

xooki.url.reload = function() {
    window.location = window.location;
}


if (typeof xooki.action == "undefined") {
    xooki.action = {};
}

xooki.action.quitEdit = function () {
    xooki.input.applyChanges();
	xooki.html.hide('xooki-edit');
	xooki.html.show('xooki-content');
}
xooki.action.edit = function () {
	xooki.html.hide('xooki-content');
	xooki.html.show('xooki-edit');
}
xooki.action.toggleEdit = function () {
	if (document.getElementById('xooki-edit').style.display == 'none') {
		xooki.action.edit();
	} else {
		xooki.action.quitEdit();
	}
}
xooki.action.remove = function () {
    if (confirm(t("The current page will be removed from the table of content, and deleted on file system.\nNote that all children will be removed from the table of content too, but not from the file system!\nAre you sure you want to delete the current page?"))) {

        // the page to which we'll be redirected...
        var nextPage;
        var index = xooki.page.meta.index;
        var parent = xooki.page.meta.parent;
        if (index > 0) {
            // ... will be the previous sibling if there is one ...
            nextPage = parent.children[index - 1];
        } else if (parent.children.length > 1) {
            // ... or the next sibling if there is one ...
            nextPage = parent.children[index + 1];        
        } else if (parent != xooki.toc) {
            // ... or the parent if the parent is not the toc root ...
            nextPage = parent;        
        } else {
            // ... otherwise it s a problem
            xooki.error(t("Cannot delete the sole page!"));
            return;
        }
        
        parent.children.splice(index, 1); // remove node from toc
        xooki.toc.save();
        
        xooki.io.removeFile(xooki.io.getLocalPath(window.location.toString()));
        
        window.location = pu(nextPage.id);
    }
}
xooki.action.discardChanges = function () {
    xooki.url.reload();
}
xooki.action.previewChanges = function () {
    xooki.action.quitEdit();
}
xooki.action.saveChanges = function () {
	var originalPath = document.location.toString();
	var localPath = xooki.io.getLocalPath(originalPath);
	
	// Load the original file
	var original = xooki.io.loadFile(localPath);
	if(original == null) {
		xooki.error(t("Impossible to load original file: ${0}", localPath));
		return;
	}
	
	var startSaveArea = '<textarea id="xooki-source">';
	var posOpeningArea = original.indexOf(startSaveArea);
	var posClosingArea = original.indexOf('</textarea>');
	
	xooki.page.title = document.getElementById('xooki-input-title').value;
	xooki.toc.save();
	
	var save;
	try {
		// Save new file
		var revised = original.substr(0,posOpeningArea + startSaveArea.length) + "\n" +
					xooki.input.source() +
					original.substr(posClosingArea);
					
		save = xooki.io.saveFile(localPath,xooki.io.fixEOL(revised));
	} catch (e) {
		xooki.error(e);
	} 
    if(save) {
		xooki.info(t("saved to ${0}",localPath));
		
		// TODO: see if we are able to apply title change without reloading
		setTimeout(function() {xooki.url.reload();}, 800);
	} else
		xooki.error(t("Impossible to save changes to ${0}", localPath));
}


xooki.action.movePageUp = function () {
    xooki.action.movePage(-1);
}
xooki.action.movePageDown = function () {
    xooki.action.movePage(1);
}

xooki.action.movePage = function (delta) {
    var index = xooki.page.meta.index;
    var parent = xooki.page.meta.parent;

    // check if node can move
    if (index + delta < 0) {
        xooki.info(t("Can't move first page up"));
        return;
    }
    if (index + delta >= parent.children.length) {
        xooki.info(t("Can't move last page down"));
        return;
    }

    // move node in toc    
    parent.children.splice(index, 1);
    parent.children.splice(index+delta, 0, xooki.page);
    
    xooki.toc.save();
    xooki.url.reload();
}

xooki.action.createChild = function () {
    titleToId = function (title) {
        return title.replace(/\s+/g, '');
    }

    var title = prompt("Child page title?", "");
    var id = prompt("Child page path?", titleToId(title));
    
    xooki.action.createChildPage({"id": id, "title": title, "children": []});
}

xooki.action.createChildPage = function (child) {
    if (typeof child.meta == 'undefined' || typeof child.meta.level == 'undefined') {
        if (typeof child.meta == 'undefined') child.meta = {};
        child.meta.level = child.id.split('/').length - 1;
    }
        
    var pagetpl = xooki.url.loadURL(cu("blankPageTpl"));
    if (pagetpl != null) {
        var childURL = pu(child.id);
        var localPath = xooki.io.getLocalPath(childURL);
        var original = xooki.io.loadFile(localPath);
        if (original != null) {
            if (!window.confirm(t("File for child page:\n${0}\nalready exists.\nAre you sure you want to continue and overwrite it?", localPath))) 
                return;
        }
        
        xooki.page.children.push(child);
        xooki.toc.save();
        
        // usually used by templates
        if (typeof child.relroot == 'undefined') {
            child.relroot = "";
        	for (var i=0; i < child.meta.level; i++) {
        		child.relroot += "../";
        	}
        }
        child.level = child.meta.level;
		var revised = xooki.string.processTemplate(pagetpl, child);
    	var save;
    	try {
    		// Save new file
    		save = xooki.io.saveFile(localPath,xooki.io.fixEOL(revised));
    	} catch (e) {
    		xooki.error(e);
    	} 
        if(save) {
    		// go to child page
            window.location = childURL;
    	} else
    		xooki.error(t("Impossible to save changes to ${0}", localPath));
    }
}


xooki.toc.save = function (revised) {
    if (!revised) {
        revised = xooki.json.serialize({children: this.actualRoot.children});
    }
	var save;
	var tocPath = xooki.io.getLocalPath(this.url);
	try {
		save = xooki.io.saveFile(tocPath, xooki.io.fixEOL(revised));
	} catch (e) {
		xooki.error(e);
	} 
    if(!save) 
		xooki.error(t("Impossible to save changes to ${0}", tocPath));
}


if (typeof xooki.util == 'undefined') xooki.util = {}
xooki.util.copy = function(o) {
    var copy = {};
    for (var k in o) {
        copy[k] = o[k];
    }   
    return copy;
}
