﻿if(! ("Wiki" in window)){
	window.Wiki = {
		IModel:{},// interface for Model definition
		Model:{},//real class definition for model
		IView:{},// interface for View
		View:{},// real Class defined for View
		TView:{},// HTML template for View
		I18N:{}// Multi-Lang support
	};
}
Wiki.TView.getPF=function(name, params){
	var pf = name.split(".");
	var mod = (pf[0] in this)?this[pf[0]]:null;
	return (mod && (pf[1] in mod))?mod[pf[1]].loopReplace(IX.Utils.loop(mod._paramList[pf[1]],[], function(acc, item, idx){
		return IX.Utils.pushx(acc, ["#"+item +"#", params[idx]]);
	})):"";
};
Wiki.I18N.get=function(name){
	var str = IX.Utils.loop(name.split("."), this, function(acc, item){
		return (acc && (item in acc))? acc[item]:null;
	});
	return isString(str)?str:name;
};
Wiki.Object = Object.inherit(IX.Object, {
// Componenet ID definition;
	__ITEM: 0,// wiki item
	__SECTION: 1,// all sections in page
	__LINKS: 2,
	__COMMENTS:3,
	__ATTACHMENTS:4,
	__COMMENT:5,
	__TAGS:6,		// Tags
	__UNUSED1:7,  	// unused now
	__QUICKLINKS:8,
	__KITEMS:9,
	__KITEM:10,
	__KIMAGE:11,
	__DESCRIPTION:12,
	__SITEMS:13, 	//search items
	__SITEM:14,
	__ITEMS: 15,
	__BACKLOG:16,
	__DOCUMENT:17,
	__DEVELOPMENT:18,

	__UNKNOWN: 90, // temporary node ;
	__TOC:91, // not model, just a view;

// Item Type ID definition;
	__UNUSED2: 100, // page but not wiki page;unused now
	__WIKI: 101,			// knowledge item in wiki
	__WIKI_KFOLDER:102,	//knowledge folder in wiki
	__WIKI_IMAGE:103,	//image in wiki
	__WIKI_RFOLDER:104,	//requirement folder in wiki
	__WIKI_IFOLDER:105,	//imagebase folder in wiki

	__WIKI_BOOKITEM:106,	//item in book
	__WIKI_BOOKFOLDER:107, // folder in book

	__WIKI_TEMPLATEITEM:108, // item in template
	__WIKI_TEMPLATEITEM:109, // requirement item in wiki

// MVC frame ID definition;
	__WIKI_MODEL: 1000,
	__WIKI_VIEW: 1001,
	__WIKI_CONTROLLER: 1002
});

