/*
	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 script can be either embedded in a xooki page for in browser processing, or used in batch using rhino or java 6 javascript tool:
jrunscript path/to/xooki.js inputFileFromXookiSite.html [path/to/dir/to/put/generated/file]

Be sure to be in the directory where the html input to process is when running this command.
 */
var batchMode = (typeof arguments != 'undefined');

var xooki = {};
xooki.console = ""; // used for debugging purpose only, and only when the debug div is not yet created
xooki.config = {};
xooki.c = xooki.config;

function t(msg) {
    // returns the internationalized version of the message, or the message if no translation is available
    // t stands for translate
// FIXME
//    if (typeof xooki.c == "object" 
//        && typeof xooki.c.messages == "object" 
//        && typeof xooki.c.messages[msg] == "string") {
//        msg = xooki.c.messages[msg];
//    }
    var arr = [];
    for (var i=1; i<arguments.length; i++) {
        arr.push(arguments[i]);
    }
    return xooki.string.substituteParams(msg, arr);
}

function css(clss) {
    // returns the css class or id configured, or the given class (or id) if no one is configured
    if (typeof xooki.c.css[clss] != "undefined") {
        return xooki.c.css[clss];
    } else {
        return clss;
    } 
}
function u(path) {
  // convert a path relative to the root to a full URL
  // u stands for Url
  if (batchMode) {
	return xooki.c.relativeRoot+path;
  } else {
	return xooki.c.root + path;
  }
}
function lu(path) {
  // convert a path relative to the local root to a full URL
  // l stands for local, u stands for Url
  if (batchMode) {
	return xooki.c.localRelativeRoot+path;
  } else {
	return xooki.c.localRoot + path;
  }
}
function cu(urlCfgProp) {
  // get a path from a configuration path and convert it to an URL
  // cu stands for Configured Url
  if (typeof xooki.c.path[urlCfgProp] == "undefined") {
    xooki.warn(t("path not configured in xooki: '${0}'", urlCfgProp));
    return "";
  }
  return u(xooki.c.path[urlCfgProp]);
}
function pu(id) {
  // returns the url of the page identified by id
  // pu stands for Page Url
  return u(id+".html");
}
xooki.p = function(path) {
  // get a xooki full path from a xooki relative path
  // p stands for path
  return xooki.c.path.install+"/"+path;
}
xooki.u = function(path) {
  // convert a path relative to the xooki installation dir to a full URL
  return u(xooki.p(path));
}
xooki.cu = function(urlCfgProp) {
  // get a xooki path from a configuration path and convert it to an URL
  if (typeof xooki.c.path[urlCfgProp] == "undefined") {
    xooki.warn(t("path not configured in xooki: '${0}'", urlCfgProp));
  }
  return xooki.u(xooki.c.path[urlCfgProp]);
}

xooki.util = {
    isArray: function(it) {
    	return (it && it instanceof Array || typeof it == "array"); // Boolean
    },
    mix: function(src, into, override) {
        if (typeof override == "undefined") {
            override = true;
        }
        if (typeof into == "undefined") {
            into = {};
        }
        for (var k in src) {
            if (typeof src[k] == "object" && !xooki.util.isArray(src[k])) {
                if (override || typeof into[k] == "object" || typeof into[k] == "undefined") {
                    if (typeof into[k] != "object") {
                        into[k] = {};
                    }
                    xooki.util.mix(src[k], into[k], override);
                }
            } else if (override || typeof into[k] == "undefined") {
                into[k] = src[k];
            }
        }
        return into;
    },
    initArray: function(a) {
        if (this.isArray(a)) return a;
        else return {};
    }
}

xooki.url = {
        newXmlHttpRequest: function() {
        // we first try to use ActiveX, because IE7 has a direct support for XmlHttpRequest object, 
        // but which doesn't work with file urls
        	if(window.ActiveXObject)
        	{
        		try { req = new ActiveXObject("Msxml2.XMLHTTP");
        		} catch(e) {
        			try { req = new ActiveXObject("Microsoft.XMLHTTP");
        			} catch(e) { req = false; }
        		}
        	}
        	else if(window.XMLHttpRequest) {
        		try { req = new XMLHttpRequest();
        		} catch(e) { req = false; }
        	}
        
        	return req;	
        },
                
        loadURL: function( url, warnOnError ) {
        	req = this.newXmlHttpRequest();
        	if(req) {
        		try {
        			req.open("GET", url, false);
        			req.send("");
        	
        			return req.responseText;
        		} catch (e) {
                    if (warnOnError != false)
                        xooki.error(e, t("problem while loading URL ${0}", url));
                    else
                        xooki.debug(t("problem while loading URL ${0}: ${1}", url, e));
                }		
        	}
        	return null;
        },
        
        asyncLoadURL: function( url, callback, obj ) {
        	var req = this.newXmlHttpRequest();
        	if(req) {
        		try {
        			req.open("GET", url, true);
				    req.onreadystatechange=function() {
				        if (req.readyState == 4) {
				           if (req.status == 200 || req.status == 0) {
				              callback(req.responseText, obj);
				           }
				        }
				     };  			
				     req.send("");
        		} catch (e) {
        			xooki.error(e, t("problem while loading URL ${0}", url));
                }		
        	}
        },

        include: function(script_filename) {
            document.write('<' + 'script');
            document.write(' language="javascript"');
            document.write(' type="text/javascript"');
            document.write(' src="' + xooki.u(script_filename) + '">');
            document.write('</' + 'script' + '>');
        },
        
        evalURL: function( url, warnOnErrorUrl ) {
            script = this.loadURL(url, warnOnErrorUrl);
            if (script != null) {
                try {
                    eval(script);
                } catch (e) {
        			xooki.error(e, t("error while executing script from URL ${0}", url));
                }
            }
        },

        action: function(action) {        
            // returns the url for an action on the same page
            loc = batchMode?'':xooki.pageURL;
            if (loc.indexOf("#") != -1) {
                loc = loc.substring(0, loc.indexOf("#"));
            }
            return loc+"?action="+action;
        }

    };
    
