/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.docs");
dojo.require("dojo.io.*");
dojo.require("dojo.event.topic");
dojo.require("dojo.rpc.JotService");
dojo.require("dojo.dom");
dojo.require("dojo.uri.Uri");
dojo.require("dojo.Deferred");
dojo.require("dojo.DeferredList");

/*
 * TODO:
 *
 * Package summary needs to compensate for "is"
 * Handle host environments
 * Deal with dojo.widget weirdness
 * Parse parameters
 * Limit function parameters to only the valid ones (Involves packing parameters onto meta during rewriting)
 *
 */

dojo.docs = new function() {
	this._url = dojo.uri.dojoUri("docscripts");
	this._rpc = new dojo.rpc.JotService;
	this._rpc.serviceUrl = dojo.uri.dojoUri("docscripts/jsonrpc.php");
};
dojo.lang.mixin(dojo.docs, {
	_count: 0,
	_callbacks: {function_names: []},
	_cache: {}, // Saves the JSON objects in cache
	require: function(/*String*/ require, /*bool*/ sync) {
		dojo.debug("require(): " + require);
		var parts = require.split("/");

		var size = parts.length;
		var deferred = new dojo.Deferred;
		var args = {
			mimetype: "text/json",
			load: function(type, data){
				dojo.debug("require(): loaded for " + require);

				if(parts[0] != "function_names") {
					for(var i = 0, part; part = parts[i]; i++){
						data = data[part];
					}
				}
				deferred.callback(data);
			},
			error: function(){
				deferred.errback();
			}
		};

		if(location.protocol == "file:"){
			if(size){
				if(parts[parts.length - 1] == "documentation"){
					parts[parts.length - 1] = "meta";
				}

				if(parts[0] == "function_names"){
					args.url = [this._url, "local_json", "function_names"].join("/");
				}else{
					var dirs = parts[0].split(".");
					args.url = [this._url, "local_json", dirs[0]].join("/");
					if(dirs.length > 1){
						args.url = [args.url, dirs[1]].join(".");
					}
				}
			}
		}

		dojo.io.bind(args);
		return deferred;
	},
	getFunctionNames: function(){
		return this.require("function_names"); // dojo.Deferred
	},
	unFormat: function(/*String*/ string){
		var fString = string;
		if(string.charAt(string.length - 1) == "_"){
			fString = [string.substring(0, string.length - 1), "*"].join("");
		}
		return fString;
	},
	getMeta: function(/*String*/ pkg, /*String*/ name, /*Function*/ callback, /*String?*/ id){
		// summary: Gets information about a function in regards to its meta data
		if(typeof name == "function"){
			// pId: a
			// pkg: ignore
			id = callback;
			callback = name;
			name = pkg;
			pkg = null;
			dojo.debug("getMeta(" + name + ")");
		}else{
			dojo.debug("getMeta(" + pkg + "/" + name + ")");
		}

		if(!id){
			id = "_";
		}
	},
	_withPkg: function(/*String*/ type, /*Object*/ data, /*Object*/ evt, /*Object*/ input, /*String*/ newType){
		dojo.debug("_withPkg(" + evt.name + ") has package: " + data[0]);
		evt.pkg = data[0];
		if("load" == type && evt.pkg){
			evt.type = newType;
		}else{
			if(evt.callbacks && evt.callbacks.length){
				evt.callbacks.shift()("error", {}, evt, evt.input);
			}
		}
	},
	_gotMeta: function(/*String*/ type, /*Object*/ data, /*Object*/ evt){
		dojo.debug("_gotMeta(" + evt.name + ")");

		var cached = dojo.docs._getCache(evt.pkg, evt.name, "meta", "functions", evt.id);
		if(cached.summary){
			data.summary = cached.summary;
		}
		if(evt.callbacks && evt.callbacks.length){
			evt.callbacks.shift()(type, data, evt, evt.input);
		}
	},
	getSrc: function(/*String*/ name, /*Function*/ callback, /*String?*/ id){
		// summary: Gets src file (created by the doc parser)
		dojo.debug("getSrc(" + name + ")");
		if(!id){
			id = "_";
		}
	},
	getDoc: function(/*String*/ name, /*Function*/ callback, /*String?*/ id){
		// summary: Gets external documentation stored on Jot for a given function
		dojo.debug("getDoc(" + name  + ")");

		if(!id){
			id = "_";
		}

		var input = {};

		input.type = "doc";
		input.name = name;
		input.callbacks = [callback];
	},
	_gotDoc: function(/*String*/ type, /*Array*/ data, /*Object*/ evt, /*Object*/ input){
		dojo.debug("_gotDoc(" + evt.type + ")");

		evt[evt.type] = data;
		if(evt.expects && evt.expects.doc){
			for(var i = 0, expect; expect = evt.expects.doc[i]; i++){
				if(!(expect in evt)){
					dojo.debug("_gotDoc() waiting for more data");
					return;
				}
			}
		}

		var cache = dojo.docs._getCache(evt.pkg, "meta", "functions", evt.name, evt.id, "meta");

		var description = evt.fn.description;
		cache.description = description;
		data = {
			returns: evt.fn.returns,
			id: evt.id,
			variables: []
		}
		if(!cache.parameters){
			cache.parameters = {};
		}
		for(var i = 0, param; param = evt.param[i]; i++){
			var fName = param["DocParamForm/name"];
			if(!cache.parameters[fName]){
				cache.parameters[fName] = {};
			}
			cache.parameters[fName].description = param["DocParamForm/desc"]
		}

		data.description = cache.description;
		data.parameters = cache.parameters;

		evt.type = "doc";

		if(evt.callbacks && evt.callbacks.length){
			evt.callbacks.shift()("load", data, evt, input);
		}
	},
	getPkgDoc: function(/*String*/ name, /*Function*/ callback){
		// summary: Gets external documentation stored on Jot for a given package
		dojo.debug("getPkgDoc(" + name + ")");
		var input = {};
	},
	getPkgInfo: function(/*String*/ name, /*Function*/ callback){
		// summary: Gets a combination of the metadata and external documentation for a given package
		dojo.debug("getPkgInfo(" + name + ")");

		var input = {
			expects: {
				pkginfo: ["pkgmeta", "pkgdoc"]
			},
			callback: callback
		};
		dojo.docs.getPkgMeta(input, name, dojo.docs._getPkgInfo);
		dojo.docs.getPkgDoc(input, name, dojo.docs._getPkgInfo);
	},
	_getPkgInfo: function(/*String*/ type, /*Object*/ data, /*Object*/ evt){
		dojo.debug("_getPkgInfo() for " + evt.type);
		var input = {};
		var results = {};
		if(typeof key == "object"){
			input = key;
			input[evt.type] = data;
			if(input.expects && input.expects.pkginfo){
				for(var i = 0, expect; expect = input.expects.pkginfo[i]; i++){
					if(!(expect in input)){
						dojo.debug("_getPkgInfo() waiting for more data");
						return;
					}
				}
			}
			results = input.pkgmeta;
			results.description = input.pkgdoc;
		}

		if(input.callback){
			input.callback("load", results, evt);
		}
	},
	getInfo: function(/*String*/ name, /*Function*/ callback){
		dojo.debug("getInfo(" + name + ")");
		var input = {
			expects: {
				"info": ["meta", "doc"]
			},
			callback: callback
		}
		dojo.docs.getMeta(input, name, dojo.docs._getInfo);
		dojo.docs.getDoc(input, name, dojo.docs._getInfo);
	},
	_getInfo: function(/*String*/ type, /*String*/ data, /*Object*/ evt, /*Object*/ input){
		dojo.debug("_getInfo(" + evt.type + ")");
		if(input && input.expects && input.expects.info){
			input[evt.type] = data;
			for(var i = 0, expect; expect = input.expects.info[i]; i++){
				if(!(expect in input)){
					dojo.debug("_getInfo() waiting for more data");
					return;
				}
			}
		}

		if(input.callback){
			input.callback("load", dojo.docs._getCache(evt.pkg, "meta", "functions", evt.name, evt.id, "meta"), evt, input);
		}
	},
	_getMainText: function(/*String*/ text){
		// summary: Grabs the innerHTML from a Jot Rech Text node
		dojo.debug("_getMainText()");
		return text.replace(/^<html[^<]*>/, "").replace(/<\/html>$/, "").replace(/<\w+\s*\/>/g, "");
	},
	getPackageMeta: function(/*Object*/ input){
		dojo.debug("getPackageMeta(): " + input.package);
		return this.require(input.package + "/meta", input.sync);
	},
	getFunctionMeta: function(/*Object*/ input){
		var package = input.package || "";
		var name = input.name;
		var id = input.id || "_";
		dojo.debug("getFunctionMeta(): " + name);

		if(!name) return;

		if(package){
			return this.require(package + "/meta/functions/" + name + "/" + id + "/meta");
		}else{
			this.getFunctionNames();
		}
	},
	getFunctionDocumentation: function(/*Object*/ input){
		var package = input.package || "";
		var name = input.name;
		var id = input.id || "_";
		dojo.debug("getFunctionDocumentation(): " + name);

		if(!name) return;

		if(package){
			return this.require(package + "/meta/functions/" + name + "/" + id + "/documentation");
		}
	},
	_onDocSearch: function(/*Object*/ input){
		var _this = this;
		var name = input.name.toLowerCase();
		if(!name) return;

		this.getFunctionNames().addCallback(function(data){
			dojo.debug("_onDocSearch(): function names loaded for " + name);

			var output = [];
			var list = [];
			var closure = function(pkg, fn) {
				return function(data){
					dojo.debug("_onDocSearch(): package meta loaded for: " + pkg);
					if(data.functions){
						var functions = data.functions;
						for(var key in functions){
							if(fn == key){
								var ids = functions[key];
								for(var id in ids){
									var fnMeta = ids[id];
									output.push({
										package: pkg,
										name: fn,
										id: id,
										summary: fnMeta.summary
									});
								}
							}
						}
					}
					return output;
				}
			}

			pkgLoop:
			for(var pkg in data){
				if(pkg.toLowerCase() == name){
					name = pkg;
					dojo.debug("_onDocSearch found a package");
					//dojo.docs._onDocSelectPackage(input);
					return;
				}
				for(var i = 0, fn; fn = data[pkg][i]; i++){
					if(fn.toLowerCase().indexOf(name) != -1){
						dojo.debug("_onDocSearch(): Search matched " + fn);
						var meta = _this.getPackageMeta({package: pkg});
						meta.addCallback(closure(pkg, fn));
						list.push(meta);

						// Build a list of all packages that need to be loaded and their loaded state.
						continue pkgLoop;
					}
				}
			}

			list = new dojo.DeferredList(list);
			list.addCallback(function(results){
				dojo.debug("_onDocSearch(): All packages loaded");
				_this._printFunctionResults(results[0][1]);
			});
		});
	},
	_onDocSearchFn: function(/*String*/ type, /*Array*/ data, /*Object*/ evt){
		dojo.debug("_onDocSearchFn(" + evt.name + ")");

		var name = evt.name || evt.pkg;

		dojo.debug("_onDocSearchFn found a function");

		evt.pkgs = packages;
		evt.pkg = name;
		evt.loaded = 0;
		for(var i = 0, pkg; pkg = packages[i]; i++){
			dojo.docs.getPkgMeta(evt, pkg, dojo.docs._onDocResults);
		}
	},
	_onPkgResults: function(/*String*/ type, /*Object*/ data, /*Object*/ evt, /*Object*/ input){
		dojo.debug("_onPkgResults(" + evt.type + ")");
		var description = "";
		var path = "";
		var methods = {};
		var requires = {};
		if(input){
			input[evt.type] = data;
			if(input.expects && input.expects.pkgresults){
				for(var i = 0, expect; expect = input.expects.pkgresults[i]; i++){
					if(!(expect in input)){
						dojo.debug("_onPkgResults() waiting for more data");
						return;
					}
				}
			}
			path = input.pkgdoc.path;
			description = input.pkgdoc.description;
			methods = input.pkgmeta.methods;
			requires = input.pkgmeta.requires;
		}
		var pkg = evt.name.replace("_", "*");
		var results = {
			path: path,
			description: description,
			size: 0,
			methods: [],
			pkg: pkg,
			requires: requires
		}
		var rePrivate = /_[^.]+$/;
		for(var method in methods){
			if(!rePrivate.test(method)){
				for(var pId in methods[method]){
					results.methods.push({
						pkg: pkg,
						name: method,
						id: pId,
						summary: methods[method][pId].summary
					})
				}
			}
		}
		results.size = results.methods.length;
		dojo.docs._printPkgResult(results);
	},
	_onDocResults: function(/*String*/ type, /*Object*/ data, /*Object*/ evt, /*Object*/ input){
		dojo.debug("_onDocResults(" + evt.name + "/" + input.pkg + ") " + type);
		++input.loaded;

		if(input.loaded == input.pkgs.length){
			var pkgs = input.pkgs;
			var name = input.pkg;
			var results = {methods: []};
			var rePrivate = /_[^.]+$/;
			data = dojo.docs._cache;

			for(var i = 0, pkg; pkg = pkgs[i]; i++){
				var methods = dojo.docs._getCache(pkg, "meta", "methods");
				for(var fn in methods){
					if(fn.toLowerCase().indexOf(name) == -1){
						continue;
					}
					if(fn != "requires" && !rePrivate.test(fn)){
						for(var pId in methods[fn]){
							var result = {
								pkg: pkg,
								name: fn,
								id: "_",
								summary: ""
							}
							if(methods[fn][pId].summary){
								result.summary = methods[fn][pId].summary;
							}
							results.methods.push(result);
						}
					}
				}
			}

			dojo.debug("Publishing docResults");
			dojo.docs._printFnResults(results);
		}
	},
	_printFunctionResults: function(results){
		dojo.debug("_printFnResults(): called");
		// summary: Call this function to send the /docs/function/results topic
	},
	_printPkgResult: function(results){
		dojo.debug("_printPkgResult(): called");
	},
	_onDocSelectFunction: function(/*Object*/ input){
		// summary: Get doc, meta, and src
		var name = input.name;
		var package = input.package || "";
		var id = input.id || "_";
		dojo.debug("_onDocSelectFunction(" + name + ")");
		if(!name || !package) return false;

		var pkgMeta = this.getPackageMeta({package: package});
		var meta = this.getFunctionMeta({package: package, name: name, id: id});
		var doc = this.getFunctionDocumentation({package: package, name: name, id: id});

		var list = new dojo.DeferredList([pkgMeta, meta, doc]);
		list.addCallback(function(results){
			dojo.debug("_onDocSelectFunction() loaded");
			for(var i = 0, result; result = results[i]; i++){
				dojo.debugShallow(result[1]);
			}
		});

		return list;
	},
	_onDocSelectPackage: function(/*Object*/ input){
		dojo.debug("_onDocSelectPackage(" + input.name + ")")
		input.expects = {
			"pkgresults": ["pkgmeta", "pkgdoc"]
		};
		dojo.docs.getPkgMeta(input, input.name, dojo.docs._onPkgResults);
		dojo.docs.getPkgDoc(input, input.name, dojo.docs._onPkgResults);
	},
	_onDocSelectResults: function(/*String*/ type, /*Object*/ data, /*Object*/ evt, /*Object*/ input){
		dojo.debug("_onDocSelectResults(" + evt.type + ", " + evt.name + ")");
		if(evt.type == "meta"){
			dojo.docs.getPkgMeta(input, evt.pkg, dojo.docs._onDocSelectResults);
		}
		if(input){
			input[evt.type] = data;
			if(input.expects && input.expects.docresults){
				for(var i = 0, expect; expect = input.expects.docresults[i]; i++){
					if(!(expect in input)){
						dojo.debug("_onDocSelectResults() waiting for more data");
						return;
					}
				}
			}
		}

		dojo.docs._printFunctionDetail(input);
	},

	_printFunctionDetail: function(results) {
		// summary: Call this function to send the /docs/function/detail topic event
	},

	selectFunction: function(/*String*/ name, /*String?*/ id){
		// summary: The combined information
	},
	savePackage: function(/*Object*/ callbackObject, /*String*/ callback, /*Object*/ parameters){
		dojo.event.kwConnect({
			srcObj: dojo.docs,
			srcFunc: "_savedPkgRpc",
			targetObj: callbackObject,
			targetFunc: callback,
			once: true
		});

		var props = {};
		var cache = dojo.docs._getCache(parameters.pkg, "meta");

		var i = 1;

		if(!cache.path){
			var path = "id";
			props[["pname", i].join("")] = "DocPkgForm/require";
			props[["pvalue", i++].join("")] = parameters.pkg;
		}else{
			var path = cache.path;
		}

		props.form = "//DocPkgForm";
		props.path = ["/WikiHome/DojoDotDoc/", path].join("");

		if(parameters.description){
			props[["pname", i].join("")] = "main/text";
			props[["pvalue", i++].join("")] = parameters.description;
		}

		dojo.docs._rpc.callRemote("saveForm",	props).addCallbacks(dojo.docs._pkgRpc, dojo.docs._pkgRpc);
	},
	_pkgRpc: function(data){
		if(data.name){
			dojo.docs._getCache(data["DocPkgForm/require"], "meta").path = data.name;
			dojo.docs._savedPkgRpc("load");
		}else{
			dojo.docs._savedPkgRpc("error");
		}
	},
	_savedPkgRpc: function(type){
	},
	functionPackages: function(/*String*/ name, /*Function*/ callback, /*Object*/ input){
		// summary: Gets the package associated with a function and stores it in the .pkg value of input
		dojo.debug("functionPackages() name: " + name);

		if(!input){
			input = {};
		}
		if(!input.callbacks){
			input.callbacks = [];
		}

		input.type = "function_names";
		input.name = name;
		input.callbacks.unshift(callback);
		input.callbacks.unshift(dojo.docs._functionPackages);
	},
	_functionPackages: function(/*String*/ type, /*Array*/ data, /*Object*/ evt){
		dojo.debug("_functionPackages() name: " + evt.name);
		evt.pkg = '';

		var results = [];
		var data = dojo.docs._cache['function_names'];
		for(var key in data){
			if(dojo.lang.inArray(data[key], evt.name)){
				dojo.debug("_functionPackages() package: " + key);
				results.push(key);
			}
		}

		if(evt.callbacks && evt.callbacks.length){
			evt.callbacks.shift()(type, results, evt, evt.input);
		}
	},
	setUserName: function(/*String*/ name){
		dojo.docs._userName = name;
		if(name && dojo.docs._password){
			dojo.docs._logIn();
		}
	},
	setPassword: function(/*String*/ password){
		dojo.docs._password = password;
		if(password && dojo.docs._userName){
			dojo.docs._logIn();
		}
	},
	_logIn: function(){
		dojo.io.bind({
			url: dojo.docs._rpc.serviceUrl.toString(),
			method: "post",
			mimetype: "text/json",
			content: {
				username: dojo.docs._userName,
				password: dojo.docs._password
			},
			load: function(type, data){
				if(data.error){
					dojo.docs.logInSuccess();
				}else{
					dojo.docs.logInFailure();
				}
			},
			error: function(){
				dojo.docs.logInFailure();
			}
		});
	},
	logInSuccess: function(){},
	logInFailure: function(){},
	_set: function(/*Object*/ base, /*String...*/ keys, /*String*/ value){
		var args = [];
		for(var i = 0, arg; arg = arguments[i]; i++){
			args.push(arg);
		}

		if(args.length < 3) return;
		base = args.shift();
		value = args.pop();
		var key = args.pop();
		for(var i = 0, arg; arg = args[i]; i++){
			if(typeof base[arg] != "object"){
				base[arg] = {};
			}
			base = base[arg];
		}
		base[key] = value;
	},
	_getCache: function(/*String...*/ keys){
		var obj = dojo.docs._cache;
		for(var i = 0; i < arguments.length; i++){
			var arg = arguments[i];
			if(!obj[arg]){
				obj[arg] = {};
			}
			obj = obj[arg];
		}
		return obj;
	}
});

dojo.event.topic.subscribe("/docs/search", dojo.docs, "_onDocSearch");
dojo.event.topic.subscribe("/docs/function/select", dojo.docs, "_onDocSelectFunction");
dojo.event.topic.subscribe("/docs/package/select", dojo.docs, "_onDocSelectPackage");

dojo.event.topic.registerPublisher("/docs/function/results", dojo.docs, "_printFunctionResults");
dojo.event.topic.registerPublisher("/docs/function/detail", dojo.docs, "_printFunctionDetail");
dojo.event.topic.registerPublisher("/docs/package/detail", dojo.docs, "_printPkgResult");