//TO BE Reimplement as CLASS for multi-Wiki in one Page;
Wiki.Config = {// Configuration for whole wiki component
	name:"wikiController", // id for multi-wiki view 
	base:"",
	lang:"zh-cn",
	readonly:false,
	isLocalMode:false,
	ifHTMLSection:true, // true: all summary and sections are in an HTML page fragments.

	isJsMassed:false,
	massed_js:"wiki.js",
	ifPreview:false,
	
	editor_wrapper:"../ixEditor.htm",
	max_edit_size:"200K", //[k|K|m|M]

	tview_js:"template/wikiview.js",
	view_css:"template/default.css",
	
	wiki_js_list:["wikiAux.js","wikiModel.js","wikiViewBase.js","wikiView.js","wikiWView.js","wikiController.js"],

	useLayerDialog:true,
	mdialog_wrapper:"ixDialog.htm",
	ifShowTidx:true,
	ifQuickLinkGroupExpaned:true,
    isthumbnail:false,

	mvcDef:{ // id: [className]
		1000: ["Wiki.Model.Page"],
		1001: ["Wiki.View.Page"],
		1002: ["Wiki.Controller"]
	},
	componentDef:{ //id: [modelClassName, viewClassName, idPrefix];
		0:["Item", "Item", "r"],
		1:["Section", "Section", ""],
		2:["Linked", "Linked", "kw"],
		3:["Comments", "Comments", "cmt"],
		4:["Attachment", "Attachment", "attach"],
		5:["Comment", "Comment", "cmt"],
		6:["Tag", "Tag", "tags"],
		8:["QuickLinks", "QuickLinks", "qlinks"],
		9:["KItems", "KItems", "ki"],
		10:["KItem", "KItem", "ki"],
		11:["KImage", "KImage", "img"],
		12:["", "KDesc","desc"],
		13:["SItems", "SItems", "si"],
		14:["SItem", "SItem", "si"],
		15:["Items", "Items", "itm"],
		16:["BackLog", "BackLog", "bklog"],
		17:["Document", "Document", "doc"],
		18:["Development", "Development", "dev"],
		90:["Unknown", "", "unknown"],
		91:["","Toc", "toc"]
	},	
	_getComponentDef:function(type){return (type in this.componentDef)?this.componentDef[type]:["Page", "Page", "wiki"];},
	getComponentModelClassName:function(type){return this._getComponentDef(type)[0];},
	getComponentViewClassName:function(type){return this._getComponentDef(type)[1];},
	getComponentPrefix:function(type){return this._getComponentDef(type)[2];},

	enable:{
		kw:true,
		cmt:true,
		attach:true,
		tags:true,
		topic:true,
		topicEditable:true,
		qlinks:true,
		itm:true,
		ki:true,
		bklog:false,
		dev:false,
		doc:true,
		ki_grapable:true,
		si:true,
		img:true,
		toc:true,
		desc:true,
		rich_summary:true,
		rich_comment:true
	},
	readonlysection:{
	    kw:false,
		cmt:false,
		attach:false,
		tags:false,
		topic:false,
		topicEditable:false,
		qlinks:false,
		itm:false,
		ki:false,
		bklog:false,
		dev:false,
		doc:false,
		ki_grapable:false,
		si:false,
		img:false,
		toc:false,
		desc:false,
		rich_summary:false,
		rich_comment:false
	},
	show:{
	    toc:false,
	    qlinks:false,
	    doc:true
	},
	appendix:{
		all:["ITEMS","LINKS", "COMMENTS", "ATTACHMENTS", "TAGS", "QUICKLINKS", "KITEMS", "KIMAGE", "TOC"], //refer to the Wiki.Object;
		// itemTypeId:[[Components before sections], [Components after sections], [Components not in wiki view]]
		101:[["TOC", "QUICKLINKS"], ["LINKS","DOCUMENT","ATTACHMENTS", "TAGS", "COMMENTS"],["KITEMS"]],
		102:[["DESCRIPTION"], ["ITEMS","KITEMS"],[]],
		103:[["KIMAGE"], ["COMMENTS"],["DESCRIPTION"]],
		104:[["DESCRIPTION"], ["ITEMS","KITEMS"],[]],
		105:[["DESCRIPTION"], ["KITEMS"],[]],
		106:[["TOC", "QUICKLINKS"], ["LINKS","DOCUMENT","ATTACHMENTS", "TAGS", "COMMENTS"],["KITEMS"]],
		107:[[], ["COMMENTS"],["KITEMS"]],
		108:[["TOC"], ["DOCUMENT","COMMENTS"],["DESCRIPTION"]],
		109:[["TOC", "QUICKLINKS"], ["DOCUMENT","ATTACHMENTS", "TAGS","BACKLOG","DEVELOPMENT","LINKS","COMMENTS"],["KITEMS"]],
		110:[["DESCRIPTION"], ["ITEMS","KITEMS"],[]]
	},
	allFolderActions:["actionNew","actionForward", "actionEdit", "actionDelete", "actionClone", "actionMove", "actionCustomize", "actionRefresh"],
	realFolderActions:["actionNew","actionForward", "actionEdit", "actionDelete", "actionClone", "actionMove","actionRefresh", "actionCustomize"],
	_init:function(){
		this.base = isEmpty(this.base)?"":(this.base.split("/").join("/") + "/");
		this.lang = isEmpty(this.lang)?"en":this.lang;
		this.lang_js = "lang/" + this.lang +".js";
		this.imgbase = this.base+"images/";
		this.editorbase = this.base + this.editor_wrapper;
		this.ndialogbase = this.base +this.mdialog_wrapper;

		var sizeStr = this.max_edit_size;
		this.maxSizeofEditing = sizeStr.substring(0, sizeStr.length-1) * (sizeStr.toLowerCase().charAt(sizeStr.length-1)=='k'?1:1000)*1000;
	}
};
Wiki.startView=function(xmlData,layout, userActionList){
	var controller = new Wiki.Controller(wiki_preReceive(xmlData),layout);
	IX.Utils.loop(["pre", "post", "reset", "update"], 0, function(acc, type){
		IX.Utils.loop((userActionList && type in userActionList)?userActionList[type]:[], 0, function(acc1, item){
			if(item!=null && item.length>1){controller.register(type, item[0], item[1], item[2]);}
		});
	});
	controller.show();
	window[Wiki.Config.name] = controller;
	IX.Utils.loop((userActionList && "loadview" in userActionList)?userActionList.loadview:[], 0, function(acc, item){
		if(item!=null && item.length>1){
			item[1]();
		}
	});
}