xooki.string = {

    substituteParams: function(/*string*/template, /* object - optional or ... */hash) {
    // borrowed from dojo
    // summary:
    //	Performs parameterized substitutions on a string. Throws an exception if any parameter is unmatched.
    //
    // description:
    //	For example,
    //		dojo.string.substituteParams("File '${0}' is not found in directory '${1}'.","foo.html","/temp");
    //	returns
    //		"File 'foo.html' is not found in directory '/temp'."
    //
    // template: the original string template with ${values} to be replaced
    // hash: name/value pairs (type object) to provide substitutions.  Alternatively, substitutions may be
    //	included as an array
    
        var map;
        if (typeof hash == "object" && hash.length) { // array
            map = {};
            for (var i in hash) {
                map[i+""] = hash[i];
            }
        } else {
            map = hash;
        }
    
    	return template.replace(/\$\{(\w+)\}/g, function(match, key){
    		if(typeof(map[key]) != "undefined" && map[key] != null){
    			return map[key];
    		}
    		xooki.warn("Substitution not found: " + key);
    		return key;
    	}); // string
	},
	
	processTemplate: function(/*string*/template, /* object */hash) {
	   if (typeof template.process == "function") {
	       return template.process(hash);
       } else {
            return this.substituteParams(template, hash);
       }
    },

    exceptionText: function(e, message) {
    	var s = e.description ? e.description : e.toString();
    	return message ? message+":\n"+s : s;
    },
    
    findXmlSection: function(str, element, from) {
        return this.findSection(str, new RegExp('<'+element+'(\\s*\\w+="[\\w\\s]*")*>'), new RegExp('</'+element+'>'), from);
    },
    
    find: function(/*string*/str, /*string or regexp*/exp, /*number, optional*/from) {
        // find an expression (string or regexp) in a string, from an optional index
        // the object returned has two properties:
        // begin: the index in str of the matching find
        // end: the index in str of the end of the matching find
        // returns null if no match is found
        if (typeof from != "number") {
            from = 0;
        }
        if (typeof exp == "string") {
            var result = {};
            result.begin = str.indexOf(exp,from);
            if (result.begin >= 0) {
                result.end = result.begin + exp.length;
                return result;
            }
        } else {
            var m;
            if (from > 0) {
                // I haven't found any other way to start from the given index
                m = exp.exec(str.substring(from));
            } else {
                m = exp.exec(str);
            }
            if (m != null) {                
                var result = {};
                result.begin = m.index + from;
                result.end = result.begin + m[0].length;
                return result;
            }
        }
        return null;
    },
    
    findSection: function(/*string*/str, /*string or regexp*/open, /*string or regexp*/close, /*number, optional*/from) {
        // finds a section delimited by open and close tokens in the given string
        // the algorithm looks for matching open and close tokens
        // the returned object has the following properties:
        //   outerStart: the index in str where the first open token was found
        //   innerStart: the index in str just after the found open token
        //   innerEnd: the index in str where the matching close token was found
        //   outerEnd: the index in str just after the matching close token
        //   children: an array of similar objects if nested sections where found
        // if no section is found (no open token, an open token with no matching 
        // close token, or a close token before an open token), null is returned
        //
        // for instance if open=='(' and close==')' then the section will find
        // a section delimited by the first found open parenthesis and the matching
        // close parentethis, taking into account other opening parentethis
        // examples:
        // findSection("a(test)b", "(", ")") == {outerStart: 1, innerStart:2, innerEnd:6, outerEnd:7, children:[]}
        // findSection("a(te(s)(t))b", "(", ")") == {outerStart: 1, innerStart:2, innerEnd:10, outerEnd:11, 
        //      children:[
        //          {outerStart: 4, innerStart:5, innerEnd:6, outerEnd:7, children:[]},
        //          {outerStart: 7, innerStart:8, innerEnd:9, outerEnd:10, children:[]}
        //      ]}
        
        var openResult = this.find(str, open, from);        
        if (openResult == null) {
            return null;
        }
        var closeResult = this.find(str, close, from);        
        if (closeResult == null || closeResult.begin < openResult.end) {
            return null;
        }
        if (openResult.end <= openResult.begin || closeResult.end <= closeResult.begin) {
            // empty match are not allowed
            return null;
        }
        
        var children = [];
        var child = this.findSection(str, open, close, openResult.end);
        while (child != null) {
            if (child.outerEnd > closeResult.begin) {
                closeResult = this.find(str, close, child.outerEnd);        
                if (closeResult == null) {
                    // unmatched open token
                    return null;
                }
            }
            children.push(child);
            child = this.findSection(str, open, close, child.outerEnd);
        }

        return {
            outerStart: openResult.begin,
            innerStart: openResult.end,
            innerEnd: closeResult.begin,
            outerEnd: closeResult.end,
            children: children
        };        
    },
    
    mul: function (/*string*/ s, /*int*/ n) {
        r = '';
        for (var i=0; i < n; i++) {
    		r += s;
    	}
        return r;
    }
};
    