Wiki.start=function(pageDesc,layout, userActionList){
	var conf= this.Config;
	conf._init();

	IX.Net.loadCss(conf.base+ conf.view_css);
	var jsList = [];
	if (!("lang" in Wiki.I18N && Wiki.I18N.lang==conf.lang)){jsList.push(conf.lang_js);}
	if(!conf.isJsMassed){
		if (!("style" in Wiki.TView)){jsList.push(conf.tview_js);}
		jsList = jsList.concat(conf.wiki_js_list);
	} else {
		jsList.push(conf.massed_js);
	}

	IX.Net.loadJsFiles(IX.Utils.loop(jsList, [], function(acc, item){
		return IX.Utils.pushx(acc, conf.base+item);
	}), function(){Wiki.startView(pageDesc,layout, userActionList);});
};

function getController(){return (window[Wiki.Config.name])?window[Wiki.Config.name]:null;}

//Call-in functions:must implement in user module, Here are examples, don't uncomment them
//function wiki_getCurUid(){return _userID;}
//function wiki_getCurUname(){return _userName;}
//function wiki_post(xmlData){}
//function wiki_getUrlForAddingAppendix(op, ids){}
//function wiki_link2Knowledge(kwId){}
//function wiki_addAttachment(title, content){}
//function wiki_addQuickLinkGroup(){}
//function wiki_editQuickLinkGroup(gid){}
//function wiki_removeQuickLinkItem(gid, itemId){}
//function wiki_folder_action(action, param){}
//function wiki_post_config(configNameList){}


// Call-out functions:called in other modules.
// for ixEditor.htm special which is sub-componenet of wiki componenet
function wiki_get_editObject(id) {
	return getController().find(id);
}
function wiki_set_editor(editor) {
	editor._projectID = window._projectID;
	editor._kwprojectID = window._kwprojectID;	
	editor._userID = window.wiki_getCurUid();
	editor._viewType = window._viewType;
	editor._supportImageLink = window._supportImageLink;
	editor._sessionID=window.SessionID;
	editor._supportImageBase= window._supportImageBase;
	editor.config.screenCaptureID= window._screenCaptureID;
	editor.config.supportImageLink= window._supportImageLink;
	editor.config.supportImageBase= window._supportImageBase;
	
//	editor._wikiBookName = window._wikiBookName;
//	var fun = window.callWikiOnlineHelp;
//    editor._callWikiOnlineHelp = function(){
//        fun(window._wikiBookName,"HtmlEditor");
//    }
    editor._callWikiOnlineHelp = function(){
        this.callWikiOnlineHelp(this._wikiBookUrl,this._wikiBookName,"HtmlEditor");
    }.bind(window)
}
// FOR Topic related special:!!!!
function wiki_focusTopicRelatedSection(topicString){
	var controller= this.getController();
	if (!controller) {
		setTimeout(function(){wiki_focusTopicRelatedSection(topicString);}, 100);
		return;	
	}
	var fun = function(str){
		var spChars =  ["&gt;", "&lt;", "<", ">", "_", '"', "'"];
		return str.replace(/(\s+)|(\n)|(\r)|(\t)/g, "").strip().loopReplace(IX.Utils.loop(spChars, [], function(acc, item){
			acc.push([item, ""]);
			return acc;
		}));
	};
	var wItem = controller.find("root");	
	var sectTitle = fun(wItem.loopExtTopics("", function(acc, item){
		return (!acc && item[0] == topicString)?item[1]:acc;
	}));
	var sectId = isEmpty(sectTitle)?null:wItem.loopAll(null, function(acc, item) {
		return (!acc && fun(item.getTitle()).indexOf(sectTitle)>=0)?item.getId():acc;
	});
	if (!sectId) {sectId = "root";}
	controller.focus(sectId);
}

// for ixDialog.htm special which is sub-componenet of wiki componenet
function wiki_get_MDialogObject(did) {return getController().getDialog(did);}
function wiki_md_action(op, nodeId, did){getController().actionM(op, [nodeId, did]);}

// For user module which using wiki component
// PageDesc: xml string in SDEP
// layout: [[BodyContainerID, WikiBodyID],[DialogContainerID, WikiDialogID], [BodyContainerID, WikiPopupID]]
// userActionList :{pre:[[name, fun, obj], ...], post:[[name...]]}
// For fun in userActionList: fun=function(controller, actionID, param) {...}
function wiki_start(pageDesc, layout, userActionList){
	if(_wiki_url) {Wiki.Config.base = _wiki_url;}
	Wiki.start(pageDesc,layout, userActionList);
}
function wiki_resize(width){
	var fun = function(){
		var obj = getController();
		if (obj) {obj.resize(Math.max(width,500)-28);}
		else { setTimeout(fun, 10);}
	};
	fun();
}
function wiki_getWikiItem(){
	log('wiki_getWikiItem()');
	return getController().getSubmitData();
}
function wiki_registerHandler(type, name, fun, obj){
	log('wiki_registerHandler("'+type+'","'+name+ '", isFunction()='+isFunction(fun) +')');
	getController().register(type, name, fun, obj);
}
function wiki_callback_getAttachmentUploadUrl(url){
	log('wiki_callback_getAttachmentUploadUrl('+url +')');
	getController().addAttachmentWithUrl(url);
}
function wiki_callback_closeAttached(){
	getController().closeDialog("attach", "Attach,attach,");
}
// param: [idx, title, section, did]
function wiki_callback_editTopicInfo(param) {
	if (param[0]==-2){ // WikiBook 
		getController().updateKItemsTopicInfo(param);
	}else {
		getController().updateTopicInfo("edit", param);
	}
}
function wiki_callback_receive(xmlData){
	var xmlDoc = IX.Xml.parser(wiki_preReceive(xmlData));
	var node = xmlDoc.firstChild;
	var op= node.getAttribute("op");
	op=isEmpty(op)?"reset":op;
	getController()[op](xmlDoc.firstChild);
}
function wiki_callback_focus(sectionTidx){
	var ctl = getController();
	var node = ctl.find("root");
	if (sectionTidx.length!=0){
		node = node.loopAll(node, function(acc, item){
			return item.getTidxForce()==sectionTidx?item:acc;
		});
	}
	ctl.focus(node.getId());
}

// act:"new"/"forward"/"edit"/"delete": param = [idlist]
//	"clone"/"move": param = [folderid, itemid1,itemid2]
//	"customize": param = []
function wiki_callback_folder_action(act, param){
	var obj =getController();
	switch(act){
	case "new":
	case "forward":
	case "edit": obj.callServer("loaditem", param); break;
	case "clone": obj.callServer("cloneki", param); break;
	case "delete":obj.callServer("delki", param); break;
	case "move": obj.callServer("moveki", param); break;
	case "customize":obj.callServer("loadki"); break;
	case "refresh":
	default: break;
	};
}
// TO be tested:
function wiki_preReceive(wikiData){
	var splitFun=function(xml, tagN) {
		var sIdx = xml.indexOf("<" + tagN);
		if (sIdx<0){return [xml, 0, ""];}
		var eIdx = xml.indexOf("</" + tagN + ">");
		if(eIdx<0){
		    //alert("un-predictable data in wiki_preReceive:"+ xml); 
		    return [xml, 0, ""];
		}
		eIdx += (tagN.length)+3;
		return  [xml.substring(0, sIdx) +xml.substring(eIdx), sIdx, data.substring(sIdx, eIdx)];
	};
	var rmTagFun=function(xml, tagN){
		var sIdx= xml.indexOf(">");
		var eIdx = xml.lastIndexOf("<");
		return [xml.substring(0, sIdx+1) + xml.substring(eIdx), xml.substring(sIdx+1, eIdx)];
	};
	var getXmlRoot=function(str){
		var xmlDoc = IX.Xml.parser(str);
		return xmlDoc.firstChild;
	};
	var data = "" + wikiData;
	var  arr = splitFun(data, "wiki_data");
	if (arr[2].length==0){return arr[0];}
	var xmlData = arr[0];

	arr = rmTagFun(arr[2], "wiki_data");
	data = arr[1];
	// hack for XML writer in C#:
	if (data.substring(0,6)=="\r\n    ") {
		data = data.substring(6, data.length-4);
		//alert(data);
	}
	
	var idx = arr[0].indexOf("ifEncoded=");
	if (idx>0){
		var child = getXmlRoot(arr[0]);
		var flag = child.getAttribute("ifEncoded");
		if (flag && flag=='true'){data = data.loopReplace([['&lt;','<'],['&gt;','>'],['&quot;','"'],['&amp;','&']]);}
	}

	// converter ;
	var content=null;
	var sections = null;
	var cvt = Wiki.SDEP;
	if (data.indexOf ("</wiki>")<0){data = data.inPureTag("content").inTag("wiki");}
	var child = getXmlRoot(data);
	var node = cvt.__$first(child, "content");
	if (node) {content = node.cloneNode(true);}
	node = cvt.__$first(child, "sections");
	if (node) {sections = node.cloneNode(true);}
	
	// replace
	var xmlDoc = IX.Xml.parser(xmlData);
	var child = xmlDoc.firstChild;
	if (content){
		node = cvt.__$first(child, "content");
		if (node == null){child.appendChild(content);}
		else {child.replaceChild(content, node);}
	}
	if (sections) {
		node = cvt.__$first(child, "sections");
		if (node==null){child.appendChild(sections);}
		else{
			var nnode = node.cloneNode(false);
			var cnode = sections.firstChild;
			while(cnode){
				nnode.appendChild(cnode.cloneNode(true));
				cnode = cnode.nextSibling;
			}
			child.replaceChild(nnode, node);
		}
	}
	return IX.Xml.getXmlString(child);	
}