xooki.json = {
        evalJson: function (str) {
            try {
                return eval("("+str+")");
            } catch (e) {
                return null;
            }
        },
        
        loadURL: function (url) {
            return this.evalJson(xooki.url.loadURL(url));
        }
    };

// Displays an alert of an exception description with optional message
xooki.warn = function(e, message) {
    xooki.display(xooki.string.exceptionText(e, message), "#eecccc");
}

// Displays an alert of an exception description with optional message
xooki.error = function(e, message) {
    xooki.display(xooki.string.exceptionText(e, message), "#ffdddd");
}

xooki.info = function(message) {
    xooki.display(message, "#ddddff");
}

xooki.display = function(message, background) {
    var messages = document.getElementById('xooki-messages');
    if (messages) {
        messages.innerHTML = '<table width="100%" border="0"><tr><td align="center">'+message+'</td></tr></table>';
        messages.style.background = background;
        messages.style.display = "inline";
    } else {
        alert(message);
    }
}

xooki.debug = function(message) {
    var console = typeof document == 'undefined' ? false : document.getElementById('xooki-console');
    if (console) {
        console.value += message + "\n";
    } else {
        xooki.console += message + "\n";
    }
}

xooki.debugShowDetail = function (message) {
    var detail = typeof document == 'undefined' ? false : document.getElementById('xooki-debug-detail');
    if (detail) {
        detail.value=message;
    } else {
        alert(message);
    }
}


xooki.html = {
    hide: function(divid) {
	   document.getElementById(divid).style.display = 'none';
    },

    show: function (divid) {
	   document.getElementById(divid).style.display = '';
    },
    
    pageLink: function(page) {
    	if (page.isAbstract) {
    		return page.title;
    	} else {
    		return '<a href="'+(page.url != null ? page.url : pu(page.id))+'" '+(page.id == xooki.page.id?'class="current"':'')+'>'+page.title+'</a>';
    	}
    },
	
	// insert  the given  header in the html head
	// can be used only when the browser is still in the head !
	addHeader: function(/* string */ head) {
		document.write(head);
	},
	
	setBody: function( /* string */ body) {
		document.body.innerHTML = body;
	}
};

xooki.component = {
    childrenList: function () {
    	if (xooki.page.children.length > 0) {
    		childrenList = '<ul class="'+css('childrenList')+'">';
    		for (var i in xooki.page.children) {
    			childrenList+='<li>'+xooki.html.pageLink(xooki.page.children[i])+'</li>';
    		}
    		childrenList += "</ul>";
    		return childrenList;
    	} else {
    	   return "";
        }
    },
    
    menu: function () {
    	var menu = '<ul id="'+css("treemenu")+'" class="treeview">';
    	menu += (function (page) {
        	var menu = '';
        	for (var i in page.children) {
                if (typeof page.children[i] == 'object') {
            		smenu = arguments.callee(page.children[i]);
            		if (smenu != '') {
                        menu += '<li id="xooki-'+page.children[i].id+'" class="submenu">'+xooki.html.pageLink(page.children[i]);
            			if (smenu.indexOf('id="xooki-'+xooki.page.id+'"') != -1 
            				|| page.children[i].id == xooki.page.id) {
            				// either a descendant or the node processed is the current page node
            				// we specify that the menu must be opened by default
            				menu += '<ul class="open"';
    	        			menu += '>'+smenu+'</ul>';
            			} else {
    						menu += '<ul class="closed"';
    	        			menu += '>'+smenu+'</ul>';
    					}
            		} else {
                        menu += '<li id="xooki-'+page.children[i].id+'">'+xooki.html.pageLink(page.children[i]);
                    }
            		menu += '</li>';
                }
        	}
        	return menu;
        })(xooki.toc);
    	menu += '</ul>';
    	return menu;
    },
    
    messages: function () {
        return '<div id="xooki-messages" onclick="xooki.html.hide(\'xooki-messages\')" style="zIndex:999;display:none;position:absolute;top:30px;padding:10px;border-style:solid;background:#eeeeee;"></div>';
    },

    debugPanel: function () {
        return '<div id="xooki-debug" style="display:none;margin-top:15px;padding:10px;border-style:solid;background:#eeeeee;"><strong>Xooki Console</strong><br/><textarea cols="100" rows="15" id="xooki-console">'+xooki.console+'</textarea><hr/><a href="javascript:xooki.debugShowDetail(document.getElementById(\'xooki-body\').innerHTML)">content</a> <a href="javascript:xooki.debugShowDetail(xooki.c.body)">xooki body</a> <a href="javascript:xooki.debugShowDetail(document.body.innerHTML)">whole body</a> <a href="javascript:xooki.action.evaluate()">evaluate</a><br/><textarea cols="100" rows="15" id="xooki-debug-detail"></textarea></div>';
    },

    printerFriendlyLocation: function () {
        return xooki.url.action("print");
    },

    printerFriendlyLink: function () {
        return '<a href="'+this.printerFriendlyLocation()+'">'+t('Printer Friendly')+'</a>';
    },

    breadCrumb: function () {
        var breadCrumb = '<span class="breadCrumb">';
		breadCrumb += (function (page) {
        	var breadCrumb = xooki.html.pageLink(page);
			if (page.meta.level >= 1) {
				breadCrumb = arguments.callee(page.meta.parent) + " &gt; " + breadCrumb;
			}
        	return breadCrumb;
        })(xooki.page);
		breadCrumb += '</span>';
		return breadCrumb;
    }
};

xooki.render = {};
xooki.render.printerFriendlyAsyncLoader = function(source, arr) {
	var root = arr[0];
	var page = arr[1];
    if (source == null) {
        return;
    }
	var level = page.meta.level - root.meta.level + 1;
	
    // compute printer friendly block
    var beginIndex = source.indexOf('<textarea id="xooki-source">');
    beginIndex += '<textarea id="xooki-source">'.length;
    var endIndex = source.lastIndexOf('</textarea>');
    source = source.substring(beginIndex, endIndex);
    
    var printerFriendly = "<h"+level+">"+page.title+"</h"+level+">";
    printerFriendly += xooki.input.format.main(source, level) + "<hr/>";
    // inject block in page
    var pf = document.getElementById('xooki-printerFriendly');
    pf.innerHTML += printerFriendly;    
    
    // continue recursive loading
   	var nextPage = xooki.toc.getNextPage(page, root);
   	if (nextPage != null) {
    	xooki.url.asyncLoadURL(pu(nextPage.id), xooki.render.printerFriendlyAsyncLoader, [root, nextPage]);
   	}
};

xooki.render.printerFriendlyAsync = function() {
	xooki.c.body = xooki.c.messages
	+ "<div id='xooki-printerFriendly'></div>" // div where printer friendly content will be put
    + xooki.c.debugPanel;
    
    document.body.innerHTML = xooki.string.processTemplate(xooki.template.body, xooki.c);
    
    // start async loading of content
    xooki.url.asyncLoadURL(pu(xooki.page.id), xooki.render.printerFriendlyAsyncLoader, [xooki.page, xooki.page]);
};

xooki.render.printerFriendlySync = function() {
	xooki.c.body = xooki.c.messages
    + (function (page, level) {
        var source = xooki.url.loadURL(pu(page.id));
        if (source == null) {
            return "";
        }
        var beginIndex = source.indexOf('<textarea id="xooki-source">');
        beginIndex += '<textarea id="xooki-source">'.length;
        var endIndex = source.lastIndexOf('</textarea>');
        source = source.substring(beginIndex, endIndex);
        
        var printerFriendly = "<div class='toc-title toc-title-"+level+"'>"+page.title+"</div>";
        printerFriendly += xooki.input.format.main(source, level);
        for (var i=0; i <page.children.length; i++) {
            printerFriendly += "<hr/>";
            printerFriendly += arguments.callee(page.children[i], level+1);
        }
        return printerFriendly;
    })(xooki.page, 1);
    
    xooki.html.setBody(xooki.string.processTemplate(xooki.template.body, xooki.c));
};

xooki.render.printerFriendly = function() {
    for (var k in xooki.component) {
        xooki.c[k] = xooki.component[k]();
    }
    
	if (batchMode) {
		xooki.render.printerFriendlySync();
	} else {
		xooki.render.printerFriendlyAsync();
	}
};


xooki.render.page = function() {
    // realize all components available
    for (var k in xooki.component) {
        xooki.c[k] = xooki.component[k]();
    }
    
    xooki.input.source();
    
    if (xooki.c.allowEdit) {
    	xooki.c.body = xooki.c.messages
            + xooki.c.toolbar
            + '<div id="xooki-content">' 
                + '<div id="xooki-body"></div>'
            + '</div>'
            + xooki.c.editZone
            + xooki.c.debugPanel;
    } else {
    	xooki.c.body = xooki.c.messages
            + '<div id="xooki-content">' 
                + '<div id="xooki-body"></div>'
            + '</div>'
            + xooki.c.debugPanel;
    }

    xooki.html.setBody(xooki.string.processTemplate(xooki.template.body, xooki.c));
    
    xooki.input.applyChanges();
};

xooki.render.main = function() {
    if (xooki.c.action == "print") {
        // render the printer friendly version of the page
        this.printerFriendly();
    } else {
        // render the page normally
        this.page();
    }
};

xooki.input = {
    source: function() {
        if (typeof document != 'undefined' && document.getElementById('xooki-source') != null) {
            this._source = document.getElementById('xooki-source').value;
        }
        return this._source;
    },
    processed: function() {
        return this.format.main(this.source());
    },
    
    format: {
        getInputFilters: function (inputFormat) {
            return xooki.c[inputFormat+"InputFormat"];
        },
        define: function (inputFormat, filters) {
            // define a new inputFormat
            // inputFormat: the new input format name
            // filters: an array of input filter names
            xooki.c[inputFormat+"InputFormat"] = filters;
        },
        main: function(source, level) {
            // formats an input source
            if (xooki.c.inputFormat && typeof this.getInputFilters(xooki.c.inputFormat) != "undefined") {
                format = xooki.c.inputFormat;
            } else {
                format = xooki.c.defaultInputFormat;
            }
            filters = this.getInputFilters(format);
            for (var i in filters) {
                if (typeof filters[i] == 'string') {
    				xooki.debug('processing filter '+filters[i]);
                    f = xooki.input.filters[filters[i]];
                    if (typeof f == "function") {
                    	try {
                        	source = f(source, level); // process filter
                        } catch (e) {
    	                    xooki.error(e, t("error occurred while processing filter ${0}", filters[i]));
                        }
                    } else {
                        xooki.error(t("unknown filter ${0} used in input format ${1}", filters[i], format));
                    }
                }
            }
            return source;
        }
    }, 
    
    filters: {
        url: function (input) {
            // handle urls
            return input.replace(new RegExp("(?:file|http|https|mailto|ftp):[^\\s'\"]+(?:/|\\b)", "g"), function (str, offset, s) {
                var before = s.substring(0,offset);
                if (before.match(/(href|src)="$/)) {
                    return str;
                } else {
                    return '<a href="'+str+'">'+str+'</a>';
                }
            });
        },
        
        shortcuts: function (input) {
            // handle shortcut links like this:
            //    [[svn:build.xml]] => <a href="https://xooki.svn.sourceforge.net/svnroot/xooki/trunk/build.xml">build.xml</a>
            //    [[svn:test/example.js a good example]] => <a href="https://xooki.svn.sourceforge.net/svnroot/xooki/trunk/test/example.js">a good example</a>
            // needs to be configured in xooki config like this
            //      xooki.c.shortcuts.<any shortcut>.url = base url of the shortcut. 
            //      ex: xooki.c.shortcuts.svn.url = https://xooki.svn.sourceforge.net/svnroot/xooki/trunk/
            return input.replace(new RegExp("\\[\\[([^:\n]+):([^\\]\n]+)\\]\\]", "g"), function (str, prefix, code, offset, s) {
            	if (typeof xooki.c.shortcuts == "undefined" || typeof xooki.c.shortcuts[prefix] == "undefined") {
                    xooki.debug('unknown shortcut '+prefix);
            		return str;
            	}
                var index = code.indexOf(' ');
                var path = index>0?code.substring(0,index):code;
                
                var title = index>0?code.substring(index+1):path;
                var pre = typeof xooki.c.shortcuts[prefix].pre == "undefined"?'':xooki.c.shortcuts[prefix].pre;
                var post = typeof xooki.c.shortcuts[prefix].post == "undefined"?'':xooki.c.shortcuts[prefix].post;
                return '<a href="'+pre+path+post+'">'+title+'</a>';
            });
        },
        
        xookiLinks: function (input) {
            // handle xooki links like this:
            //    [[page/id]]
            //    [[page/id My Title]]
            return input.replace(new RegExp("\\[\\[([^\\]]+)\\]\\]", "g"), function (str, code, offset, s) {
                var index = code.indexOf(' ');
                var id = (index>0?code.substring(0,index):code);
                
                var title;
                var url;
                var invalid = false;
                
                if (typeof xooki.toc.pages[xooki.toc.importRoot + id] != "undefined") {
               	    title = xooki.toc.pages[xooki.toc.importRoot + id].title;
                    url = pu(xooki.toc.importRoot + id);
               	} else if (xooki.toc.importRoot.length > 0 && typeof xooki.toc.pages[id] != "undefined") {
               	    title = xooki.toc.pages[id].title;
                    url = pu(id);
               	} else {
                    invalid = true;
               		title = code;
               		url = u(id);
               	}
                if (index>0) {
                	title = code.substring(index+1);
                }
                if (invalid) {
                    if (batchMode) {
                        // do not output invalid links as links in batch mode
                        return title;
                    } else {
                        return title+'<a href="'+url+'">?</a>';
                    }
                } else {
                    return '<a href="'+url+'">'+title+'</a>';
                }
            });
        },
        
        wikiMarkup: function (input) { 
            // handle bold
            input = input.replace(new RegExp("\\*([^\n]+)\\*", "g"), "<b>$1</b>");
            
            // handle italic
            input = input.replace(new RegExp("\\_([^\n]+)\\_", "g"), "<em>$1</em>");
            
            return input;
        },
        
        jira: function (input) { 
            // auto replace jira issue ids (like IVY-12) by a link to the issue
            // needs to be configured in xooki config like this
            //      xooki.c.jira.ids = an array of jira projects ids (ex: ["IVY", "ANT"])
            //      xooki.c.jira.url = the url of the jira server (ex: "http://issues.apache.org/jira")
            if (typeof xooki.c.jira != "object") {
                return input;
            }
            input = input.replace(new RegExp("(("+xooki.c.jira.ids.join("|")+")-\\d+)([^\"\\d])", "g"), '<a href="'+xooki.c.jira.url+'/browse/$1">$1</a>$3');
            
            return input;
        },
        
        code: function (input) {
            codeSection = xooki.string.findXmlSection(input, "code");
            from = 0;
            while (codeSection != null) {
                processedSection = "<pre>" 
                    + input.substring(codeSection.innerStart, codeSection.innerEnd).replace(/</g, "&lt;").replace(/>/g, "&gt;") // .replace(/\n/g, "<br/>")
                    + "</pre>";
                input = input.substring(0, codeSection.outerStart)
                    + processedSection
                    + input.substring(codeSection.outerEnd);
                from = codeSection.outerStart + processedSection.length;
    
                codeSection = xooki.string.findXmlSection(input, "code", from);
            }
            return input;
        },
        
        lineBreak: function (input) {
            return input.replace(new RegExp("\r?\n", "g"), function (str, offset, s) {
                var before = s.substring(0,offset);
                var after = s.substring(offset+str.length);
                if (after.match(/^<\/?(ul|table|li|pre|div)(\s*\w+="[^"]+")*\s*>/i) || (before.match(/<\/?\w+(\s*\w+="[^"]+")*\s*\/?>\s*$/i) && !before.match(/<\/?(a|b|strong|em|i|big|br class="xooki-br")(\s*\w+="[^"]+")*\s*\/?>\s*$/i))) { 
                    return '\n';
                } else {
                    return '<br class="xooki-br"/>'; // the class is not really necessary but allow to distinguish generated br from input one
                }
            });
        },
        
        includes: function (input) {
	        //[<url>] replaced by the content of the url
	        result = "";
	        lastStart = 0;
	        nextPos = input.indexOf("[<" , lastStart);
	        while( nextPos > 0 ) {
		        result = result + input.slice(lastStart,nextPos);
		        lastStart = nextPos;
		        nextPos = input.indexOf(">]" , lastStart);
		        result = result + xooki.url.loadURL(lu(input.slice(lastStart+2,nextPos)));
		        lastStart = nextPos + 2;
		        nextPos = input.indexOf("[<" , lastStart);
	        }
            return result + input.slice(lastStart);
        },

        printFormatImgFix: function (input, level) {
			if (level == undefined || level < 3) {
				return input;
			}
			return input.replace(new RegExp('<img +src *= *\\"([^\\"]*)\\"', "g"), function (str, img, offset, s) {
				l = level;
				while (l > 2) {
					if (img.indexOf("../") >= 0) {
						img = img.substring(3);
					} else {
						break;
					}
					l--;
				}
				return '<img src="'+img+'"';
			});
		}
    },
    
    
    applyChanges: function() {
    	document.getElementById('xooki-body').innerHTML = xooki.input.processed();
    }
};


xooki.postProcess = function() {
	xooki.render.main();
	window.onkeypress = keyCtrl;
};


if (typeof xooki.io == "undefined") {
    xooki.io = {};
}


xooki.action = {}
xooki.action.toggleDebug = function() {
    if (xooki.c.debug) {
    	if (document.getElementById('xooki-debug').style.display == 'none') {
    		xooki.html.show('xooki-debug');
    	} else {
    		xooki.html.hide('xooki-debug');
    	}
	}
}
xooki.action.evaluate = function () {
    var exp = prompt("Please enter javascript expression to evaluate");
    xooki.debugShowDetail(eval(exp));
}

// TODO, review use registration
function keyCtrl(evt) {
	var code = xooki.c.browser.NS ? evt.which : event.keyCode;
	var ctrl = xooki.c.browser.NS ? evt.ctrlKey : event.ctrlKey;
  	var key = String.fromCharCode(code);
	if (xooki.c.debug && ctrl && "d" == key) {
		xooki.action.toggleDebug();
		return false;
	}
	if (xooki.c.allowEdit && ctrl && "s" == key) {
		xooki.action.saveChanges();
		return false;
	}
	if (xooki.c.allowEdit && ctrl && "e" == key) {
		xooki.action.toggleEdit();
		return false;
	}
}

// xooki engine init function
xooki.init = function() {
    ////////////////////////////////////////////////////////////////////////////
    ////////////////// config init
    ////////////////////////////////////////////////////////////////////////////
    initConfigProperty = function(prop, value, defaultValue) {
        if (typeof this[prop] == "undefined") {
            if (typeof value == "undefined") {
                this[prop] = defaultValue;
            } else if (typeof value == "function") {
                this[prop] = value();
            } else {
                this[prop] = value;
            }
        }
    };
    if (typeof xookiConfig != "undefined") {xooki.util.mix(xookiConfig, xooki.config);}
    xooki.c.initProperty = initConfigProperty;
    xooki.c.computeRoot = function() {
    	root = xooki.pageURL;
    	// remove trailing parts of the URL to go the root depending on level
    	for (var i=0; i < xooki.c.level + 1; i++) {
    		root = root.substring(0, root.lastIndexOf('/'));
    	}
    	return root + '/';
    };
    xooki.c.computeRelativeRoot = function() {
    	return xooki.string.mul('../', xooki.c.level);
    };
    xooki.c.setImportLevel = function(level) {
        // compute roots with old level value, for paths relative to the local (non imported) root
        this.localRoot = this.computeRoot();
        this.localRelativeRoot = this.computeRelativeRoot();
        // change level and update roots
        this.level+=level;
        this.root = this.computeRoot();
        this.relativeRoot = this.computeRelativeRoot();
    };
    xooki.c.initProperty("level", 0);
    xooki.c.initProperty("root", xooki.c.computeRoot);
    xooki.c.initProperty("relativeRoot", xooki.c.computeRelativeRoot);
    xooki.c.initProperty("localRoot", xooki.c.root);
    xooki.c.initProperty("localRelativeRoot", xooki.c.relativeRoot);
    globalConfig = xooki.url.loadURL(u("config.json"), false);
    if (globalConfig != null && globalConfig.length != 0) {
        globalConfig = eval('('+globalConfig+')');
        xooki.util.mix(globalConfig, xooki.c, false);
    }
    xooki.url.evalURL(u("config.js"), false);
    xooki.url.evalURL(u("config.extra.js"), false);


    xooki.c.initProperty("defaultInputFormat", "xooki");
    xooki.c.initProperty("xookiInputFormat", ["xooki"]);
    xooki.c.initProperty("allowEdit", !batchMode && xooki.pageURL.substr(0,5) == "file:");
    
    xooki.input.format.define("xooki", ["code", "shortcuts", "url", "xookiLinks", "jira", "lineBreak" , "includes", "printFormatImgFix"]);
    
    xooki.c.path = (typeof xooki.c.path != "undefined")?xooki.c.path:{};
    xooki.c.path.initProperty = initConfigProperty;
    xooki.c.path.initProperty("install", "xooki");
    xooki.c.path.initProperty("messages", xooki.p("messages.json"));
    xooki.c.path.initProperty("template", "template.html");
    xooki.c.path.initProperty("printTemplate", "printTemplate.html");
    xooki.c.path.initProperty("toc", "toc.json");
    xooki.c.path.initProperty("blankPageTpl", xooki.p("blankPageTpl.html"));
    
    
    xooki.c.css = (typeof xooki.c.css != "undefined")?xooki.c.css:{};    
        
    xooki.c.messages = xooki.json.loadURL(cu("messages")); 
	if (!batchMode) {
	    xooki.c.browser = {
	        NS: (window.Event) ? 1 : 0
	    };
    
	    // action
	    if (! xooki.c.action) xooki.c.action = 'render';
	    // TODO: better handle action extraction
		xooki.c.action = window.location.search == '?action=print'?'print':xooki.c.action;
	}
	
	var match = new RegExp("^.*\\/((?:.*\\/){"+xooki.c.level+"}[^\\/]*)(?:\\.\\w+)(?:\\?.+)?$", "g").exec(xooki.pageURL);
	if (match == null || match[1] == '') {
		xooki.c.curPageId = "index";
	} else {
		xooki.c.curPageId = match[1];
	}
    
    ////////////////////////////////////////////////////////////////////////////
    ////////////////// TOC init
    ////////////////////////////////////////////////////////////////////////////
    xooki.toc = xooki.json.loadURL(cu("toc"));
    xooki.toc.url = cu("toc");
    xooki.toc.pages = {}; // to store a by id map of pages objects
    xooki.toc.importRoot = '';
    xooki.toc.actualRoot = xooki.toc; // this is the real root of the TOC, in case of a TOC imported, it will point to the root of the TOC on which import has been performed

	// populate meta data
	(function(page, parent, index, level, prefix) {
        if (prefix.length > 0) {
            page.meta = xooki.util.mix({id: page.id}, page.meta);
            page.id = prefix + page.id;
        }
        xooki.toc.pages[page.id] = page;
        
        page.meta = xooki.util.mix({
            index: index,
            level: level,
            getSerializeValue: function(o, k) {
                if (k == 'id' && typeof this.id != 'undefined') {
                    return this.id;
                } else {
                    return o[k];
                }
            }
        }, page.meta);
        page.meta.parent = parent;
        if (typeof page.importNode != 'undefined' && !page.isImported) {
            // this node requires to import another xooki TOC
            importedTocUrl = u(page.importRoot + '/toc.json');
            importedToc = xooki.json.loadURL(importedTocUrl);
            // look for the imported node in the importedTOC and import it in main TOC
            (function(page, parent, index, level, prefix, importedToc, node, id, populateFunction) {
                if (node.id == id) {
                    xooki.util.mix(node, page, false);
                    page.id = id;
                    page.isImported = true;
                    page.meta = xooki.util.mix({
                        isTransient: function(k) {
                            // only title, importRoot and importNode should be serialized
                            return k != 'title' && k != 'importRoot' && k != 'importNode';
                        }
                    }, page.meta);
                    if (xooki.c.curPageId.indexOf(prefix) == 0) {
                        // the current page is in this imported TOC
                        xooki.toc.actualRoot = importedToc;
                        xooki.toc.url = u(page.importRoot + '/toc.json');
                        xooki.toc.importRoot = prefix;
                    }
                    populateFunction(page, parent, index, level, prefix);
                    return true;
                } else if (typeof node.children != 'undefined') {
                    for (var i=0; i<node.children.length; i++) {
                        if (arguments.callee(page, parent, index, level, prefix, importedToc, node.children[i], id, populateFunction)) {
                            return true;
                        }
                    }
                }
                return false;
            })(page, parent, index, level, page.importRoot+'/', importedToc, importedToc, page.importNode, arguments.callee);
        }
        if (typeof page.children == 'undefined') {
            page.children = [];
        } else {
            for (var i=0; i<page.children.length; i++) {
                arguments.callee(page.children[i], page, i, level+1, prefix); // recurse
            }
        }
    })(xooki.toc, null, 0, -1, '');
    
    xooki.toc.getNextPage = function(page, root) {
        if (page.children.length > 0) {
        	return page.children[0];
        } else if (page.meta.parent != null) {
        	var cur = page;
        	var next = xooki.toc.getNextSibling(cur);
        	while (next == null) {
        		cur = cur.meta.parent;
        		if (cur == null || cur == root) {
        			return null;
        		}
        		next = xooki.toc.getNextSibling(cur);
        	}
       		return next;
        } else {
        	return null;
        }
    };
    xooki.toc.getNextSibling = function(page) {
    	if (page.meta.parent == null) {
    		return null;
    	}
       	if (page.meta.parent.children.length > page.meta.index) {
       		return page.meta.parent.children[page.meta.index+1];
       	} else {
       		return null;
       	}
    };
	xooki.page = xooki.toc.pages[xooki.c.curPageId];

	if (xooki.page == null) {
		xooki.warn(t('page id not found in TOC: ${0}',xooki.c.curPageId));
		xooki.page = xooki.toc.children[0];
	} 
	if (typeof xooki.config.title == 'undefined') {
		xooki.config.title = xooki.page.title;
	}		
	xooki.config.page = xooki.page;
	
    ////////////////////////////////////////////////////////////////////////////
    ////////////////// main template loading + head output
    ////////////////////////////////////////////////////////////////////////////
	xooki.template = {};
    xooki.template.source = xooki.url.loadURL(xooki.c.action == "print"?cu("printTemplate"):cu("template"));
	if(xooki.template.source != null) {
		xooki.template.head = xooki.template.source.match(/<head>([^�]*)<\/head>/im)[1];
		var root = batchMode?xooki.c.relativeRoot:xooki.c.root;
		
        var head = xooki.string.processTemplate(xooki.template.head, xooki.config);
		head = head.replace(/href="([^\\$:"]+)"/g, 'href="'+root+'$1"');
		head = head.replace(/src="([^\\$:"]+)"/g, 'src="'+root+'$1"');
		xooki.html.addHeader(head);

		var body = xooki.template.source.match(/<body>([^�]*)<\/body>/im)[1];
		body = body.replace(/href="([^\\$:"]+)"/g, 'href="'+root+'$1"');
		xooki.template.body = body.replace(/src="([^\\$:"]+)"/g, 'src="'+root+'$1"');		
	}
	

    ////////////////////////////////////////////////////////////////////////////
    ////////////////// includes
    ////////////////////////////////////////////////////////////////////////////
	if (batchMode) {
		xooki.html.addHeader('<script language="javascript" type="text/javascript">xooki = {u: function(url) {return "'+xooki.c.relativeRoot+'xooki/"+url;}};</script>');
	}
    if (xooki.c.allowEdit) {
        xooki.url.include("xookiEdit.js");
    }

    for (var k in xooki.c) {
        if (typeof xooki.c[k] == "string" || typeof xooki.c[k] == "number" || typeof xooki.c[k] == "boolean") {
            xooki.debug(k+": "+xooki.c[k]);
        }
    }
};

if (batchMode) {
	importPackage(java.io);
	
	xooki.io.loadFile = function( url, warnOnError ) {
	  var str = '';
	  try {
      var r = new BufferedReader(new FileReader(url));
	  line = r.readLine();
	  while (line != null) {
		str += line + '\n';
		line = r.readLine();
	  }
	  r.close();
	  } catch (e) {
	  	if (warnOnError) {
	  		throw e;
	  	} else {
	  		xooki.debug("error occurred while loading "+url);
	  	}
	  }
	  return str;
    };
	
	xooki.io.saveFile = function (fileUrl, content) {
		p = new File(fileUrl).getParentFile();
		if (p != null) {
			p.mkdirs();
		}
		pw = new PrintWriter(new FileWriter(fileUrl));
		pw.write(content);
		pw.close();
		return true;
	}

    xooki.url.loadURL = function( url, warnOnError ) {
		return xooki.io.loadFile(url, warnOnError );
	};
	
	xooki.html.addHeader = function (head) {
		xooki.pageContent = xooki.pageContent.replace(/<\/head>/, head+'\n</head>');
	};
	
	xooki.html.setBody = function(body) {
		xooki.pageContent = xooki.pageContent.replace(/<body>(.|[^,])*<\/body>/gm, '<body>'+body+'</body>');
	}
	
	xooki.url.include = function(script_filename) {
		xooki.html.addHeader('<script language="javascript" type="text/javascript" src="'+xooki.c.relativeRoot+'xooki/'+script_filename+'"></script>');
	};
	
	xooki.input.source = function() {
		if (typeof this._source == 'undefined') {
			xooki.debug('searching source');
			var beg = xooki.pageContent.indexOf('<textarea id="xooki-source">');
			beg += '<textarea id="xooki-source">'.length;
			var end = xooki.pageContent.lastIndexOf('</textarea>');
			this._source = xooki.pageContent.substring(beg, end);
			xooki.debug('source found');
		}
		return this._source;
	}
	
	xooki.render.page = function() {
	    // realize all components available
		xooki.debug('realizing components');
	    for (var k in xooki.component) {
	        xooki.c[k] = xooki.component[k]();
	    }
	    
		xooki.debug('processing body');
		xooki.c.body = xooki.input.processed();

		xooki.debug('updating body');
		var body = xooki.string.processTemplate(xooki.template.body, xooki.c);
	    xooki.html.setBody(body);
	};

	xooki.display = function(message, background) {
		print(message);
	};
	
	xooki.debug = function (message) {
		if (xooki.c.debug) {
			print(message+'\n');
		}
	};
	var i=0;
	if (arguments.length > i && arguments[0] == '-debug') {
		xooki.c.debug = true;
		i++;
	} else {
		xooki.c.debug = false;
	}
	
	var file = 'index.html';
	if (arguments.length > i) {
		file = arguments[i];
		i++;
	}
	var generateTo = "gen";
	if (arguments.length > i) {
		generateTo = arguments[i];
		i++;
	}
	xooki.c.action = 'render';
	if (arguments.length > i) {
		xooki.c.action = arguments[i];
		i++;
	}

	xooki.pageURL = new File(file).toURL().toExternalForm();
	
	print('processing '+new File(file).getAbsolutePath()+'...\n');
	xooki.pageContent = xooki.io.loadFile(file);
    
    if (xooki.pageContent.match(/<textarea\s+id="xooki\-source">/) == null) {
        print(file + ' is not a valid xooki source. ignored.');
    } else {	
    	var m = /var\s+xookiConfig\s+=\s+{.*};/.exec(xooki.pageContent);
    	if (typeof m != 'undefined' && m != null) {
    		eval(m[0]);
    	}

        xooki.init();
        
    	xooki.pageContent = xooki.pageContent.replace(/<script type="text\/javascript" src="[^"]*xooki.js"><\/script>/g, '');
    	
    	xooki.render.main();

		var dest = generateTo.endsWith(".html") ? generateTo : generateTo+'/'+file;
    	print('generating to '+dest);
    	xooki.io.saveFile(dest, xooki.pageContent);
    }
} else {
	xooki.pageURL = window.location.toString();
    xooki.init();
}

