﻿/// <reference path="file://C:/Source/KnowledgeBase/Portal/UI/PortalSite/Content/js/ext/ext-all.js" /> 
Ext.ns('$KB','$KB.User','kbReader','kbReader.Articles','PresentationAPI','$DOM');
Ext.Ajax.timeout = 60000;
$KB.LoginParams = [ { modal: false } ];
$KB.copyProps = function(A,B)
{
	if (Ext.isDefined(A))
	{
		for (var key in A)
		{
			if (typeof(key) != 'function')
			{
				B[key] = A[key];
			}
		}
	}
};
$KB.GetMatches = function(arr, matchFn)
{
	var res = [];
	for (var i=0; i < arr.length; i++)
	{
		if (matchFn(arr[i])) res.push(arr[i]);
	}
	return res;
};
$KB.RefreshSession = function()
{
	$KB.SessionHandler = new function()
	{
		var me = this;
		this.sessionStart = null;
		this.sessionLen = $KB.GlobalData.SessionTimeout * 60;
		this.warning = $KB.GlobalData.SessionTimeoutWarning * 60;
		this.randId = 'rId' + Math.floor(Math.random()*999999).toString();
		this.getSLeft = function()
		{
			var cv = Ext.util.Cookies.get("kbUser");
			if ($KB.isNull(cv)) return 999999;
			var exp = $KB.Extract(cv,this.randId + "=",null);
			exp = $KB.FixNull(exp,999999);
			return parseInt(exp);
		}
		this.Check = function()
		{	
			var sLeft = this.getSLeft();
			if(sLeft >= this.sessionLen)
			{
				this.sessionStart = new Date();
				var cv = Ext.util.Cookies.get("kbUser");
				if (!$KB.isNull(cv))
				{
					cv = cv.split("&");
					var newCV = "";
					var dl = "";
					var found = false;
					var userFound = false;
					for(var i=0;i<cv.length;i++)
					{
						if(cv[i].substr(0,this.randId.length) == this.randId)
						{
							newCV = newCV + dl + this.randId + "=0";
							found = true;
						}
						else if (cv[i].substr(0,7) == "UserId=")
						{
							newCV = newCV + dl + "UserId=" + ($KB.isNull($KB.GlobalData.User) ? "0" : $KB.GlobalData.User.UserID);
							userFound = true;
						}
						else newCV = newCV + dl + cv[i];
						dl = "&";
					}
					if(!found) newCV = newCV + dl + this.randId + "=0";
					if(!userFound) newCV = newCV + dl + "UserId=" + ($KB.isNull($KB.GlobalData.User) ? "0" : $KB.GlobalData.User.UserID);
					document.cookie = "kbUser=" + newCV + ";path=/";
				}
				this.SessionTimer = self.setTimeout("$KB.SessionHandler.Check();", 10000);
				return;
			}
			var now = new Date();
			var secsLeft = this.sessionLen - Math.ceil((now-this.sessionStart)/1000);
			if (secsLeft < 25)
			{
				this.ShowDialog(1);
			}
			else if (secsLeft<=this.warning)
			{
				if($KB.GlobalData.PortalProperties.KeepSessionAlive) DirectRequest.RefreshSession( function(res,resp) {});
				else this.ShowDialog(2);
			}
			this.SessionTimer = self.setTimeout("$KB.SessionHandler.Check();", 10000);
		}

		this.ShowDialog = function(n)
		{
			this.close();
			var ttl = '';
			var htm = '';
			var btn = '';
			var hnd = function(){};
			if(n == 1)
			{
				ttl = '<div class="SD_DialogTitle">' + $KB.LZ('TimeoutTitle', 'Session Timeout') + '</div>';
				htm = $KB.LZ('TimeoutMsg', 'Your session has timed out.  Please click "Return to Portal" to restart your session.');
				btn = $KB.LZ('TimeoutBtn', 'Return to Portal');
				hnd = function() 
				{	
					var url = window.location.href.split('#')[0];
					url = url + ( ( (url.indexOf('?') > -1) ? '&' : '?' ) + 'nc=t');
					window.location = url.replace('/kb/secure','');
				};
			}
			else
			{
				ttl = '<div class="SD_DialogTitle">' + $KB.LZ('TimeoutWarningTitle', 'Session Timeout Warning') + '</div>';
				htm = $KB.LZ('TimeoutWarningMsg', 'Your online session is about to timeout.  Please choose "Continue Session" to remain logged in.');
				btn = $KB.LZ('TimeoutWarningBtn', 'Continue Session');

				hnd = function() 
				{	
					DirectRequest.RefreshSession( function(res,resp) { if (res) me.close(); });
				};
			}
			this.button = new Ext.Button
			(
				{
					text: btn,
					handler: hnd
				 }
			);
			this.message = new Ext.Panel({ border: false, bodyStyle: 'background-color: transparent; padding:5px;padding-bottom:14px;', autoHeight: true, html: htm});
			this.dialog = new Ext.Window
			(
				{
					modal: true,
					resizeable: false,
					closable: false,
					height: 120,
					frame: false,
					padding: '5',
					layout: { type:'vbox', padding:'5', pack:'center', align:'center'},
					width: 250,
					border: false,
					cls: 'SD_Form',
					title: ttl,
					items:	[this.message, this.button]
				}
			);
			this.dialog.show();
		}		
		this.close = function()
		{
			if(!$KB.isNull(this.dialog))
			{
				this.dialog.close();
			}
		}
		this.Check();
	}
};
$KB.RemapArticleLinks = function(o)
{
	var links = o.getElementsByTagName('a');
	Ext.each
	(
		links,
		function (item)
		{
			var p = $KB.Extract(item.href.toLowerCase(), "articleRedirect.aspx", null);
			if (!$KB.isNull(p))
			{
				var pIn = $KB.Extract(p + "|", "?", "|").split('&');
				var pOut = {};
				for (var i =0; i < pIn.length; i++)
				{
					var pSplit = pIn[i].split("=");
					if (pSplit[0] == "aid") pSplit[0] = "ArticleId";
					pOut[pSplit[0]] = pSplit[1];
				}
				var L = p.split('|')[1];
				if (L.length > 0) pOut.anchor = L;
				item.href = "javascript: $KB.open(" + Ext.util.JSON.encode(pOut) + ");"
			}
		}
	);
};
$KB.buildParams = function(data, keys, fnCleanUp)
{
	var s = [];
	var fn = Ext.isDefined(fnCleanUp) ? fnCleanUp : function (key, v) { return v };
	function b(key)
	{
		var	v = $KB.FixNullorEmpty(data[key],"");
		if (v != "" && typeof(v) != 'function' )
		{
			var isN = $KB.isNumeric(v);
			var q = (isN ?  '' : '\'');
			s.push( key.replace(/ID$/,'Id') + ':' + q + (isN ? fn(key, v) : $KB.escStr(fn(key,v)) ) + q);
		}
	}
	if ($KB.FixNullorEmpty(keys, null) == null)
	{
		for (var key in data) { b(key); }
	}
	else
	{
		for (var i=0; i < keys.length; i++) { b(keys[i]); }
	}
	return '{' + s.join(',') + '}';
};
$KB.buildURL = function(root, keys, params)
{
	var q = [];
	for (var i=0; i < keys.length; i++)
	{
		var key = keys[i];
		var v = $KB.readByName(params, key)
		if (v != null)
		{
			q.push(key + "=" + $KB.replaceQuotes(v));
		}
	}
	return (q.length == 0) ? root : (root + "?" + q.join("&"));
};
$KB.getCmp = function (objOrId)
{
	if (Ext.isObject(objOrId)) return objOrId;
	return Ext.getCmp(objOrId);
};
$KB.setDisabled = function (idList, bDisable)
{
	for (var i = 0; i < idList.length; i++)
	{
		var c = $KB.getCmp(idList[i]);
		if (c != null)
		{
			switch (c.getXType())
			{
				case "kbpagingtoolbar":
					$KB.setDisabled([c.first, c.prev, c.next, c.last, c.refresh], bDisable);
					c.doLayout();
					break;
				default:
					c.setDisabled(bDisable);
					c.suspendEvents(bDisable);
					break;
			}
		}
	}
};
$KB.setVisible = function(idList, bVisible)
{
	for (var i=0; i < idList.length; i++)
	{
		var c = Ext.getCmp(idList[i])
		if (c != null)
		{
			c.setVisible(bVisible);
			c.ownerCt.doLayout();
			var o = c.getEl();
			if (o != null)
			{
				o.dom.style.zIndex = 1000;
			}
		}
	}
};
$KB.Opposite = function(val, s1, s2)
{
	return (val == s1 ? s2 : s1);
};
$KB.RemoveElements = function(o, from, to)
{
	var rest = o.slice((to || from) + 1 || o.length);
	o.length = from < 0 ? o.length + from : from;
	o.push.apply(o, rest);
};
$KB.Reverse = function(x)
{
	y = [];
	for (var i=x.length-1; i > -1; i--)
	{
		y.push(x[i]);
	}
	return y;
};
$KB.PadIfNotNull = function (L, x, R)
{
	return (x != null && x.length > 0) ? L + x + $KB.FixNull(R,"") : "";
};
$KB.ArrayContains = function(arr, v)
{
	if (arr.length == 0) return false;
	for (var i=0; i< arr.length; i++)
	{
		if (arr[i] == v) return true;
	}
	return false;
}
$KB.MapRblData = function (data, labelField, valueField, name)
{
	var r = [];
	for (var i =0; i < data.length; i++)
	{
		r.push({ boxLabel: data[i][labelField], value: data[i][labelField], name: name})
	}
	return r;
};
$KB.UniqueId = new function()
{
	this.Ids = [];
	this.get = function(stub)
	{
		if (!Ext.isDefined(this.Ids[stub]))
		{
			this.Ids[stub] = -1;
		}
		this.Ids[stub]++;
		return stub + "_" + this.Ids[stub];
	}
}
$KB.LoadedArticleNames = {};
$KB.ShowArticle = function(ns, addFunc, showFunc, params)
{
	var ct = $KB.FixNull(params.ArticleContentType,$KB.FixNull(params.ContentType,'')).toLowerCase();
	if( (ct.substr(0,11) == 'application') && (ct.substr(0,15) != 'application/pdf') )
	{
		params.RunScript = "0";
		var dinfo = $KB.GetOfficeDocOpenInfo(params);
		window.open(dinfo.URL,dinfo.WindowId,dinfo.Parameters);
	}
	var urlAdd = '';
	if( (ct.substr(0,11) == 'application') && (ct.substr(0,15) == 'application/pdf') )
	{
		var ttl = params.Title;
		var goodCount = 0.0;
		for(var i=0;i<ttl.length;i++)
		{
			var code = ttl.charCodeAt(i);
			if(ttl[i] != ' ' && ttl[i] != '_' && ttl[i] != '-')
			{
				if(!( (code > 47 && code < 58) || (code > 64 && code < 91) || (code > 96 && code < 123) ))
				{
					ttl = ttl.split(ttl[i]).join('_');
				}
				else goodCount++;
			}
		}
		
		urlAdd = '/' + ((goodCount/ttl.length < 0.6) ? 'My Article' : ttl);
	}
	var autoCreateCrumb = $KB.FixNullorEmpty(params.AutoCreateCrumb,true);
	var articleLinkFn = $KB.FixNull(params.ArticleLinkFn,null);
	var isSnapIn = $KB.FixNull(params.IsSnapIn,false);
	params.cid = $KB.GlobalData.PortalProperties.PortalId;
	if (params.ShowToolbar)
	{
		params.ToolbarId = $KB.UniqueId.get($KB.getCurrentTabName());
	}
	var keys = ["articleId", "DocId", "Source", "anchor", "DB", "dbQuery", "SearchString","cid","SearchId","RunScript"];
	var dataParams = $KB.FixParams(params, keys);
	dataParams.Source = $KB.FixNullorEmpty(dataParams.Source,'article');
	var showArtInfo = ['article','faq'].indexOf(dataParams.Source.toLowerCase()) > -1;
	if (showArtInfo) showArtInfo = $KB.GlobalData.PortalArticleInfo.ArticleInfo;
	var src = $KB.buildURL('/kb/article' + urlAdd, keys, dataParams ).toLowerCase();
	var ht = 0;
	if($KB.FixNullorEmpty(params.ShowToolbar,false)) ht = 25;
	var anchor = '';
	if(!$KB.isNull(params.anchor)) anchor = '#' + params.anchor;
	ns.ArticleIFrame = new Ext.Container(
	{
		region:'center',
		style:'padding:2px;background-color:#ffffff;',
		autoEl:
		{
			tag: 'iframe',
			src: src + "&islink=true" + anchor,
			align: 'left',
			scrolling: 'auto',
			marginwidth:'8px',
			marginheight:'8px',
			hspace:'10px',
			frameborder: '0'
		}
	});
	var randId = $KB.UniqueId.get($KB.getCurrentTabName() + 'articlePanel');
	ns.ArticleInfoPanel = new Ext.Panel(
	{
		autoScroll:true,
		columnWidth:1
	})
	var sepContainer = new Ext.Panel
	(
		{
			region:'east',
			width: (showArtInfo ? 200 : 0),
			hidden: !showArtInfo,
			hideBorders:true,
			border:false,
			id:randId,
			layout:'column',
			items:
			[
				{
					xtype:'box',
					width:8,
					autoEl:
					{
						tag:'div',
						html:''
					}
				},
				ns.ArticleInfoPanel
			],
			listeners:
			{
				resize:function(comp,aw,ah,rw,rh)
				{
					if(rh != null)
					{
						var cmp = comp.get(0);
						cmp.setSize(8,rh);
						ns.ArticleInfoPanel.setHeight(rh);
						var dom = cmp.getEl();
						var newPos = Math.round(rh/2) - 15;
						if(newPos<0) newPos=0;
						if(typeof(dom) == 'undefined')
						{
							cmp.autoEl.html = '<div onclick="var cmp=Ext.getCmp(\'' + randId + '\');var wdth = cmp.getWidth();cmp.setWidth((wdth==8) ? 200 : 8);cmp.ownerCt.doLayout(false,true);" onmouseover="this.style.backgroundColor = \'#dadada\';" onmouseout="this.style.backgroundColor = \'#ffffff\';" style="height:' + rh.toString() + 'px;cursor:pointer;border-left:1px solid #bbbbbb;background-color:#ffffff;padding-top:' + newPos.toString() + 'px;"><div class="icon_separator"></div></div>';
						}
						else
						{
							cmp.el.dom.innerHTML = '<div onclick="var cmp=Ext.getCmp(\'' + randId + '\');var wdth = cmp.getWidth();cmp.setWidth((wdth==8) ? 200 : 8);cmp.ownerCt.doLayout(false,true);" onmouseover="this.style.backgroundColor = \'#dadada\';" onmouseout="this.style.backgroundColor = \'#ffffff\';" style="height:' + rh.toString() + 'px;cursor:pointer;border-left:1px solid #bbbbbb;background-color:#ffffff;padding-top:' + newPos.toString() + 'px;"><div class="icon_separator"></div></div>';
						}
					}
				}
			}
		}
	);
	ns.ArticleView = new Ext.Container
	(
		{
			anchor: '0 0',
			layout: 'border',
			items:
			[
				{
					xtype:'container',
					region: 'north',
					cls: 'SD_ArticleToolbar',
					hidden: true
				},{
					xtype:'panel',
					layout:'border',
					bodyStyle:'background-color:transparent;',
					hideBorders:true,
					border:false,
					region: 'center',
					anchor: '-3 -' + ht.toString(),
					preventBodyReset:true,
					items:
					[
						ns.ArticleIFrame,
						sepContainer
					]
				}
			]
		}
	);
	var backFn = $KB.FixNull(params.backFn,function(){});
	var fromBack = $KB.FixNull(params.fromBack,false);
	if($KB.FixNullorEmpty(params.ShowToolbar,false))
	{
		ns.articleBar = new $KB.ArticleToolbar
		(
			{
				Id:params.ToolbarId,
				ArticleId:dataParams.articleId,
				Source:params.Source,
				Title:params.Title,
				Component:ns.ArticleView.get(1),
				IsFrame:true,
				DB:dataParams.DB,
				Query:dataParams.dbQuery,
				LastArticlesParams:params.lastArticlesParams,
				InfoPanel: showArtInfo ? ns.ArticleInfoPanel : null,
				ArticleLinkFn: articleLinkFn,
				IsSnapIn: isSnapIn,
				OnLoad:function(articleBar)
				{
					if(params.Source.toLowerCase() == 'article') $KB.LoadedArticleNames[dataParams.articleId] = articleBar.title;
					if(articleBar.IsEmpty)
					{
						ns.ArticleView.get(0).hide();
					}
					else
					{
						if($KB.FixNullorEmpty(params.ShowToolbar, false))
						{
							ns.ArticleView.get(0).add(articleBar.Control);
							ns.ArticleView.get(0).doLayout(false,true);
							ns.ArticleView.get(0).show();
						}
					}
					ns.ArticleView.doLayout(false,true);
					addFunc(ns.ArticleView);
					showFunc(ns.ArticleView);
					if(autoCreateCrumb) ns.BreadCrumb.ShowTempCrumb(articleBar.title,params,backFn,fromBack);
				}
			}
		);
	}
	else
	{
		if(params.Source.toLowerCase() == 'article') $KB.LoadedArticleNames[dataParams.articleId] = params.Title;
		addFunc(ns.ArticleView);
		showFunc(ns.ArticleView);
		if(autoCreateCrumb) ns.BreadCrumb.ShowTempCrumb(params.Title,params,backFn,fromBack);
	}
};
$KB.addTabContent = function(TabId, item, doLayout)
{
	var c = Ext.getCmp(TabId + "Contents");
	c.add(item);
	if ( $KB.FixNullorEmpty(doLayout, true) ) c.doLayout();
};
$KB.addContent = function(Id, item, doLayout)
{
	var c = Ext.getCmp(Id);
	c.add(item);
	if ( $KB.FixNullorEmpty(doLayout, true) ) c.doLayout();
};
$KB.removeContent = function(Id, item, destroy)
{
	var c = Ext.getCmp(Id);
	if(c.items.contains(item)) c.remove(item,destroy);
};
$KB.CopyParam = function (ToCopy, CopyTo, f)
{
	if (Ext.isDefined(f) && Ext.isDefined(ToCopy[f]) && ToCopy[f] != null) CopyTo[f] = ToCopy[f];
};
$KB.OpenViewScript = function(view, ViewObj)
{
	if (Ext.isDefined(ViewObj))
	{
		ViewObj();
	}
	else
	{
		var fms = new Ext.Panel({ autoLoad: view, hidden:true } );
		$KB.ScriptContainer.add(fms);
		$KB.ScriptContainer.doLayout();
	}
};
$KB.EnableDisable = function (o, bEnable) { if (Ext.isDefined(o)) { if (bEnable) o.enable(); else o.disable(); }};
$KB.FixParams = function(ParamsToFix, paramList, idPad)
{
	idPad = $KB.FixNullorEmpty(idPad, "")
	var Params = [];
	if (ParamsToFix == null) ParamsToFix = [];
	for (var i=0; i < paramList.length; i++)
	{
		var n = paramList[i]
		Params[n] = $KB.FixNullorEmpty($KB.readByName(ParamsToFix, n, idPad));
	}
	return Params;
};
$KB.readByName = function (data, name, idPad)
{
	var t = [name];
	idPad = $KB.FixNullorEmpty(idPad, "");
	if (idPad != "" && $KB.right(name, 2) == idPad) t.push( name.substr(0, name.length-idPad.length) );
	for (var i=0; i< t.length; i++)
	{
		var n = t[i]
		if (Ext.isDefined(data[n])) return data[n];
		var xName = n.toLowerCase();
		for (var xDataName in data)
		{
			if (xDataName.toLowerCase() == xName) return data[xDataName];
		}
	}
	return null;
};
$KB.replaceQuotes = function (x)
{
	if (x == null || $KB.isNumeric(x)) return x;
	var z= x.split("'").join("&#8217;").split("\"").join("&#34;");
	return z;
};
$KB.replaceSpaces = function (x)
{
	if (x == null) return x;
	x = new String(x);
	var z= x.split(" ").join("&nbsp;");
	return z;
};
$KB.replaceSlashes = function (x)
{
      if (x == null) return x;
      x = new String(x);
      var z= x.split("\\").join("\\\\");
      return z;
};
$KB.LastSplitItem = function(x, sep)
{
	var s = x.split(sep);
	return s[s.length-1];
};
$KB.replaceAll = function (x)
{
	if (x == null) return null;
	return $KB.replaceQuotes($KB.replaceSpaces(x));
};
$KB.escapeLiteral = function (x)
{
	if (x == null) return null;
	return $KB.replaceQuotes($KB.replaceSpaces($KB.replaceSlashes(x)));
};
$KB.escapeLiteral2 = function (x)
{
	if (x == null) return null;
	return $KB.replaceQuotes($KB.replaceSlashes(x));
};
$KB.escStr = function (x)
{
	if (x == null) return null;
	return $KB.replaceQuotes($KB.replaceSlashes(x)).split("\r").join("\\r").split("\n").join("\\n");
};
$KB.escTag = function (x)
{
	if (x == null) return null;
	return $KB.replaceQuotes($KB.replaceSlashes(x));
};
$KB.replaceDoubleQuotesForInnerJS = function (x)
{
	if (x == null || $KB.isNumeric(x)) return x;
	var z= x.split("'").join("&#8217;").split('\\').join('\\\\').split('"').join('\\"');
	return z;
};
$KB.replaceAllSpecial = function (x)
{
	if (x == null) return null;
	return $KB.replaceDoubleQuotes($KB.replaceSpaces(x));
};
$KB.isNumeric = function (o)
{
	var t = typeof(o);
	if (t == "number") return true;
	if (t == "undefined" || o == null || o == "") return false;
	var bCont = true;
	var iDec = 0;
	var szNumbers = "0123456789";
	for (var i=0; i<o.length && bCont; i++)
	{
		var szX = o.substr(i,1);
		if (szX == ".")
		{
			iDec++;
			bCont = (iDec < 2);
		}
		else
		{
			bCont = szNumbers.indexOf(szX) > -1;
		}
	}
	return bCont;
}
$KB.FixNullorEmpty = function (v, valueIfNull)
{
	return $KB.isNullOrEmpty(v) ? (Ext.isDefined(valueIfNull) ? valueIfNull : null) : v;
};
$KB.isNullOrEmpty = function(v)
{
	return ( $KB.isNull(v) || ((typeof(v) == "string") && (v == "")) );
};
$KB.isNull = function(v)
{
	return(!Ext.isDefined(v) || v == null);
};
$KB.FixNull = function (v, valueIfNull)
{
	return $KB.isNull(v) ? (Ext.isDefined(valueIfNull) ? valueIfNull : null) : v;
};
$KB.IfNotNull = function (v, funct)
{
	if (!$KB.isNull(v)) funct();
};
$KB.ExecIf = function (fn, params){ var isDef = Ext.isDefined(fn); if (isDef) {if (Ext.isDefined(params)) { fn(params); } else { fn(); } } return isDef };
$KB.DisplaySingle = function()
{
	this.LastItem = null;
	this.hideLast = function()
	{
		var hd = false;
		if($KB.isNull(this.LastItem.el)) hd = true;
		else if(!$KB.isNull(this.LastItem.el.dom)) hd = true;
		if(hd) this.LastItem.hide();
	}
	this.show = function(item, DeleteLastItem)
	{
		if (this.LastItem != null)
		{
			if ($KB.FixNull(DeleteLastItem, false))
			{
				this.LastItem.ownerCt.remove(this.LastItem);
			}
			else
			{
				this.hideLast();
			}
		}
		this.LastItem = item;
		item.show();
	}
	this.displayNone = function()
	{
		if (this.LastItem != null) this.hideLast();
	}
};
$KB.GetNextId = function()
{
	$KB.objNextId = $KB.FixNull($KB.objNextId,0) + 1;
	return $KB.objNextId;
}
//Get an object with error checking
var $nf = function () {};
function $g(objOrId, bIgnoreNull)
{
	if (typeof(bIgnoreNull) == "undefined") bIgnoreNull = false;
	var obj = (typeof(objOrId) == "object" ? objOrId : document.getElementById(objOrId) );
	if (obj == null && !bIgnoreNull)
	{
		$KB.alert ('Id has no Object [' + objOrId + ']');
	}
	return obj;
}
$KB.Stack = [];
$KB.WhenExists = function()
{
	this.Init = true;
	this.Exec = function(testObject, funct, test)
	{
		if (this.Init)
		{
			this.funct = funct;
			this.testObject = testObject;
			this.timer = null;
			this.tries = 0;
			this.tf =(Ext.isDefined(test)) ? test : function (to) { this.objectResult = $g(to, true); return this.objectResult !=null; };
			this.Init = false;
			$KB.Stack[this.testObject] = this;
		}
		if (this.tf(this.testObject))
		{
			if (this.timer != null) self.clearTimeout(this.timer);
			this.funct(this.objectResult);
			$KB.Stack[this.testObject] == null;
		}
		else
		{
			this.tries++;
			if (this.tries < 22)
			{
				//the loop gradually adds more time as tries increase.
				this.timer = self.setTimeout("$KB.Stack." + this.testObject + ".Exec();", 20 + this.tries * 20);
			}
			else
			{
				$KB.alert('Could not find: ' + this.testObject)
			}
		}
	};
}
$KB.clearTimeout = function(t)
{
	if ( (!Ext.isDefined(t)) || (t == null)) return;
	self.clearTimeout(t);
	t = null;
};
$KB.alert = function(msg, title, fn, width)
{
	function GetDefaultTitle()
	{
		try
		{
			return $KB.GlobalData.PortalProperties.Title;
		}
		catch(ex)
		{
			return "Message";
		}
	}
	var f = $KB.FixNullorEmpty(fn,$nf);
	var win = new Ext.Window
	(
		{
			renderTo: Ext.getBody(),
			closable: true,
			title: Ext.isDefined(title) ? title : GetDefaultTitle(),
			modal: true,
			width: $KB.FixNull(width,300),
			autoHeight:true,
			cls:'SD_ErrMsgBox',
			items:
			[
				{
					xtype:'form',
					bodyStyle:'background-color:transparent; padding:10px; ',
					hideBorders:true,
					border:false,
					defaults:
					{
						labelSeparator:'',
						width: 200
					},
					items: 
					{
						xtype:'box',
						autoEl:{tag:'div',html:msg},
						style:'padding:10px;'
					},
					buttons:
					[
						{
							text:$KB.LZ('OK', 'OK'), handler:function() {win.close(); f();}
						}
					]
				}
			]
		}
	).show();
};
$KB.BuildClick = function(fN)
{
	return String.format(' onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);" onclick="{0}"', fN);
};
$KB.BuildMouseOver = function()
{
	return ' onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);"';
}
function setValue(obj, defaultValue)
{
	return (typeof(obj) != "undefined") ? obj : defaultValue;
};
$KB.getVisualCenter = function(width, height, oBG)
{
	var pos = [];
	oBG = Ext.isDefined(oBG) ? oBG : Ext.getBody();
	pos.x = Math.max(Math.floor(0.4 * oBG.getWidth()  - (width /2)), 20);
	pos.y = Math.max(Math.floor(0.4 * oBG.getHeight() - (height/2)), 20);
	return pos;
}
$KB.InsertLink = function(UniqueId, button, LinkType)
{
	var width=400; var height=350;
	var isArticle = LinkType == "Article";
	if (isArticle) 
	{
		width=330;
		height=130;
	}
    var pos = $KB.getVisualCenter(width, height);
	var CE= $KB.EditorStack[UniqueId].CuteEdit;
	var editwin = CE.GetWindow();
	var editdoc = CE.GetDocument();
	
	var LinkId = null;
	var LinkText;
	
	var LinkText = "";
	var SelectedText = getSelectedHTML();
	
	function getSelectedHTML()
	{
		var rng=null, html=null;
		if(document.selection && document.selection.createRange)
		{
			rng = editdoc.selection.createRange();
			html = $KB.FixNull(rng.htmlText,"");
		}
		else if(window.getSelection)
		{
			rng=editwin.getSelection();
			if(rng.rangeCount> 0 && window.XMLSerializer)
			{
				rng=rng.getRangeAt(0);
				html= new XMLSerializer().serializeToString(rng.cloneContents());
			}
		}
		return html;
	}
	if (Ext.getCmp('LinkForm') != null) return;
	function Close()
	{
		LinkForm.close();
	}
	function EnableSelect()
	{
		$KB.setDisabled(['link_btnSelect'], LinkId == null)
	}
	function DisableSelect()
	{
		$KB.setDisabled(['link_btnSelect'],true)
	}
	var items = 
	[
		{
            layout: { type:'vbox', padding:'5', align:'left'},
			defaults: { margins:'0 0 5 0', xtype:'button', width: 65, padding:'0' },
			region: 'east',
			width: 80,
			cls: 'SD_Form',
			bodyStyle: 'background-color:transparent',
			margins: '14',
			layoutConfig:
			{
				pack:'end',
				align:'left',
				padding:'0'
			},
			items:
			[
				{
					text:$KB.LZ('Select', 'Select'),
					id: 'link_btnSelect',
					disabled: true,
					handler: function()
					{
						var url = '<a href=javascript:$KB.open({' + LinkId + '})">' + 
						$KB.FixNullorEmpty($KB.FixNullorEmpty(SelectedText, LinkText), LinkType + " Link") + '</a>';
						CE.ExecCommand("PasteHTML", false, url);
						Close();
					}
				},{
					text:$KB.LZ('Cancel', 'Cancel'),
					handler:Close
				}
			]
		}
	];
	if (isArticle)
	{
		items.push
		(
			{
				layout: 'form',
				id: 'isArticleform',
				xtype: 'panel',
				labelAlign: 'top',
				autoHeight: true,
				region: 'center',
				margins:'0 10',
				bodyStyle: 'background-color:transparent',
				items:
				[
					{
						labelSeparator:'',
						fieldLabel: $KB.LZ('ArticleId', 'Article Id'),
						xtype: 'textfield',
						width: 200,
						id: 'insertarticlelinkfield',
						enableKeyEvents: true,
						maskRe: /[0-9]/,
						listeners:
						{
							keyup: function (tf, e)
							{	
								var v = tf.getValue();
								LinkId = (v.length > 3) ?  "articleId:" + v : null;
								if (v.length > 3)
								{
									DirectRequest.ArticleExists(v,function(res,resp)
									{
										if( (resp.status == true) && (res.Exists == true) )
										{
											EnableSelect();
											articlenametext.value = res.Title;
										} else
										{
											DisableSelect();
											articlenametext.value = " ";
										}
									});
								} else
								{
									DisableSelect();
									articlenametext.value = " ";
								}
							},
							keydown: function (tf, e)
							{	
								DisableSelect();
							}							
						}
					},
					{
						xtype: 'textfield',
						labelSeparator: '',
						id: 'articlenametext',
						style: { color: 'black' },
						disabled: true,
						width: 200
					}
					
				]
			}
		)
	}
	else
	{
		items.push
		(
			new Ext.tree.TreePanel
			(
				{
					region: 'center',
					margins: '6',
					loader: new Ext.tree.TreeLoader
					(
						{
							directFn: DirectRequest['GetLinkTree_' + LinkType]
						}
					),
					height: 350,
					rootVisible: false,
					autoScroll: true,
					anchor: '1 1',
					animate: true,
					border: false,
					root:{text: 'root', id: 'root', leaf: false, expanded: true },
					listeners:
					{
						click: function(n)
						{
							LinkId = null;
							var idSplit = n.id.split("_");
							switch (idSplit[0])
							{
								case "forum": case "thread":
									LinkId = idSplit[0] + "Id:" + idSplit[1];
									break;
							}
							if (LinkId != null)
							{
								n.expand();
								LinkText = "";
								while (n.text != "root")
								{
									LinkText = n.text + $KB.PadIfNotNull("&ndash;", LinkText, "");
									n = n.parentNode;
								}
							}
							EnableSelect();
						}
					}
				}
			)
		);
	}
	
	var LinkForm = new Ext.Window
    (
		{
			id: 'LinkForm',
			width: width,
			height: height,
			title: '<div class="SD_DialogTitle">Insert ' + LinkType + ' Link</div>',
			x: pos.x,
			y: pos.y,
			frame: false,
			closable: false,
			cls: 'SD_Form',
			modal: true,
			layout: 'border',
			padding: '12',
			bodyStyle: 'background-color: transparent; padding: 5px 0px 0px 5px',
			border: false,
			defaults: { border: false },
			items: items
		}
	)
	LinkForm.show();
};
$KB.SearchClicked = function(searchText)
{
	if(searchText == '') return;
	var params =
	{
		"SearchText": searchText
	}
	switch($KB.getCurrentTabId())
	{
		case 'homeTab': kbHome.SearchClicked(params); break;
		case 'wikiTab': kbWiki.SearchClicked(params); break;
		case 'forumTab': kbForum.SearchClicked(params); break;
		case 'categoryTab': kbCategory.SearchClicked(params); break;
	}
};
$KB.ShowAdvancedSearch = function()
{
	switch($KB.getCurrentTabId())
	{
		case 'homeTab': kbHome.ShowAdvancedSearch(); break;
	}
};
$KB.HideAdvancedSearch =function()
{
	switch($KB.getCurrentTabId())
	{
		case 'homeTab': kbHome.HideAdvancedSearch(); break;
	}
};
$KB.SearchControl = function(params)
{
	this.id = params.Id;
	this.width = $KB.FixNullorEmpty(params.Width, 0);
	$KB[this.id + 'searchClicked'] = $KB.FixNullorEmpty(params.SearchClicked,null);
	$KB[this.id + 'this'] = this;
	this.dc = params.Parent;
	this.emptyText = $KB.FixNullorEmpty(params.EmptyText,'');
	this.isDefaultText = true;
	this.onChange = $KB.FixNullorEmpty(params.OnChange,null);
	var asugg = $KB.FixNull(params.AutoSuggestSource,'none');
	asugg = ( (asugg != 'none') && $KB.GlobalData.PortalProperties.CommClues ) ? asugg : 'none';
	this.autoSuggestSource = asugg;
	this.isDisabled = false;
	this.init = function()
	{
		var thisObject = this;
		this.tbDef = 
		{
			anchor: '-3 -1',
			id:this.id+'tb', emptyText: this.emptyText,
			style:'background-color:transparent; background-image: none; border:0;',
			value: $KB.FixNull(params.Text, ''),
			listeners:
			{
				keydown:function(tf,e)
				{
					if(e.keyCode == 13)
					{
						var nv = Ext.get(thisObject.id + 'tb').dom.value;
						$KB[thisObject.id + 'searchClicked'](nv);
					}
				},
				keyup:function(tf,e)
				{
					if(thisObject.onChange != null)
					{
						var nv = Ext.get(thisObject.id + 'tb').dom.value;
						thisObject.onChange(nv);
					}
					else {}
				}
			}
		};
		if(this.autoSuggestSource == 'none')
		{
			this.tbDef.xtype = 'textfield';
			this.tbDef.enableKeyEvents = true;
		}
		else
		{
			this.tbDef.xtype = 'kbautosuggesttextbox';
			this.tbDef.outFunction = DirectRequest.GetCommunityClues;
			this.tbDef.clickFunction = function()
			{
				var nv = Ext.get(thisObject.id + 'tb').dom.value;
				$KB[thisObject.id + 'searchClicked'](nv);
			};
			this.tbDef.popupCls = 'SD_AutoSuggestTBPopup';
			this.tbDef.popupHighlightCls = 'SD_AutoSuggestItemHighlight';
			this.tbDef.popupItemCls = 'SD_AutoSuggestItem';
		}
		this.contdef =
		{
			xtype: 'panel',
			layout: 'column',
			cls:'SD_SearchBoxCtrl',
			columns: 2,
			height: 27,
			items:
			[
				{
					xtype: 'panel',
					layout: 'anchor',
					border: false,
					bodyStyle: 'background-color: transparent',
					columnWidth: 1,
					height: 24,
					items:
					[
						this.tbDef
					]
				},{
					xtype:'box',
					width: 24,
					padding: '0',
					margins: '0',
					autoEl:
					{
						tag:'div',
						style: 'padding:0px;margin:1px 0px 0px 0px; width:24px; height: 20px',
						children:
						[
							{
								tag:'img',
								src:'/content/images/icons/search.gif',
								alt:$KB.LZ('Search', 'Search'),
								onmouseover: 'Ext.ux.btnMO(this, true)',
								onmouseout: 'Ext.ux.btnMO(this, false)',
								onclick:'var sc = $KB[\'' + this.id + 'this\']; if(sc.isDisabled) return; var searchText = Ext.get(\'' + this.id + 'tb\').dom.value; $KB.' + this.id + 'searchClicked(searchText);'
							}
						]
					}
				}
			]
		};
		if(this.width == 0) this.contdef.anchor = '-10';
		else this.contdef.width = this.width;
		this.cont = new Ext.Container(this.contdef);
		this.dc.add(this.cont);
	}
	//public methods
	this.GetValue = function()
	{
		var v = Ext.get(this.id+'tb').dom.value;
		if(v == this.emptyText) return '';
		else return v;
	}
	this.SetText = function(val)
	{
		var v = Ext.get(this.id+'tb');
		if(!$KB.isNull(v.setValue))	v.setValue(val);
		else v.dom.value = val;
	}
	this.SetDisabled = function(v)
	{
		this.isDisabled = v;
		return Ext.get(this.id+'tb').dom.disabled=v;
	}
	this.Focus = function()
	{
		var v = Ext.getCmp(this.id+'tb');
		v.focus(false,true);
	}
	this.DestroyObjects = function()
	{
		this.dc.remove(this.cont, true);
		$KB[this.id + 'searchClicked'] = null;
	}
	this.init();
};
$KB.Search = function(params)
{
	if(!Ext.isDefined(params.renderTo)) return;
	var dsp = 'display: none;';
	if(typeof(params.showAdvanced) != 'undefined')
	{
		if(params.showAdvanced) dsp = 'visibility: visible;';
	}
	var emptyText = $KB.FixNull(params.EmptyText, $KB.LZ('Search_All_Content', 'Search All Content...'));
	
	var items = [];
	if ($KB.Settings.PortalStyle.SearchLogo != 'none')
	{
		items.push 
		(
			{
				xtype: 'box',
				cls:'FL',
				autoEl:
				{
					tag:'div',
					children: [{tag:'img', src: $KB.Settings.PortalStyle.SearchLogo }]
				}
			}
		);
	}
	items.push ({ xtype:'container', cls:'FL', id: 'SearchMainTB' });
	items.push 
	(
		{
			xtype:'box',
			cls:'FL',
			autoEl:
			{
				id:'AdvancedSearchText',
				tag:'div', style:'' + dsp + ' margin:8px 0px 0px 7px; height: 22px; cursor: pointer; background-color:transparent; ', html: $KB.LZ('Home_Adv_Search', 'Advanced Search'),
				onclick: '$KB.ShowAdvancedSearch();',
				onselectstart: "return false;", ondragstart: "return false;"
			}
		}
	);
	
	$KB.SearchUI =
	{
		xtype: 'container',
		layout: 'anchor',
		id:'SearchMainContainer',
		advancedIsHidden: true,
		cls:'SD_TabHeader',
		anchor: '0 0',
		items: items
	}
	var autoSuggSrc = 'none';
	if(params.renderTo == 'homeTabSearch') autoSuggSrc = 'home';
	var we = new $KB.WhenExists();
	we.Exec
	(
		params.renderTo,
		function(o)
		{
			if(typeof(Ext.getCmp($KB.SearchUI.id)) != 'undefined')
			{
				var parent = Ext.getCmp($KB.SearchUI.id).ownerCt;
				parent.remove($KB.SearchUI.id);
			}
			Ext.getCmp(params.renderTo).add($KB.SearchUI);
			var searchBox = new $KB.SearchControl
			(
				{
					Id:'KBMainSearch',
					Width:400,
					Parent:Ext.getCmp('SearchMainTB'),
					SearchClicked: function(text)
					{
						if(text != emptyText)
						{
							$KB.SearchClicked(text);
						}
					},
					EmptyText:emptyText,
					AutoSuggestSource:autoSuggSrc
				}
			);
			$KB.VisibleSearchBox = searchBox;
			Ext.getCmp(params.renderTo).doLayout(false, true);
			if(typeof(params.targetTab) != 'undefined')
			{
				params.targetTab.doLayout(false, true);
			}
		}
	);
};
$KB.GetVisibleSearchBox = function()
{
	return $KB.isNull($KB.VisibleSearchBox) ? null : $KB.VisibleSearchBox;
}
$KB.SetSearchBoxState = function(params)
{
	if($KB.isNull($KB.VisibleSearchBox)) return;
	$KB.VisibleSearchBox.SetDisabled($KB.FixNull(params.Disabled, false));
	if(!$KB.isNull(params.Text)) $KB.VisibleSearchBox.SetText($KB.FixNull(params.Text, ''));
};
$KB.getCurrentTabId = function ()
{
	if ($KB.isNull($KB.PageTabs))
	{
		return "";
	}
	var t = $KB.PageTabs.getActiveTab();
	return t == null ? 'homeTab' : t.itemId;
};
$KB.getCurrentTabName = function()
{
	var z = $KB.getCurrentTabId();
	return z.substr(0, z.length-3);
};
$KB.TabManager = new function ()
{
	this.items = [];
	this.indexByTabName = [];
	this.TabNames = [];
	this.history = [];
	this.add = function(crumb)
	{
		var index = this.items.length;
		var TabName = $KB.getCurrentTabName().toLowerCase();
		this.TabNames.push(TabName);
		this.indexByTabName[TabName] = index;
		this.items.push(crumb);
		return index;
	}
	this.setActiveTab = function(tabName)
	{
		if (!Ext.isDefined($KB.PageTabs)) return;
		var t = tabName.toLowerCase();
		t = ($KB.right(t,3) == "tab" ? $KB.left(t.length-3) : t);
		$KB.PageTabs.setActiveTab($KB.MatchByName(t, $KB.TabNames) + "Tab");
	}
	this.addHistory = function(index, cId, params)
	{
		params.cId = cId;
		params.tab = this.TabNames[index];
		//alert($KB.buildParams(params));
		//this.history.push($KB.buildParams(params));
		//$KB.Cookie.setCookie('History', this.history, 1);
	}
	this.getTab = function(tabName)
	{
		var t = tabName.toLowerCase();
		if (Ext.isDefined(this.indexByTabName[t]))
		{
			return this.items[this.indexByTabName[t]]
		}
		return null;
	}
	this.refresh = function()
	{
		if (this.items.length == 0) return;
		var t = this.getTab($KB.getCurrentTabName());
		if (t != null) t.refresh();
	}
	this.getNS = function(tabName)
	{
		var tab = this.getTab(tabName);
		return (tab == null ? null : tab.ns);
	}
};
$KB.BreadCrumbManager = function(params)
{
	this.params = [];
	this.ParamNames = [];
	this.disabled = false;
	this.currentItem = null;
	this.onRefresh = params.onRefresh;
	this.ns = params.ns;
	this.writeCrumb = function(crumb)
	{
		if (!crumb.rendered)
		{
			crumb.separator = null;
			crumb.element = document.createElement("span");
			crumb.element.cId = crumb.cId;
			crumb.element.manager = this;
			if (crumb.parent != null)
			{
				var crumbParent = this.Crumbs[crumb.parent];
				if (!crumbParent.rendered)
				{
					this.writeCrumb(crumbParent)
				}
				crumb.separator = document.createElement("span");
				crumb.separator.className = "SD_CrumbSep";
				crumb.separator.innerHTML = "&nbsp;";
				this.container.appendChild(crumb.separator);
			}
			this.container.appendChild(crumb.element);
			if (Ext.isDefined(crumb.idField))
			{
				crumb.LastId = this.params[crumb.idField];
			}
			crumb.rendered = true;
		}
		var lbl = $KB.FixNull(Ext.isDefined(crumb.label) ? crumb.label : this.params[crumb.labelField], "null");
		crumb.element.title = lbl;
		var newLbl = Ext.util.Format.substr(lbl,0,35);
		if(lbl.length == newLbl.length) crumb.element.innerHTML = newLbl;
		else crumb.element.innerHTML = newLbl + '<span class="SD_CrumbEllipsis" ' + $KB.BuildClick('var ele = $KB.elementFromEvent(event).parentElement;ele.innerHTML = \'' + $KB.escStr(lbl) + '\';') + '>...</span>';
	}
	this.hideCrumb = function(crumb)
	{
		if (!crumb.rendered) return;
		this.container.removeChild(crumb.element);
		crumb.element = null;
		if (crumb.separator != null) this.container.removeChild(crumb.separator);
		crumb.separator = null;
		crumb.rendered = false;
		this.hideChildren(crumb);
	}
	this.Select = function(cId, optionalParams, fromBack)
	{
		fromBack = $KB.FixNull(fromBack,false);
		if(!fromBack) $KB.ProcessCrumbClick = false;
		var params = $KB.FixNull(optionalParams,[]);
		var CrumbIndex = this.CrumbIndexByCid[cId];
		this.SelectedIndex = CrumbIndex;
		for (var iC = 0; iC < this.ParamNames.length; iC++)
		{
			var p = this.ParamNames[iC];
			if (Ext.isDefined(params[p]) && params[p] != null) this.params[p] = params[p];
		}
		var crumb = this.Crumbs[CrumbIndex];
		if (crumb.parent != null)
		{
			this.hideChildren(this.Crumbs[crumb.parent]);
		}
		if (crumb.children != null)
		{
			for (var i = 0; i < crumb.children.length; i++)
			{
				this.hideCrumb(this.Crumbs[crumb.children[i]]);
			}
		}
		$KB.TabManager.addHistory(this.index, cId, params);
		this.writeCrumb(crumb);
		this.activate(crumb, true);
		if($KB.allowHistoryAdd && $KB.IsMasterSite() && $KB.AllowHistory() && (!fromBack))
		{
			var histTab = $KB.getCurrentTabId();
			if( !( (histTab == $KB.DefTabName) && (CrumbIndex.toString() == '0') ) )
			{
				var prmsInfo = ($KB.FixNull(this.otherParams,null) != null) ? ':artId:' + this.otherParams.ArticleId : '';
				Ext.History.add('tab:' + histTab + ':crumb:' + CrumbIndex + prmsInfo);
			}
		}
	}
	this.click = function(CrumbElement)
	{
		$KB.ProcessCrumbClick = false;
		if (this.disabled) return;
		var ind = this.CrumbIndexByCid[CrumbElement.cId];
		this.clickByIndex(ind);
	}
	this.clickByIndex = function(index,doClick)
	{
		doClick = $KB.FixNull(doClick,true);
		if($KB.allowHistoryAdd && $KB.IsMasterSite() && $KB.AllowHistory())
		{
			var histTab = $KB.getCurrentTabId();
			if( !( (histTab == $KB.DefTabName) && (index.toString() == '0') ) )
			{
				Ext.History.add('tab:' + histTab + ':crumb:' + index);
			}
		}
		this.SelectedIndex = index;
		this.currentItem = index;
		var crumb = this.Crumbs[index];
		this.hideChildren(crumb);
		if (Ext.isDefined(crumb.onClick))
		{
			var params = [];
			$KB.CopyParam(this.params, params, crumb.labelField);
			$KB.CopyParam(this.params, params, crumb.idField);
			if(doClick) crumb.onClick(params);
		}
		$KB.ProcessCrumbClick = false;
	}
	this.GetCrumb = function(cId)
	{
		return this.Crumbs[this.CrumbIndexByCid[cId]];
	}
	this.hideChildren = function(crumb)
	{
		if (Ext.isDefined(crumb.children) && crumb.children.length > 0)
		{
			var TempIndex = null;
			for (var i=0; i < crumb.children.length; i++)
			{
				if (crumb.children[i].index != this.SelectedIndex)
				{
					this.hideCrumb(this.Crumbs[crumb.children[i]]) ;
					if(crumb.children[i].IsTemp)
					{
						TempIndex = i;
					}
				}
			}
			if (TempIndex != null)
			{
				$KB.RemoveElements(crumb.children, i);
			}
		}
	}
	this.refresh = function()
	{
		$KB.ProcessCrumbClick = true;
		if (this.currentItem != null) this.clickByIndex(this.currentItem);
		if (Ext.isDefined(this.onRefresh)) this.onRefresh();
	}
	this.activate = function(crumb, isSelected)
	{
		//if (!crumb.rendered) return;
		if (isSelected)
		{
			this.currentItem = crumb.index;
			crumb.element.moData = null;
			crumb.element.className = "SD_Crumb_sel";
			crumb.active = false;
			crumb.element.onmouseover = null;
			crumb.element.onmouseout = null;
			crumb.element.onclick = null;
		}
		else
		{
			var css = "SD_Crumb";
			crumb.element.moData = null;
			crumb.element.className = css;
			crumb.element.onmouseover = function () { Ext.ux.btnMO(this, true); };
			crumb.element.onmouseout = function () { Ext.ux.btnMO(this, false); };
			crumb.element.onclick = function () { this.manager.click(this); }
			crumb.active = true;
		}
		if (crumb.parent != null)
		{
			this.activate(this.Crumbs[crumb.parent], false);
		}
	}
	this.AddCrumbs = function(CrumbsToAdd, parent)
	{
		for (var i=0; i< CrumbsToAdd.length; i++)
		{
			var crumb = [];
			crumb.index = (this.Crumbs.length);
			if (parent != null)
			{
				crumb.parent = parent.index;
				parent.children.push(crumb.index);
			}
			else
			{
				crumb.parent = null;
			}
			var paramList = [ "cId","idField","labelField","onClick","label" ];
			for (var pl = 0; pl < paramList.length; pl++)
			{
				var p = paramList[pl];
				if (Ext.isDefined(CrumbsToAdd[i][p]))
				{
					var xP = CrumbsToAdd[i][p];
					switch (p)
					{
						case "idField" : case "labelField":
							this.ParamNames.push(xP);
							break;
					}
					crumb[p] = xP;
				}
			}
			this.CrumbIndexByCid[crumb.cId] = crumb.index;
			crumb.active = false;
			crumb.rendered = false;
			crumb.children = [];
			this.Crumbs[crumb.index] = crumb;
			if (Ext.isDefined(CrumbsToAdd[i].children))
			{
				this.AddCrumbs(CrumbsToAdd[i].children, this.Crumbs[crumb.index]);
			}
		}
	}
	this.ShowTempCrumb = function(label,otherPrms,artBackFn,fromBack)
	{
		this.otherParams = $KB.FixNull(otherPrms,null);
		this.articleBackFn = $KB.FixNull(artBackFn,function(){});
		fromBack = $KB.FixNull(fromBack,false);
		var tc = this.Crumbs[this.CrumbIndexByCid["$temp"]];
		if (tc.index != this.SelectedIndex)
		 {
			tc.parent = this.SelectedIndex;
			var p = this.Crumbs[this.SelectedIndex];
			if (!Ext.isDefined(p.children)) p.children = [];
			if (!$KB.ArrayContains(p.children, this.SelectedIndex)) p.children.push(tc.index);
		}
		tc.label = label;
		 this.Select("$temp",null,fromBack);
	}
	this.setDisabled = function(bDisabled)
	{
		this.disabled = bDisabled;
		for (var i=0; i< this.Crumbs.length; i++)
		{
			if (Ext.isObject(this.Crumbs[i].element))
			{
				Ext.ux.btnDisable(this.Crumbs[i].element, bDisabled);
			}
		}
	}
	this.SelectedCrumb = function()
	{
		return this.Crumbs[this.SelectedIndex];
	}
	this.isDisplayed = function(cId)
	{
		var i = this.SelectedIndex;
		do
		{
			var crumb = this.Crumbs[i];
			if (crumb.cId == cId) return true;
			i = crumb.parent;
		} while (i != null);
		return false;
	}
	this.container = document.createElement("div");
	this.container.className = "SD_BreadCrumb";
	this.Crumbs = [];
	this.CrumbIndexByCid = [];
	var el = document.getElementById(params.renderTo);
	if (el != null) 
	{
		if (el.childNodes.length == 0)
		{
			el.appendChild(this.container);
		}
		else
		{
			el.insertBefore(this.container, el.firstChild);
		}
	}
	this.Actions = [];
	this.SelectedIndex = 0;
	this.AddCrumbs(params.crumbs, null);
	this.AddCrumbs([{ cId: '$temp', label: '$', IsTemp: true }], null)
	this.SelectedIndex = 0;
	this.writeCrumb(this.Crumbs[0]);
	this.activate(this.Crumbs[0], true);
	this.HasCrumb = function(CrumbId)
	{
		return Ext.isDefined(this.CrumbIndexByCid[CrumbId]);
	}
	this.index = $KB.TabManager.add(this);
};
$KB.isEmpty = function(x)
{
	return (!Ext.isDefined(x)) || x == null;
};
$KB.ReadData = function(store, RowId, FieldId)
{
	var val;
	if (Ext.isDefined(store))
	{
		{
			var r = store.data.get(RowId);
			if (r != null)
			{
				return r.data[FieldId];
			}
		}
	}
	return null;
};
$KB.toBool = function(v)
{
	if (typeof(v) == "boolean") return v;
	switch(v.toLowerCase())
	{
		case "true": case "yes": case "1": return true;
		case "false": case "no": case "0": case null: return false;
		default: return Boolean(v);
	}
};
$KB.LocationKeeper = function()
{
	this.items = [];
	this.sortItem = function(a,b)
	{
		if(a.Container == b.Container) return a.Position-b.Position;
		else
		{
			if(a.Container > b.Container) return 1;
			else if(a.Container < b.Container) return -1;
			else return 0;
		}
	};
	this.AddItem = function(item, container, position)
	{
		var ind = this.items.length;
		var pos = $KB.FixNullorEmpty(position,-1);
		var target = container;
		if(typeof($KB.Cookie.Data[item.id+'Target']) != 'undefined') target = $KB.Cookie.Data[item.id+'Target'];
		if(typeof($KB.Cookie.Data[item.id+'Pos']) != 'undefined') pos = parseInt($KB.Cookie.Data[item.id+'Pos']);
		this.items[ind] = {Item:item,Container:target,Position:pos};
	};
	this.RemoveItem = function(id,destroy)
	{
		var newItems = [];
		var pos = 0;
		for(var i=0;i<this.items.length;i++)
		{
			if(this.items[i].Item.id == id)
			{
				var cont = Ext.getCmp(this.items[i].Item.newOwnerId);
				cont.remove(this.items[i].Item, destroy);
			}
			else
			{
				newItems[pos] = this.items[i];
				pos++;
			}
		}
		this.items = newItems;
	};
	this.RemoveAllItems = function(destroy)
	{
		for(var i=0;i<this.items.length;i++)
		{
			Ext.getCmp(this.items[i].Item.newOwnerId).remove(this.items[i].Item, destroy);
		}
		this.items = [];
	};
	this.ShowItems = function()
	{
		var itms = this.items.sort(this.sortItem);
		for(var i=0;i<itms.length;i++)
		{
			itms[i].Item.newOwnerId = itms[i].Container;
			var container = Ext.getCmp(itms[i].Container);
			if(container.findById(itms[i].Item.id) == null)
			{
				container.add(itms[i].Item);
			}
		}
		$KB.doLayout(false,true);
	};
	this.SavePositions = function()
	{
		for(var i=0;i<this.items.length;i++)
		{
			var newParent = Ext.getCmp(this.items[i].Item.newOwnerId);
			var newPos = newParent.items.indexOf(this.items[i].Item);
			var params = {};
			params[this.items[i].Item.id + 'Target'] = newParent.id;
			params[this.items[i].Item.id + 'Pos'] = newPos;
			$KB.Cookie.Save(params);
		}
	};
}
$KB.GenericWidget = function(name, title, contentHTML)
{
	var cspd = false;
	if(typeof($KB.Cookie.Data[name+'Collapsed']) != 'undefined') cspd = $KB.toBool($KB.Cookie.Data[name+'Collapsed']);
	var widget = new Ext.ux.Portlet
	(
		{
			title: '<div class="SD_WidgetTitle">' + $KB.escTag(title) + '</div>',
			preventBodyReset: true,
			anchor: '',
			autoWidth: true,
			autoHeight: true,
			border: false,
			frame: false,
			collapsed: cspd,
			id: name,
			html: contentHTML,
			listeners:
			{
				collapse: function(p) 
				{
					var pms = {};
					pms[p.id+'Collapsed'] = true;
					$KB.Cookie.Save(pms);
				},
				expand: function(p) 
				{
					var pms = {};
					pms[p.id+'Collapsed'] = false;
					$KB.Cookie.Save(pms);
				}
			}
		}
	);
	return widget;
};
$KB.ItemWidget = function(name, title, item, preventBodyReset)
{
	var pbr = $KB.FixNull(preventBodyReset, true);
	var cspd = false;
	if (typeof($KB.Cookie.Data[name+'Collapsed']) != 'undefined') cspd = $KB.toBool($KB.Cookie.Data[name+'Collapsed']);
	var widget = new Ext.ux.Portlet
	(
		{
			title: '<div class="SD_WidgetTitle">' + $KB.escTag(title) + '</div>',
			preventBodyReset: pbr,
			anchor: '',
			autoWidth: true,
			autoHeight: true,
			border: false,
			frame: false,
			collapsed: cspd,
			id: name,
			items:
			[
				item
			],
			listeners:
			{
				collapse: function(p) 
				{
					var pms = {};
					pms[p.id+'Collapsed'] = true;
					$KB.Cookie.Save(pms);
				},
				expand: function(p) 
				{
					var pms = {};
					pms[p.id+'Collapsed'] = false;
					$KB.Cookie.Save(pms);
				}
			}
		}
	);
	return widget;
};
$KB.GetRecentSearchesString = function(tab)
{
	var str = '';
	switch(tab.toLowerCase())
	{
		case 'home':
			kbHome.RecentSearches;
			for(var i=0;i<kbHome.RecentSearches.length;i++)
			{
				str = str + '|$|' + escape(kbHome.RecentSearches[i].SearchText);
			}
			break;
	}
	return str;
}
$KB.GetRecentArticlesString = function(tab)
{
	var str = '';
	switch(tab.toLowerCase())
	{
		case 'home':
			for(var i=0;i<kbHome.RecentArticles.length;i++)
			{
				if(kbHome.RecentArticles[i].Source.toLowerCase() == 'article')
				{
					str = str + '|$|' + kbHome.RecentArticles[i].ArticleId + '||' + escape(kbHome.RecentArticles[i].Title);
				}
			}
			break;
	}
	return str;
}
$KB.OpenChat = function(tab)
{
	tab = $KB.FixNull(tab,'home');
	var cw = $KB.GlobalData.PortalProperties.ChatWidth;
	var ch = $KB.GlobalData.PortalProperties.ChatHeight;
	var curl = $KB.GlobalData.PortalProperties.ChatURL;
	var features = 'Width=' + cw + ',height=' + ch +
		',dialogWidth=500px,dialogHeight=250px,scrollbars=no,center=yes,border=thin,help=no,status=no,resizable=yes';
	var link = "&";
	if(curl.indexOf("?")<0)
	{
		link = "?";
	}
	var rs = $KB.GetRecentSearchesString(tab);
	var ra = $KB.GetRecentArticlesString(tab);
	window.open(curl + link + 'searchHistory=' + rs +'&viewHistory=' + ra +'&KBportalID=' + $KB.GlobalData.PortalProperties.PortalId,'_blank',features);
}
$KB.SupportWidget = function(name, tab)
{
	var widgetHtml = '';
	if($KB.GlobalData.PortalProperties.ChatScript.trim() != '')
	{
		widgetHtml = $KB.GlobalData.PortalProperties.ChatScript;
	}
	else
	{
		widgetHtml = '<div style="vertical-align: middle; height: auto; width: 100%; ">' +
			'<div class="FL" style="margin-top:16px; "><div onclick="$KB.OpenChat();" title="Live Chat" class="icon_chat" style="cursor:pointer;" ' +
			'>&emsp;' +
			'</div><div style="margin-top:4px;" class="icon_phone">&emsp;</div></div><div class="FL">' + 
			'<hr size="80%" width="1px" /></div><div width="100%" align="center"><div style="text-align: center; ">' + 
			'Live Chat</div><hr size="1px" width="50%" align="center" /><div style="text-align: center; ">' + 
			'chat live online to one of our representatives</div><hr size="1px" width="50%" align="center" />' + 
			'<div style="text-align: center; ">Chat Now</div></div></div>';
	}
	return $KB.GenericWidget(name,$KB.GlobalData.WidgetManagement.ChatEscalation.Description,widgetHtml);
};
$KB.SearchWidget = function(name)
{
	var akbs = $KB.GlobalData.WidgetManagement.AllKBSearch;
	var widgetHtml = '<div style="vertical-align: middle; height: auto; width: 100%; text-align: center; "><div style=\'font-weight: bold; width: 100%; text-align: center; \'>' +
		akbs.ContentText + '</div><div style=\'text-align: center; width: 100%; \'><input id=\'' + name + 'Input\' onkeypress=\'if(event.keyCode == 13){ var searchText = Ext.get("' + name + 'Input").dom.value; $KB.SearchClicked(searchText); }\' style=\'width: 80%; \' type=\'text\' /></div><div style=\'text-align: center; width: 100%; \'><input value=\'' +
		akbs.ButtonText + '\' id=\'' + name + 'Button\' type=\'button\' onclick=\'var v = Ext.get("' + name + 'Input").dom.value; $KB.SearchClicked(v);\' class=\'x-btn-text x-btn-mc x-btn-small x-btn  x-btn-noicon\' /></div></div>';
	return $KB.GenericWidget(name,akbs.Description,widgetHtml);
};
$KB.ProvideFeedbackWidget = function(name)
{
	var wm = $KB.GlobalData.WidgetManagement;
	var widgetHtml = '<div> <div>' + wm.PortalFeedback.ContentText + '</div> <div style="font-weight: bold; color: navy; cursor: pointer; " onclick="$KB.ShowFeedBack();">' + wm.PortalFeedback.ButtonText + '</div> </div>';
	return $KB.GenericWidget(name,wm.PortalFeedback.Description,widgetHtml);
};
$KB.ShowFeedBack = function()
{
	var itms = [];
	if($KB.LoggedIn)
	{
		itms[0] =
		{
			xtype:'textfield', id:'kbFeedbackSubject',
			fieldLabel:'Subject'
		};
		itms[1] =
		{
			xtype:'textarea', id:'kbFeedbackDetail',
			anchor:'75%',
			height:150,
			fieldLabel:'Please provide as much detail as possible'
		}
	}
	else
	{
		itms[0] =
		{
			xtype:'textfield', id:'kbFeedbackName',
			fieldLabel:$KB.LZ('Widget_FB_Name', "Your Name")
		};
		itms[1] =
		{
			xtype:'textfield', id:'kbFeedbackEmail',
			fieldLabel:$KB.LZ('Widget_FB_Email', "Email Address")
		};
		itms[2] =
		{
			xtype:'textfield', id:'kbFeedbackSubject',
			fieldLabel:$KB.LZ('Widget_FB_Subject', "Subject")
		};
		itms[3] =
		{
			xtype:'textarea', id:'kbFeedbackDetail',
			anchor:'75%',
			height:150,
			fieldLabel:$KB.LZ('Widget_FB_Detail', "Please provide as much detail as possible")
		}
	}
	$KB.FeedbackWindow = new Ext.Window
	(
		{
			id: 'FeedbackWindow',
			renderTo: Ext.getBody(),
			closable: true,
			title: $KB.LZ('Widget_FB_Title', 'Knowledge Base Site Feedback'),
			modal: true,
			width: 800,
			autoHeight:true,
			listeners: { close: function() { $KB.FeedbackWindow.destroy(); }	},
			items:
			[
				{
					xtype:'box',
					autoEl:{tag:'div',html:$KB.LZ('Widget_FB_Tell_Us', 'Tell us what you think about the knowledge base. Submit your comments and suggestions to help us make the experience better.')},
					style:'padding:10px;'
				},
				{
					xtype:'box',
					autoEl:{tag:'div',html:$KB.LZ('Widget_FB_Ask', 'IMPORTANT: If you need help with a specific problem about Website, please ask your question in Support Forums or Contact Support for assistance.')},
					style:'padding:10px; color:red; '
				},
				{
					xtype:'form',
					bodyStyle:'background-color:transparent; padding:10px; ',
					hideBorders:true,
					border:false,
					defaults:
					{
						labelSeparator:'',
						width: 200
					},
					items: itms,
					bbar:
					{
						items:
						[
							'->',
							{
								text:$KB.LZ('Cancel', 'Cancel'), handler:function() {$KB.HideFeedBack();}
							},
							' ',
							{
								text:$KB.LZ('Submit', 'Submit'), handler:function()
								{
									var nme = '';
									var eml = '';
									var sbj = Ext.getCmp('kbFeedbackSubject').getValue();
									var det = Ext.getCmp('kbFeedbackDetail').getValue();
									if(sbj.trim() == '' || det.trim() == '')
									{
										$KB.alert($KB.LZ('Login_Access_Fill','Please fill out all fields.'));
										return;
									}
									if(!$KB.LoggedIn)
									{
										nme = Ext.getCmp('kbFeedbackName').getValue();
										eml = Ext.getCmp('kbFeedbackEmail').getValue();
										if(nme.trim() == '' || eml.trim() == '')
										{
											$KB.alert($KB.LZ('Login_Access_Fill','Please fill out all fields.'));
											return;
										}
									}
									DirectRequest.ProvideFeedback(
										nme,
										eml,
										Ext.getCmp('kbFeedbackSubject').getValue(),
										Ext.getCmp('kbFeedbackDetail').getValue(),
										function(res,resp) {
											$KB.HideFeedBack();
										});
								}
							}
						]
					}
				}
			]
		}
	).show();
};
$KB.GetPage = function(t)
{
	return Math.ceil((t.cursor + t.pageSize) / t.pageSize);
};
$KB.HideFeedBack = function()
{
	$KB.FeedbackWindow.destroy();
};
$KB.RedrawPortal = function(e)
{
	var portalColumn = e.panel;
	var portal = portalColumn.ownerCt;
	var columnSize = portalColumn.getOuterSize();
	portal.ownerCt.doLayout(false, true);
	$KB.PageTabs.doLayout(false,true);
};
$KB.FindMatchIndex = function(arr, matchProperty, matchValue)
{
	var match = false;
	for (var i=0; i< arr.length; i++)
	{
		var val = $KB.FixNullorEmpty(arr[i][matchProperty], null);
		if  ((val != null) && val == matchValue) return i;
	}
	return -1;
};
$KB.DestroyWidget = function(name)
{
	var data = {}
	data.Existed = false;
	var b = Ext.getCmp(name);
	if(b != null)
	{
		data.Existed = true;
		data.OwnerId = b.ownerCt.id;
		data.Index = b.ownerCt.items.indexOf(b);
		b.ownerCt.remove(b, true);
	}
	return data;
};
$KB.CloneObject = function(inObj)
{
	for (i in inObj)
	{
		this[i] = inObj[i];
	}
}
$KB.GetExtensionIconClass = function(f)
{
	var fc = "icon_" + f.substr(1);
	return (Ext.util.CSS.getRule('.' + fc) != null) ? fc : '';
}
$KB.GetExtensionTitle = function(f)
{
	var fe = f.toLowerCase();
	if(!$KB.isNull($KB.GlobalData.FileTypeTitle[fe]))
	{
		return $KB.GlobalData.FileTypeTitle[fe];
	}
	return "";
}
$KB.SearchResultsTabPanel = function(params)
{
	//private fields
	this.searchText = params.SearchText;
	this.doEmptySearch = $KB.FixNull(params.DoEmptySearch,false);
	this.onLoad = $KB.FixNullorEmpty(params.OnLoad,null);
	this.onFail = $KB.FixNullorEmpty(params.OnFail,null);
	this.searchResult = null;
	this.displayContainer = $KB.getCmp(params.DisplayContainer);
	this.refineWidgetParentId = $KB.FixNullorEmpty(params.RefineWidgetParentId,'');
	this.refineWidgetId = $KB.FixNullorEmpty(params.RefineWidgetId,'');
	this.tabPanelId = $KB.FixNullorEmpty(params.TabPanelId,'searchResultsTabPanel999');
	this.refineWidgetIndex = $KB.FixNullorEmpty(params.RefineWidgetIndex,0);
	this.showRefineWidget = $KB.FixNullorEmpty(params.ShowRefineWidget,false) && $KB.GlobalData.PortalProperties.SearchFilterEnabled;
	this.showTabs = $KB.FixNullorEmpty(params.ShowTabs,true);
	this.mainTabTitle = $KB.FixNullorEmpty(params.MainTabTitle,$KB.LZ('Search_All_Results', 'All Results'));
	this.sessionVariableName = $KB.FixNullorEmpty(params.SessionVariableName,'SearchResults');
	this.itemTypeFilter = $KB.FixNullorEmpty(params.ItemTypeFilter,'All');
	this.onItemClick = $KB.FixNullorEmpty(params.OnItemClick,null);
	$KB['searchTitleClick' + this.tabPanelId] = this.onItemClick;
	this.showSearchWithin = $KB.FixNullorEmpty(params.ShowSearchWithin,false);
	this.showSort = $KB.FixNullorEmpty(params.ShowSort,false);
	this.sortColumn = $KB.FixNullorEmpty(params.SortBy,'RankDbl');
	this.sortDirection = $KB.FixNullorEmpty(params.SortDirection,'DESC');
	this.anchor = $KB.FixNullorEmpty(params.TabControlAnchor,'0 0');
	this.doAdvancedSearch = $KB.FixNullorEmpty(params.DoAdvancedSearch,false);
	this.lastSearchesData = $KB.FixNull(params.LastSearchesData, null);
	this.lastArticlesData = $KB.FixNull(params.LastArticlesData, null);
	this.showSuggestedSearches = $KB.FixNullorEmpty(params.ShowSuggestedSearches, false);
	this.showSpellCheck = $KB.FixNullorEmpty(params.ShowSpellCheck, false);
	this.showPinnedArticles = $KB.FixNullorEmpty(params.ShowPinnedArticles, false);
	$KB['searchResults' + this.tabPanelId] = this;
	this.selectedKBs = $KB.FixNullorEmpty(params.SelectedKBs,'');
	this.selectedCategories = $KB.FixNullorEmpty(params.SelectedCategories,'');
	this.searchSourceType = $KB.FixNullorEmpty(params.SearchSourceType,'HOME').toUpperCase();
	this.breadCrumb = $KB.FixNullorEmpty(params.BreadCrumb,null);
	this.breadCrumbSelection = $KB.FixNullorEmpty(params.BreadCrumbSelection,null);
	this.breadCrumbParams = $KB.FixNullorEmpty(params.BreadCrumbParams,null);
	this.isSnapIn = $KB.FixNull(params.IsSnapIn,false);
	this.advanced = (typeof(params.Advanced) != 'undefined') ?
		{
			ResultsPerPage: $KB.FixNullorEmpty(params.Advanced.ResultsPerPage,$KB.GlobalData.SearchResultDisplay.ResultsPerPage),
			KBS: $KB.FixNullorEmpty(params.Advanced.KBS,''),
			Categories: $KB.FixNullorEmpty(params.Advanced.Categories,''),
			Attributes: $KB.FixNullorEmpty(params.Advanced.Attributes,''),
			Tags: $KB.FixNullorEmpty(params.Advanced.Tags,''),
			AllOfTheseWords: $KB.FixNullorEmpty(params.Advanced.AllOfTheseWords,''),
			AnyOfTheseWords: $KB.FixNullorEmpty(params.Advanced.AnyOfTheseWords,''),
			NotTheseWords: $KB.FixNullorEmpty(params.Advanced.NotTheseWords,''),
			SearchType: $KB.FixNullorEmpty(params.Advanced.SearchType,1),
			KeywordLocation: $KB.FixNullorEmpty(params.Advanced.KeywordLocation,'anywhere'),
			Wildcard: $KB.FixNullorEmpty(params.Advanced.Wildcard,true),
			UseDate: $KB.FixNullorEmpty(params.Advanced.UseDate,false),
			FromDate: $KB.FixNullorEmpty(params.Advanced.FromDate,new Date()),
			ToDate: $KB.FixNullorEmpty(params.Advanced.ToDate,new Date()),
			Filesize: $KB.FixNullorEmpty(params.Advanced.Filesize,'Any'),
			CaseSensitive: $KB.FixNullorEmpty(params.Advanced.CaseSensitive,false),
			Language: $KB.FixNullorEmpty(params.Advanced.Language,''),
			FileTypes: $KB.FixNullorEmpty(params.Advanced.FileTypes,''),
			RemoteSiteIds: $KB.FixNullorEmpty(params.Advanced.RemoteSiteIds,''),
			RemoteFileIds: $KB.FixNullorEmpty(params.Advanced.RemoteFileIds,''),
			RemoteDBIds: $KB.FixNullorEmpty(params.Advanced.RemoteDBIds,'')
		}:
		{
			ResultsPerPage: $KB.GlobalData.SearchResultDisplay.ResultsPerPage,
			KBS: '',
			Categories: '',
			Attributes: '',
			Tags: '',
			AllOfTheseWords: '',
			AnyOfTheseWords: '',
			NotTheseWords: '',
			SearchType: 1,
			KeywordLocation: 'anywhere',
			Wildcard: true,
			UseDate: false,
			FromDate: new Date(),
			ToDate: new Date(),
			Filesize: 'Any',
			CaseSensitive: false,
			Language: '',
			FileTypes: '',
			RemoteSiteIds: '',
			RemoteFileIds: '',
			RemoteDBIds: ''
		};
	this.searchFilter =
	{
		'ArticlesChecked': true,
		'ForumsChecked': true,
		'FAQsChecked': true,
		'WikisChecked': true,
		'GlossaryChecked': true,
		'SFChecked': true,
		'RSChecked': true,
		'RFSChecked': true,
		'RDBChecked': true
	}
	//private methods
	this.init = function(pms)
	{
		var thisObject = this;
		this.sortValue = 4;
		switch($KB.GlobalData.SearchResultDisplay.DefaultSortOption)
		{
			case 1: this.sortValue = 1; break;
			case 2: this.sortValue = 3; break;
			case 4: this.sortValue = 2; break;
		}
		var srtInfo = this.getSortFromRecord(this.sortValue);
		this.sortDirection = srtInfo.Dir;
		this.sortColumn = srtInfo.Sort;
		if(this.lastSearchesData != null)
		{
			this.lastSearchesData[this.lastSearchesData.length] = new $KB.CloneObject(params);
		}
		if(this.doAdvancedSearch)
		{
			if(this.doEmptySearch)
			{
				var result = {
					Ads:{},
					AttributeCounts:{"-1":{Key:'',Value:1}},
					Counts:[{ArticleCount:0,FAQCount:0,ForumCount:0,GlossaryCount:0,OtherCount:0,RDBCount:0,RFSCount:0,RSCount:0,SFCount:0,TotalCount:0,WikiCount:0},1,{'':6,HTML:1}],
					KBCounts:{"-1":{Key:'',Value:1}},
					PinnedArticles:{},
					RemoteDBCounts:{},
					SearchId:'',
					SearchText:'',
					SpellCheckWords:{},
					SuggestedSearches:[]
				};
				thisObject.searchId = result.SearchId;
				thisObject.searchResult = result.Counts;
				thisObject.ads = result.Ads;
				thisObject.remoteDBCounts = result.RemoteDBCounts;
				thisObject.kbCounts = result.KBCounts;
				thisObject.attributeCounts = result.AttributeCounts;
				thisObject.suggestedSearches = result.SuggestedSearches;
				thisObject.spellCheckWords = result.SpellCheckWords;
				thisObject.pinnedArticles = result.PinnedArticles;
				thisObject.showSearchResults(false, {SearchWithin:false,SearchWithinText:''}, false);
				if(thisObject.onLoad != null) thisObject.onLoad(result);
				thisObject.setBreadCrumb(this.searchText);
			}
			else
			{
				var options =
				{
					SearchText: this.searchText,
					SessionName: this.sessionVariableName,
					KBS: this.advanced.KBS,
					Categories: this.advanced.Categories,
					Attributes: this.advanced.Attributes,
					Tags: this.advanced.Tags,
					SearchType: this.advanced.SearchType,
					AllOfTheseWords: this.advanced.AllOfTheseWords,
					AnyOfTheseWords: this.advanced.AnyOfTheseWords,
					UnwantedWords: this.advanced.NotTheseWords,
					ResultsPerPage: this.advanced.ResultsPerPage,
					Wildcard: this.advanced.Wildcard,
					Filesize: this.advanced.Filesize,
					UseDate: this.advanced.UseDate,
					FromDate: this.advanced.FromDate,
					ToDate: this.advanced.ToDate,
					KeywordLocation: this.advanced.KeywordLocation,
					CaseSensitive: this.advanced.CaseSensitive,
					Language: this.advanced.Language,
					FileTypes: this.advanced.FileTypes,
					SearchWithin: pms.SearchWithin,
					SearchWithinText: pms.SearchWithinText,
					AllowSearchWithin: this.showSearchWithin,
					RemoteSiteIds: this.advanced.RemoteSiteIds,
					RemoteFileIds: this.advanced.RemoteFileIds,
					RemoteDBIds: this.advanced.RemoteDBIds
				};
				DirectRequest.GetAdvancedSearchResults(options, function(res, response)
				{
					if($KB.CheckValueResponse(response))
					{
						var result = res.Value;
						thisObject.searchId = result.SearchId;
						thisObject.searchResult = result.Counts;
						thisObject.ads = result.Ads;
						thisObject.remoteDBCounts = result.RemoteDBCounts;
						thisObject.kbCounts = result.KBCounts;
						thisObject.attributeCounts = result.AttributeCounts;
						thisObject.suggestedSearches = result.SuggestedSearches;
						thisObject.spellCheckWords = result.SpellCheckWords;
						thisObject.pinnedArticles = result.PinnedArticles;
						thisObject.showSearchResults(false, pms, pms.SearchWithin);
						if(thisObject.onLoad != null) thisObject.onLoad(result);
						thisObject.setBreadCrumb(result.SearchText);
					}
					else 
					{
						$KB.SetSearchBoxState.defer(1000, thisObject, [{Disabled:false}]);
						if(thisObject.onFail != null) thisObject.onFail();
					}
				});
			}
		}
		else
		{
			DirectRequest.GetSearchResults
			(
				this.searchText, this.sessionVariableName, this.itemTypeFilter, pms.SearchWithin, pms.SearchWithinText, this.showSearchWithin, this.selectedKBs, this.selectedCategories, this.searchSourceType, function(res, response)
				{
					if($KB.CheckValueResponse(response))
					{
						var result = res.Value;
						thisObject.searchId = result.SearchId;
						thisObject.searchResult = result.Counts;
						thisObject.ads = result.Ads;
						thisObject.remoteDBCounts = result.RemoteDBCounts;
						thisObject.kbCounts = result.KBCounts;
						thisObject.attributeCounts = result.AttributeCounts;
						thisObject.suggestedSearches = result.SuggestedSearches;
						thisObject.spellCheckWords = result.SpellCheckWords;
						thisObject.pinnedArticles = result.PinnedArticles;
						thisObject.showSearchResults(false, pms, pms.SearchWithin);
						if(thisObject.onLoad != null) thisObject.onLoad(result);
						thisObject.setBreadCrumb(result.SearchText);
					}
					else 
					{
						$KB.SetSearchBoxState.defer(1000, thisObject, [{Disabled:false}]);
						if(thisObject.onFail != null) thisObject.onFail();
					}
				}
			);
		}
	}
	this.setBreadCrumb = function(searchText)
	{
		if(this.breadCrumb != null)
		{
			var newParams = [];
			for(var v in this.breadCrumbParams)
			{
				if(typeof(this.breadCrumbParams[v]) == 'string')
				{
					var nv = this.breadCrumbParams[v].replace('{SearchText}', searchText);
					newParams[v] = nv;
				}
				else
				{
					newParams[v] = this.breadCrumbParams[v];
				}
			}
			this.breadCrumb.Select(this.breadCrumbSelection,newParams);
		}
	}
	this.showSearchResults = function(fromSort, parameters, fromSearchWithin)
	{
		fromSearchWithin = $KB.FixNull(fromSearchWithin,false);
		var thisObject = this;
		var ht = 5;
		if(this.showSearchWithin) ht = ht + 40;
		if(this.showSpellCheck && (this.spellCheckWords.length>0)) ht = ht + 20;
		if(!fromSort)
		{
			var cont = new Ext.Container
			(
				{
					layout:'column',
					hideBorders:true,
					anchor:'0 0',
					items:
					[
						{
							xtype:'container',
							hideBorders:true,
							columnWidth:1,
							layout:'anchor',
							items:
							[
								{
									hidden: (ht > 5) ? false : true,
									height: ht
								},
								{
									anchor: '0 -' + ht.toString(),
									layout: 'anchor'
								}
							]
						},
						{
							xtype:'panel',
							width:200,
							border:false,
							autoScroll:true,
							style:'padding-top:0px;',
							defaults:
							{
								style:'padding:10px;'
							}
						}
					],
					listeners:
					{
						resize:function(comp,aw,ah,rw,rh)
						{
							if( (typeof(rw) != 'undefined') && (typeof(rh) != 'undefined') )
							{
								comp.get(0).setSize(rw-200,rh);
								comp.get(1).setSize(200,rh);
							}
							else if (typeof(rw) != 'undefined')
							{
								comp.get(0).setWidth(rw);
							}
							else if (typeof(rh) != 'undefined')
							{
								comp.get(0).setHeight(rh);
								comp.get(1).setHeight(rh);
							}
						}
					}
				}
			);
			this.ContColumn1 = cont.get(0);
			this.ContColumn2 = cont.get(1);
			this.MainCont = cont;
		}
		var result = this.searchResult;
		var tabItems = [];
		var pos = 1;
		var allPanel = this.getSearchResultTab('All', 0);
		tabItems[0] = allPanel;
		if(this.showTabs)
		{
			if(result[0].ForumCount > 0)
			{
				tabItems[pos] = this.getSearchResultTab('Forum', pos);
				pos++;
			}
			if(result[0].WikiCount > 0)
			{
				tabItems[pos] = this.getSearchResultTab('Wiki', pos);
				pos++;
			}
			if(result[0].OtherCount > 0)
			{
				tabItems[pos] = this.getSearchResultTab('Other', pos);
				pos++;
			}
		}
		//add search within if configured
		if(!fromSort)
		{
			if(this.showSearchWithin)
			{
				var thisObject = this;
				this.topContainer = new Ext.Container
				({
					autoHeight: true,
					style: 'padding: 4px; '
				});
				var sw = new $KB.SearchControl({
						Id:this.tabPanelId + 'sw',
						Parent:this.topContainer,
						Text: ($KB.FixNull(parameters.SearchWithin, false)) ? parameters.SearchWithinText : '',
						SearchClicked: function(text) {
							if(text != $KB.LZ('Search_Within', 'Search Within...'))
							{
								thisObject.DestroyObjects();
								thisObject.init({SearchWithin:true, SearchWithinText:text});
							}
						},
						EmptyText:$KB.LZ('Search_Within', 'Search Within...')
					});
				this.ContColumn1.get(0).add(this.topContainer);
			}
		}
		if(this.showTabs)
		{
			var stpDef = 
			{
				id: this.tabPanelId,
				plain:true,
				border:false,
				frame: false,
				bodyStyle:'background-color:transparent;',
				activeTab: 0, style: 'padding-bottom: 10px',
				anchor: '0 0',
				items: tabItems,
				listeners:
				{
					tabchange: function(tabPanel,Tab)
					{
						$KB.RefreshCustomTab(thisObject.tabPanelId,'Children', Tab);
					}
				}
			};
			$KB.AddCustomTabOptions(this.tabPanelId,'Children',stpDef);
			this.searchResultsTabPanel = new Ext.TabPanel(stpDef);
		}
		else
		{
			this.searchResultsTabPanel = new Ext.Panel({
				id: this.tabPanelId,
				border:false,
				layout: 'anchor',
				frame: false,
				anchor: '0 0',
				items: tabItems
			});
		}
		if(fromSort)
		{
			this.ContColumn1.get(1).add(this.searchResultsTabPanel);
		}
		else
		{
			if(this.showSpellCheck != null) this.createSpellCheck();
			this.ContColumn1.get(1).add(this.searchResultsTabPanel);
			this.rightColItemCount = 0;
			if(this.itemTypeFilter == 'All')
			{
				if(this.showSuggestedSearches) this.createSuggested();
				if(this.lastSearchesData != null) this.createLastSearches();
				if(this.lastArticlesData != null) this.createLastArticles();
				if(this.showPinnedArticles != null) this.createPinnedArticles();
				this.createAds();
			}
			if(this.rightColItemCount == 0) this.ContColumn2.hide();
			else this.ContColumn2.show();
			this.displayContainer.add(cont);
			if(this.showRefineWidget) this.refineSearch(fromSearchWithin);
		}
		this.displayContainer.doLayout(false, true);
	}
	this.createPinnedArticles = function()
	{
		if(this.pinnedArticles.length>0)
		{
			var html = '<div>';
			for(var i=0;i<this.pinnedArticles.length;i++)
			{
				var pos = i+1;
				var txt = this.pinnedArticles[i].Value;
				var pms = this.getParameterString({ArticleID:this.pinnedArticles[i].Key,ItemType:'Article',Title:this.pinnedArticles[i].Value});
				html = html + '<div style=\'clear:left;\'><div onclick="$KB.searchResults' + this.tabPanelId + '.titleClicked (' + pms + ')" style=\'float:left;cursor:pointer;\' class=\'SD_ListItem\'>' + $KB.escTag(txt) + '</div></div>';
			}
			html = html + '</div>';
			var panel = new Ext.Panel(
			{
				id:this.tabPanelId + 'pinnedArticles',
				title:$KB.LZ('Search_Pinned_Articles', 'Pinned Articles'),
				header:true,
				border:false,
				html:html,
				width:200
			});
			this.ContColumn2.add(panel);
			this.rightColItemCount++;
		}
	}
	this.createSpellCheck = function()
	{
		if(this.spellCheckWords.length>0)
		{
			var txt = '';
			var spc = '';
			for(var i=0;i<this.spellCheckWords.length;i++)
			{
				txt = txt + spc + this.spellCheckWords[i];
				spc = ' ';
			}
			var html = '<div class=\'FL\' style=\'margin-right:10px;\'>' + $KB.LZ("didyoumean","Did you mean?") + '</div><div id=\'' + this.tabPanelId + 'spellDiv\' onmouseover=\'var el = document.getElementById("' + this.tabPanelId + 'spellDiv"); el.style.textDecoration = "underline"; el.style.color = "blue";\' onmouseout=\'var el = document.getElementById("' + this.tabPanelId + 'spellDiv"); el.style.textDecoration = "none"; el.style.color = "black";\' onclick=\'$KB.searchResults' + this.tabPanelId + '.reSearch("' + $KB.escStr(txt) + '");\' class=\'FL\' style=\'padding-left:20px;padding-right:20px;cursor:pointer;\'>' + $KB.escTag(txt) + '</div>';
			var panel = new Ext.BoxComponent(
			{
				id:this.tabPanelId + 'spellCheck',
				style:'padding:2px;',
				autoEl:
				{
					tag:'div',
					html:html
				}
			});
			this.ContColumn1.get(0).add(panel);
		}
	}
	this.reSearch = function(txt)
	{
		var oldData = this.DestroyObjects();
		params.RefineWidgetIndex = oldData.WidgetIndex;
		params.ShowRefineWidget = oldData.WidgetExisted;
		params.RefineWidgetParentId = oldData.WidgetOwnerId;
		params.SearchText = txt;
		this.searchText = txt;
		this.init({SearchWithin: false, SearchWithinText: ''});
	}
	this.createLastArticles = function()
	{
		var wm = $KB.GlobalData.WidgetManagement;
		if(!wm.ArticlesViewed.IsEnabled) return;
		if(this.lastArticlesData.length>0)
		{
			var html = '<div>';
			for(var i=0;i<this.lastArticlesData.length;i++)
			{
				var pos = i+1;
				var txt = this.lastArticlesData[i].Title;
				var pms = $KB.buildParams(this.lastArticlesData[i]);
				html = html + '<div style=\'clear:left;\'><div onclick="$KB.searchResults' + this.tabPanelId + '.titleClicked (' + pms + ');" style=\'float:left;cursor:pointer;\' class=\'SD_ListItem\'>' + $KB.escTag(txt) + '</div></div>';
			}
			html = html + '</div>';
			var panel = new Ext.Panel(
			{
				id:this.tabPanelId + 'lastArticles',
				title:$KB.GlobalData.WidgetManagement.ArticlesViewed.Description,
				header:true,
				border:false,
				html:html,
				width:200
			});
			this.ContColumn2.add(panel);
			this.rightColItemCount++;
		}
	}
	this.createLastSearches = function()
	{
		var wm = $KB.GlobalData.WidgetManagement;
		if(!wm.RecentSearches.IsEnabled) return;
		if(this.lastSearchesData.length>1)
		{
			var html = '<div>';
			for(var i=0;i<this.lastSearchesData.length-1;i++)
			{
				var pos = i+1;
				var txt = this.lastSearchesData[i].SearchText;
				html = html + '<div style=\'clear:both;\'><div onclick=\'$KB.searchResults' + this.tabPanelId +
				'.reSearch("' + $KB.replaceDoubleQuotesForInnerJS(txt) + '");\' style=\'float:left;cursor:pointer;\' class=\'SD_ListItem\'>' + $KB.escapeLiteral2(txt) + '</div></div>';
			}
			html = html + '</div>';
			var panel = new Ext.Panel(
			{
				id:this.tabPanelId + 'lastSearches',
				title:$KB.GlobalData.WidgetManagement.RecentSearches.Description,
				header:true,
				border:false,
				html:html,
				width:200
			});
			this.ContColumn2.add(panel);
			this.rightColItemCount++;
		}
	}
	this.createSuggested = function()
	{
		if(this.suggestedSearches.length > 0)
		{
			var html = '<div>';
			for(var i=0;i<this.suggestedSearches.length;i++)
			{
				var pos = i+1;
				var txt = this.suggestedSearches[i];
				html = html + '<div style=\'clear:both;\'><div onclick=\'$KB.searchResults' + this.tabPanelId +
				'.reSearch("' + $KB.escapeLiteral2(txt) + '");\' style=\'float:left;cursor:pointer;\' class=\'SD_ListItem\'>' + $KB.escapeLiteral2(txt) + '</div></div>';
			}
			html = html + '</div>';
			var panel = new Ext.Panel(
			{
				id:this.tabPanelId + 'suggested',
				title:$KB.LZ('Search_Suggested', 'Suggested Searches'),
				header:true,
				border:false,
				html:html,
				width:200
			});
			this.ContColumn2.add(panel);
			this.rightColItemCount++;
		}
	}
	this.createAds = function()
	{
		for(var i=0;i<this.ads.length;i++)
		{
			var panel = new Ext.Container(
			{
				id:this.tabPanelId + 'ad' + i.toString(),
				//style:'padding:10px;',
				autoEl:
				{
					tag:'div',
					style:'width:180px;overflow:auto;',
					html:this.ads[i].HTML
				}
			});
			this.ContColumn2.add(panel);
			this.rightColItemCount++;
		}
	}
	this.getSortFromRecord = function(val)
	{
		var sort = '';
		var dir = '';
		switch(val)
		{
			case 1://Relevance
				sort = 'RankDbl';
				dir = 'DESC';
				break;
			case 2://Title
				sort = 'Title';
				dir = 'ASC';
				break;
			case 3://Mod Date
				sort = 'SortModDate';
				dir = 'DESC';
				break;
			case 4://Create Date
				sort= 'SortCreateDate';
				dir = 'DESC';
				break;
		}
		return {Sort:sort,Dir:dir};
	}
	this.sort = function(record)
	{
		var srtInfo = this.getSortFromRecord(record.data.ID);
		this.sortColumn = srtInfo.Sort;
		this.sortDirection = srtInfo.Dir;
		this.destroyTabPanel();
		this.showSearchResults(true);
	}
	this.destroyTabPanel = function()
	{
		this.ContColumn1.get(1).remove(this.searchResultsTabPanel,true);
	}
	this.refreshSelectAlls = function()
	{
		var ME = this;
		var f = function(cbs,pf)
		{
			var ctAll = true;
			for(var x=0;x<cbs.length;x++)
			{
				var isChecked = cbs[x].getValue();
				if(!isChecked)
				{
					ctAll = false;
					break;
				}
			}
			var ctCB = Ext.getCmp(ME.refineWidgetId + '-' + pf + 'SelectAll');
			if(ctAll)
			{
				ctCB.suspendEvents(false);
				ctCB.setValue(true);
				ctCB.resumeEvents();
				if(!$KB.isNull(ctCB.wrap)) ctCB.wrap.child('.x-form-cb-label').update($KB.LZ('Deselect_All', 'Deselect All'));
			}
			else
			{
				ctCB.suspendEvents(false);
				ctCB.setValue(false);
				ctCB.resumeEvents();
				if(!$KB.isNull(ctCB.wrap)) ctCB.wrap.child('.x-form-cb-label').update('Select All');
			}
		}
		
		f(this.contentTypeCheckboxes,'CT');
		f(this.categoryCheckbox,'Category');
		f(this.formatCheckbox,'Format');
		f(this.kbCheckbox,'KB');
		f(this.attCheckbox,'Att');
	}
	this.getRefineCheckBox = function(cbID, label, checkVariable, unchecked,isRemote)
	{
		isRemote = $KB.FixNull(isRemote,false);
		var thisObject = this;
		var cb = new Ext.form.Checkbox
		({
			id: cbID,
			boxLabel: label,
			hideLabel: true,
			tag: checkVariable,
			checked: !unchecked,
			listeners:
			{
				check: function(cb, checked) { thisObject.searchFilter[checkVariable] = checked; thisObject.refineSearchRefresh(); thisObject.refreshSelectAlls(); }
			}
		});
		return cb;
	}
	this.refineSearch = function(loadLast)
	{
		var loadLast = $KB.FixNull(loadLast,false);
		var lastVariables = [];
		//this is used to check whether a checkbox should be checked from previous search (Search within)
		function isUnchecked(id)
		{
			if(loadLast)
			{
				for(var i=0;i<lastVariables.length;i++)
				{
					if(lastVariables[i] == id) return true;
				}
			}
			return false;
		}
		if(loadLast)
		{
			var bbPos = 0;
			for(var bb = 0;bb<this.refineCheckboxes.length;bb++)
			{
				if(!this.refineCheckboxes[bb].checked)
				{
					lastVariables[bbPos] = this.refineCheckboxes[bb].id;
					bbPos++;
				}
			}
		}
		var oldData = $KB.DestroyWidget(this.refineWidgetId);
		var cbs = [];
		var pos = 0;
		var thisObject = this;
		this.refineCheckboxes = [];

		cbs[0] = new Ext.form.Checkbox
		({
			id: this.refineWidgetId + '-CTSelectAll',
			boxLabel: $KB.LZ('Deselect_All', 'Deselect All'),
			hideLabel: true,
			checked: true,
			itemCls:'SD_refineSearchSelectAll',
			listeners:
			{
				check: function(cb, checked)
				{ 
					for(var v in thisObject.searchFilter)
					{
						thisObject.searchFilter[v] = checked;
					}
					for(var x=0;x<thisObject.contentTypeCheckboxes.length;x++)
					{
						thisObject.contentTypeCheckboxes[x].suspendEvents(false);
						thisObject.contentTypeCheckboxes[x].setValue(checked);
						thisObject.contentTypeCheckboxes[x].resumeEvents();
					}
					thisObject.refineSearchRefresh();
					thisObject.refreshSelectAlls();
				}
			}
		});
		var refineCheckboxPos = 0;
		this.contentTypeCheckboxes = [];
		pos++;
		if(this.searchResult[0].ArticleCount>0)
		{
			var cbId = this.refineWidgetId + '-ArticlesCheck';
			cbs[pos] = this.getRefineCheckBox(cbId,$KB.LZ('Search_Refine_Articles', 'Articles ({0})',[this.searchResult[0].ArticleCount]),'ArticlesChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		if(this.searchResult[0].FAQCount>0)
		{
			var cbId = this.refineWidgetId + '-FAQsCheck';
			cbs[pos] = this.getRefineCheckBox(this.refineWidgetId + '-FAQsCheck',$KB.LZ('Search_Refine_FAQs', 'FAQs ({0})',[this.searchResult[0].FAQCount]),'FAQsChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		if(this.searchResult[0].ForumCount>0)
		{
			var cbId = this.refineWidgetId + '-ForumsCheck';
			cbs[pos] = this.getRefineCheckBox(this.refineWidgetId + '-ForumsCheck',$KB.LZ('Search_Refine_Forums', 'Forums ({0})',[this.searchResult[0].ForumCount]),'ForumsChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		if(this.searchResult[0].WikiCount>0)
		{
			var cbId = this.refineWidgetId + '-WikisCheck';
			cbs[pos] = this.getRefineCheckBox(this.refineWidgetId + '-WikisCheck',$KB.LZ('Search_Refine_Wikis', 'Wikis ({0})',[this.searchResult[0].WikiCount]),'WikisChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		if(this.searchResult[0].SFCount>0)
		{
			var cbId = this.refineWidgetId + '-SFCheck';
			cbs[pos] = this.getRefineCheckBox(this.refineWidgetId + '-SFCheck',$KB.LZ('Search_Refine_SF', 'Solution Finder ({0})',[this.searchResult[0].SFCount]),'SFChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		if(this.searchResult[0].GlossaryCount>0)
		{
			var cbId = this.refineWidgetId + '-GlossaryCheck';
			cbs[pos] = this.getRefineCheckBox(this.refineWidgetId + '-GlossaryCheck',$KB.LZ('Search_Refine_Glossary', 'Glossary ({0})',[this.searchResult[0].GlossaryCount]),'GlossaryChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		if(this.searchResult[0].RSCount>0)
		{
			var cbId = this.refineWidgetId + '-RSCheck';
			cbs[pos] = this.getRefineCheckBox(this.refineWidgetId + '-RSCheck',$KB.LZ('Search_Refine_RS', 'Remote Sites ({0})',[this.searchResult[0].RSCount]),'RSChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		if(this.searchResult[0].RFSCount>0)
		{
			var cbId = this.refineWidgetId + '-RFSCheck';
			cbs[pos] = this.getRefineCheckBox(this.refineWidgetId + '-RFSCheck',$KB.LZ('Search_Refine_RF', 'Remote Files ({0})',[this.searchResult[0].RFSCount]),'RFSChecked',isUnchecked(cbId));
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
		}
		var rdbPos =0;
		for(var rdbItem in this.remoteDBCounts)
		{
			var dta = this.remoteDBCounts[rdbItem];
			var cbId = this.refineWidgetId + '-RDBCheck' + rdbPos.toString();
			var unckd = isUnchecked(cbId);
			var sf = 'RDB-' + rdbItem.toString();
			this.searchFilter[sf] = !unckd;
			cbs[pos] = this.getRefineCheckBox(cbId,dta.Key + '(' + dta.Value.toString() + ')',sf,unckd,true);
			this.refineCheckboxes[refineCheckboxPos] = cbs[pos];
			this.contentTypeCheckboxes[refineCheckboxPos] = cbs[pos];
			pos++; refineCheckboxPos++;
			rdbPos++;
		}
		var panels = [];
		panels[0] = new Ext.BoxComponent({height:7});
		var clpsd =  !$KB.GlobalData.PortalProperties.SearchFilterExpanded;
		panels[1] = new Ext.form.FieldSet
		({
			autoHeight: true,
			autoWidth: true,
			style: 'padding-left: 7px;',
			title: $KB.LZ('Search_Content_Types', 'Content Types'),
			collapsed:clpsd,
			collapsible: true,
			hidden:(cbs.length<2),
			items: cbs
		});
		var catSelectAll = new Ext.form.Checkbox
		({
			id: this.refineWidgetId + '-CategorySelectAll',
			boxLabel: $KB.LZ('Deselect_All', 'Deselect All'),
			hideLabel: true,
			checked: true,
			itemCls:'SD_refineSearchSelectAll',
			listeners:
			{
				check: function(cb, checked)
				{ 
					for(var x=0;x<thisObject.categoryCheckbox.length;x++)
					{
						thisObject.categoryCheckbox[x].suspendEvents(false);
						thisObject.categoryCheckbox[x].setValue(checked);
						thisObject.categoryCheckbox[x].resumeEvents();
					}
					thisObject.refineSearchRefresh();
					thisObject.refreshSelectAlls();
				}
			}
		});
		this.categoryCheckbox = [];
		var catPos = 0;
		for(var v in this.searchResult[1])
		{
			var cbId = this.refineWidgetId + 'categoryCB' + catPos.toString();
			var vv = v;
			var cbstyle = '';
			if(v == '') {
				vv = $KB.LZ('No_Category', '[No Category]');
				cbstyle = 'font-weight: bold; ';
			}
			var txt = vv + ' (' + this.searchResult[1][v] + ')';
			this.categoryCheckbox[catPos] = new Ext.form.Checkbox
			({
				boxLabel: txt,
				checked: !isUnchecked(cbId),
				id:cbId,
				hideLabel: true,
				tag: v == '' ? '**none**' : v,
				style: cbstyle,
				listeners:
				{
					check: function(cb, checked) { thisObject.refineSearchRefresh(); thisObject.refreshSelectAlls(); }
				}
			});
			this.refineCheckboxes[refineCheckboxPos] = this.categoryCheckbox[catPos];
			catPos++; refineCheckboxPos++;
		}
		var formatSelectAll = new Ext.form.Checkbox
		({
			id: this.refineWidgetId + '-FormatSelectAll',
			boxLabel: $KB.LZ('Deselect_All', 'Deselect All'),
			hideLabel: true,
			checked: true,
			itemCls:'SD_refineSearchSelectAll',
			listeners:
			{
				check: function(cb, checked)
				{ 
					for(var x=0;x<thisObject.formatCheckbox.length;x++)
					{
						thisObject.formatCheckbox[x].suspendEvents(false);
						thisObject.formatCheckbox[x].setValue(checked);
						thisObject.formatCheckbox[x].resumeEvents();
					}
					thisObject.refineSearchRefresh();
					thisObject.refreshSelectAlls();
				}
			}
		});
		this.formatCheckbox = [];
		var formatPos = 0;
		for(var v in this.searchResult[2])
		{
			var cbId = this.refineWidgetId + 'formatCB' + formatPos.toString();
			var vv = v;
			var cbstyle = '';
			if(v == '') {
				vv = $KB.LZ('No_File_Ext', '[No File Extension]');
				cbstyle = 'font-weight: bold; ';
			}
			var txt = vv + ' (' + this.searchResult[2][v] + ')';
			this.formatCheckbox[formatPos] = new Ext.form.Checkbox
			({
				id:cbId,
				boxLabel: txt,
				checked: !isUnchecked(cbId),
				hideLabel: true,
				tag: v == '' ? '**none**' : v,
				style: cbstyle,
				listeners:
				{
					check: function(cb, checked) { thisObject.refineSearchRefresh(); thisObject.refreshSelectAlls(); }
				}
			});
			this.refineCheckboxes[refineCheckboxPos] = this.formatCheckbox[formatPos];
			formatPos++; refineCheckboxPos++;
		}
		var kbSelectAll = new Ext.form.Checkbox
		({
			id: this.refineWidgetId + '-KBSelectAll',
			boxLabel: $KB.LZ('Deselect_All', 'Deselect All'),
			hideLabel: true,
			checked: true,
			itemCls:'SD_refineSearchSelectAll',
			listeners:
			{
				check: function(cb, checked)
				{ 
					for(var x=0;x<thisObject.kbCheckbox.length;x++)
					{
						thisObject.kbCheckbox[x].suspendEvents(false);
						thisObject.kbCheckbox[x].setValue(checked);
						thisObject.kbCheckbox[x].resumeEvents();
					}
					thisObject.refineSearchRefresh();
					thisObject.refreshSelectAlls();
				}
			}
		});		
		this.kbCheckbox = [];
		var kbPos = 0;
		for(var v in this.kbCounts)
		{
			var dta = this.kbCounts[v];
			var cbId = this.refineWidgetId + 'kbCB' + kbPos.toString();
			var txt = dta.Key + ' (' + dta.Value + ')';
			this.kbCheckbox[kbPos] = new Ext.form.Checkbox
			({
				boxLabel: txt,
				checked: !isUnchecked(cbId),
				id:cbId,
				hideLabel: true,
				tag: v,
				listeners:
				{
					check: function(cb, checked) { thisObject.refineSearchRefresh(); thisObject.refreshSelectAlls(); }
				}
			});
			this.refineCheckboxes[refineCheckboxPos] = this.kbCheckbox[kbPos];
			kbPos++; refineCheckboxPos++;
		}
		
		var attSelectAll = new Ext.form.Checkbox
		({
			id: this.refineWidgetId + '-AttSelectAll',
			boxLabel: $KB.LZ('Deselect_All', 'Deselect All'),
			hideLabel: true,
			checked: true,
			itemCls:'SD_refineSearchSelectAll',
			listeners:
			{
				check: function(cb, checked)
				{ 
					for(var x=0;x<thisObject.attCheckbox.length;x++)
					{
						thisObject.attCheckbox[x].suspendEvents(false);
						thisObject.attCheckbox[x].setValue(checked);
						thisObject.attCheckbox[x].resumeEvents();
					}
					thisObject.refineSearchRefresh();
					thisObject.refreshSelectAlls();
				}
			}
		});
		this.attCheckbox = [];
		var attPos = 0;
		for(var v in this.attributeCounts)
		{
			var dta = this.attributeCounts[v];
			var cbId = this.refineWidgetId + 'attCB' + attPos.toString();
			var txt = (dta.Key == '' ? $KB.LZ('No_Attribute', $KB.LZ('None', '[none]')) : dta.Key) + ' (' + dta.Value + ')';
			this.attCheckbox[attPos] = new Ext.form.Checkbox
			({
				boxLabel: txt,
				checked: !isUnchecked(cbId),
				id:cbId,
				hideLabel: true,
				tag: v == '-1' ? '**none**' : v,
				listeners:
				{
					check: function(cb, checked) { thisObject.refineSearchRefresh(); thisObject.refreshSelectAlls(); }
				}
			});
			this.refineCheckboxes[refineCheckboxPos] = this.attCheckbox[attPos];
			attPos++; refineCheckboxPos++;
		}
		
		panels[2] = new Ext.form.FieldSet
		({
			autoHeight: true,
			autoWidth: true,
			style: 'padding-left: 7px; ',
			title: $KB.LZ('KBs', 'KBs'),
			collapsed: clpsd,
			collapsible: true,
			hidden:(this.kbCheckbox.length==0),
			items: [kbSelectAll, this.kbCheckbox]
		});
		panels[3] = new Ext.form.FieldSet
		({
			autoHeight: true,
			autoWidth: true,
			style: 'padding-left: 7px; ',
			title: $KB.LZ('Art_Cats', 'Article Categories'),
			collapsed: clpsd,
			collapsible: true,
			hidden:(this.categoryCheckbox.length==0),
			items: [catSelectAll, this.categoryCheckbox]
		});
		panels[4] = new Ext.form.FieldSet
		({
			autoHeight: true,
			autoWidth: true,
			style: 'padding-left: 7px; ',
			title: $KB.LZ('Attributes', 'Attributes'),
			collapsed: clpsd,
			collapsible: true,
			hidden:(this.attCheckbox.length==0),
			items: [attSelectAll, this.attCheckbox]
		});
		panels[5] = new Ext.form.FieldSet
		({
			autoHeight: true,
			autoWidth: true,
			style: 'padding-left: 7px; ',
			title: $KB.LZ('Formats', 'Formats'),
			collapsed: clpsd,
			collapsible: true,
			hidden:(this.formatCheckbox.length==0),
			items: [formatSelectAll, this.formatCheckbox]
		});
		this.refineSearchWidget = new Ext.ux.Portlet
		(
			{
				title: 'Refine ' + this.mainTabTitle,
				id: this.refineWidgetId,
				items: panels,
				autoHeight: true,
				autoWidth: true,
				border:false,
				frame:false,
				bodyStyle:'background-color:transparent;',
				draggable:false
			}
		);

		var rwCont;
		if(oldData.Existed)
		{
			rwCont = Ext.getCmp(oldData.OwnerId);
			rwCont.insert(oldData.Index, this.refineSearchWidget);
		}
		else 
		{
			var rwCont = Ext.getCmp(this.refineWidgetParentId);
			rwCont.insert(this.refineWidgetIndex, this.refineSearchWidget);
		}
		
		rwCont.doLayout(false,true);
		
		if(lastVariables.length>0)
		{
			this.refineSearchRefresh();
			this.refreshSelectAlls();
		}
	}
	this.getParameterString = function(record)
	{
		return $KB.buildParams
		(
			record,
			[
				'ItemType','ArticleID','CategoryId','SFID','SFCID','FAQID','GlossaryID','TermID','PostID','ThreadID',
				'ForumID','FilePath','URL','Identity','db','DBId','QueryId','Metadata','Title','DocID',
				'GlossaryTermID','DB','ContentType'
			],
			function (key, v)
			{
				switch (key)
				{
					case 'Metadata': case 'Title':
						v = $KB.replaceAll(v);
						break;
				}
				return v;
			}
		);
	}
	this.getSearchResultRowPanel = function(record)
	{
		var imageCode = '';
		var imageTitle = '';
		var showMetadata = true;
		var showMeta1 = true;
		var showMeta2 = false;
		var showRDBMeta = false;
		var isArticle = false;
		var isWikiTag = (this.itemTypeFilter.toLowerCase() == 'wikitag');
		switch(record.ItemType.toLowerCase())
		{
			case 'wiki': imageCode = 'icon_wiki'; imageTitle = 'Wiki'; break;
			case 'article': imageCode = 'icon_article'; imageTitle = $KB.LZ('Article', 'Article'); isArticle = true; break;
			case 'glossary': imageCode = 'icon_glossary'; imageTitle = 'Glossary Term'; showMeta1 = false; showMeta2 = true; break;
			case 'faq': imageCode = 'icon_faq'; imageTitle = 'Frequently Asked Question'; break;
			case 'sf': imageCode = 'icon_solutionfinder'; imageTitle = $KB.LZ('SF', 'Solution Finder'); showMeta1 = false; showMeta2 = true; break;
			case 'forum': imageCode = 'icon_forum'; imageTitle = 'Forum Post'; showMeta1 = false; showMeta2 = true; break;
			case 'rs': imageCode = 'icon_remotesite'; imageTitle = 'Remote Site'; showMetadata = false; showMeta1 = false; break;
			case 'rfs': imageCode = 'icon_remotefilesystem'; imageTitle = 'Remote File System'; showMetadata = false; showMeta1 = false; break;
			case 'rdb': imageCode = 'icon_remotedb'; imageTitle = $KB.LZ('RemoteDB', 'Remote DataBase'); showMeta1 = false; showRDBMeta = true; break;
		}
		if(!$KB.GlobalData.SearchResultDisplay.IconExtension)
		{
			imageCode = '';
			imageTitle = '';
		}
		else if(isArticle)
		{
			var formatCode = $KB.GetExtensionIconClass(record.FileExt);
			var ic = $KB.GetExtensionTitle(record.FileExt);
			if(formatCode != '') imageCode = formatCode;
			if(ic != '') imageTitle = ic;
		}
		var clickEvent = '';
		if (this.onItemClick != null)
		{
			var rps = this.getParameterString(record);
			$KB['searchResults' + this.tabPanelId] = this;
			clickEvent = ' onclick="$KB.searchResults' + this.tabPanelId + '.titleClicked(' + rps + ')"';
		}
		var str = '<span class="SD_lblLeft">From</span>' + $KB.escTag(record.From);
		if(showMetadata)
		{
			if (showMeta1)
			{
				str = str +
					( (isArticle && $KB.GlobalData.SearchResultDisplay.ArticleID) ? '<span class="SD_lbl">' + $KB.LZ('ArticleId', 'Article Id') + '</span>' + record.ArticleID : '') +
					($KB.GlobalData.SearchResultDisplay.DateCreated ? '<span style="white-space: nowrap;"><span class="SD_lbl">' + $KB.LZ('Modified', 'Modified') + '</span>' + record.DateModified + '</span>' : '') + 
					($KB.GlobalData.SearchResultDisplay.ArticleFileType ? '<span style="white-space: nowrap;"><span class="SD_lbl">' + $KB.LZ('Format', 'Format') + '</span>' + record.FileExt + '</span>' : '') + 
					( (isArticle && $KB.GlobalData.SearchResultDisplay.KnowledgeBase && ($KB.escTag(record.KBs) != '')) ? '<span style="white-space: nowrap;"><span class="SD_lbl">' + $KB.LZ('Knowledge_base', 'Knowledge base') + '</span>' + $KB.escTag(record.KBs) + '</span>' : '') + 
					( (isArticle && $KB.GlobalData.SearchResultDisplay.ArticleAttribute && ($KB.escTag(record.Attributes) != '')) ? '<span class="SD_lbl">' + $KB.LZ('Attributes', 'Attributes') + '</span>' + $KB.escTag(record.Attributes) : '') + 
					( ($KB.GlobalData.SearchResultDisplay.ArticleSize && (!isWikiTag) ) ? '<span style="white-space: nowrap;"><span class="SD_lbl">' + $KB.LZ('Size', 'Size') + '</span>' + record.Filesize + ' kb</span>' : '');
			}
			if(showMeta2)
			{
				str = str + ($KB.GlobalData.SearchResultDisplay.DateCreated ? '<span style="white-space: nowrap;"><span class="SD_lbl">' + $KB.LZ('Modified', 'Modified') + '</span>' + record.DateModified + '</span>' : '') +
					($KB.GlobalData.SearchResultDisplay.ArticleFileType ? '<span style="white-space: nowrap;"><span class="SD_lbl">' + $KB.LZ('Format', 'Format') + '</span>' + record.FileExt + '</span>' : '');
			}
			if (showRDBMeta)
			{
				str = str + record.Metadata;
			}
		}
		var showSummary = isWikiTag ? false : $KB.GlobalData.SearchResultDisplay.Summarization;
		var r = '<div class="SD_SearchItem">';
		if (imageCode != '') r = r + '<span title="' + $KB.escStr(imageTitle) + '" class="SD_icon ' + imageCode + '"></span>'
		r = r + '<p class="SD_SearchResultTitle">' +
					( ($KB.GlobalData.SearchResultDisplay.Relevance && (!isWikiTag) ) ? '<span class="SD_relevance">' + record.Rank + '%</span>' : '') +
					'<span class="SD_SearchResultTitle" ' + $KB.BuildMouseOver() + '><span class="SD_ArticleAnchor" ' + clickEvent + '">' + $KB.escTag(record.Title) + '</span></span><span class="SD_ArticleAlert">  ' + record.Alert + '</span>' +
					'</p>' +
					$KB.PadIfNotNull('<p class="SD_SearchResultMetadata">', str, '</p>') +
					(showSummary ? $KB.PadIfNotNull('<p class="SD_SearchResultDescription">', Ext.util.Format.trim($KB.escTag(record.Description)), '</p>') : '') +
				'</div>';
		return r;
	}
	this.titleClicked = function(record)
	{
		var src = record.ItemType.toLowerCase();
		if(src == 'sf')
		{
			var url = location.protocol + '//' + location.host + '?SFId=' + record.SFId + '&SFCId=' + record.SFCId;
			if(this.isSnapIn) window.open(url);
			else $KB.open({ SFCId: record.SFCId, SFId: record.SFId, SearchId: this.searchId });
		}
		else
		{
			if ( (this.lastArticlesData != null) && (src=='article') ) this.lastArticlesData[this.lastArticlesData.length] = record;
			record.SearchString = escape(this.searchText);
			record.SearchId = this.searchId;
			$KB['searchTitleClick' + this.tabPanelId](record);
		}
	}
	this.addSearchResultPagingControl = function(tab, panel, Fn)
	{
		var thisObject = this;
		panel.removeAll();
		var cont = new Ext.Container
		(
			{
				layout:'anchor',
				anchor:'0 0',
				items:
				[
					{
						xtype:'container',
						height:25
					},
					{
						xtype:'container',
						style:'overflow:auto;',
						anchor:'0 -25'
					}
				]
			}
		);		
		
		var params = { start: 0, limit: this.advanced.ResultsPerPage, sort: this.sortColumn, dir: this.sortDirection, tabName: tab, sessionName: this.sessionVariableName };
		if(!thisObject.doEmptySearch)
		{
			var store = new Ext.data.DirectStore
			({
				directFn: Fn,
				paramsAsHash: false,
				paramOrder: 'start,limit,sort,dir,tabName,sessionName',
				baseParams: params,
				idProperty: 'UniqueID',
				totalProperty: 'Count',
				root: 'Items',
				autoLoad: {params:params},
				remoteSort:true,
				fields:
				[
					{name: 'UniqueID', type: 'string'},
					{name: 'TabName', type: 'string'},
					{name: 'ItemType', type: 'string'},
					{name: 'Description', type: 'string'},
					{name: 'Filesize', type: 'string'},
					{name: 'Rank', type: 'string'},
					{name: 'Format', type: 'string'},
					{name: 'FileExt', type: 'string'},
					{name: 'Title', type: 'string'},
					{name: 'ArticleID', type: 'string'},
					{name: 'DateModified', type: 'string'},
					{name: 'FileExt', type: 'string'},
					{name: 'Format', type: 'string'},
					{name: 'Category', type: 'string'},
					{name: 'From', type: 'string'},
					{name: 'FAQID', type: 'string'},
					{name: 'GlossaryID', type: 'string'},
					{name: 'GlossaryTermID', type: 'string'},
					{name: 'PostID', type: 'string'},
					{name: 'ForumID', type: 'string'},
					{name: 'ThreadID', type: 'string'},
					{name: 'SFID', type: 'string'},	
					{name: 'SFCID', type: 'string'},	
					{name: 'FilePath', type: 'string'}
				],
				listeners:
				{
					load: function(s,records) {
						{
							if(typeof(cont.get(1)) == "undefined") return;
							var pctb = Ext.getCmp(thisObject.tabPanelId + "pagingControl-" + tab);
							if(!$KB.isNull(pctb.refresh))
							{
								pctb.refresh.hide();
							}
							cont.get(1).removeAll(true);
							var items = [];
							for (var i = 0; i<records.length; i++)
							{
								items.push(thisObject.getSearchResultRowPanel(records[i].json));
							}
							var itemPanel = new Ext.Container
							(
								{
									anchor: '0 0',
									autoScroll: true,
									autoEl: { tag: 'div', html: items.join("") }
								}
							);
							cont.get(1).add(itemPanel);
							try
							{
								panel.doLayout();
							}
							catch(err){}
						}
					}
				}
			});
		}
		var itms = [];
		if(!thisObject.doEmptySearch && this.showSort)
		{
			var cb = {
				xtype:'combo',
				emptyText: $KB.LZ('Search_Sort_By', 'Sort By'),
				mode: 'local',
				minListWidth: 100,
				width: 100,
				forceSelection: true,
				editable: false,
				triggerAction: 'all',
				store: new Ext.data.ArrayStore({
					idIndex: 0,
					fields: [
						'ID',
						'Text'
					],
					data: [ [1, $KB.LZ('Search_Sort_Relevance', 'Relevance')], [2, $KB.LZ('Search_Sort_Title', 'Title')], [3, $KB.LZ('Search_Sort_Mod', 'Modified Date')], [4, $KB.LZ('Search_Sort_Created', 'Created Date')] ]
				}),
				value: this.sortVal,
				valueField: 'ID',
				displayField: 'Text',
				listeners:
				{
					select: function(combo, record, index)
					{
						var srtInfo = thisObject.getSortFromRecord(record.data.ID);
						thisObject.sortColumn = srtInfo.Sort;
						thisObject.sortDirection = srtInfo.Dir;
						thisObject.sortVal = record.data.ID;
						var lastOptions = store.lastOptions;
						Ext.apply(lastOptions.params, {
							start: 0,
							sort: srtInfo.Sort,
							dir: srtInfo.Dir
						});
						store.baseParams = lastOptions.params;
						store.reload(lastOptions);
					},
					afterrender:function(fld)
					{
						if(Ext.isWebKit && Ext.version < '4')
						{
							fld.el.dom.parentNode.style.width = '100px';
							fld.el.dom.style.height = '21px';
							fld.el.dom.nextSibling.style.height = '21px';
						}
					}
				}
			};
			itms[0] = cb;
		}		
		var p = new Ext.ux.PagingToolbar
		(
			{
				id:this.tabPanelId + "pagingControl-" + tab,
				displayInfo: true,
				pageSize: this.advanced.ResultsPerPage,
				items: itms
			}
		);
		cont.get(0).add(p);
		panel.add(cont);
		if(!thisObject.doEmptySearch) p.bindStore(store, true);
	}
	this.getSearchResultTab = function(tabName, tabIndex)
	{
		var total = this.searchResult[0].TotalCount;
		var title = '';
		var Fn = DirectRequest.GetSearchResultItems;
		switch(tabName)
		{
			case 'All':
				title = this.mainTabTitle + '&nbsp;<span class="SD_TabNum">' + this.searchResult[0].TotalCount + '</span>';
				break;
			case 'Wiki':
				total = this.searchResult[0].WikiCount;
				title = $KB.LZ('Search_In_Wikis', 'In Wikis') + '&nbsp;<span class="SD_TabNum">' +  total + '</span>';
				break;
			case 'Forum':
				total = this.searchResult[0].ForumCount;
				title = $KB.LZ('Search_In_Forums', 'In Forums') + '&nbsp;<span class="SD_TabNum">' + total + '</span>';
				break;
			case 'Other':
				total = this.searchResult[0].OtherCount;
				title = $KB.LZ('Search_From_Other', 'From Other Sources') + '&nbsp;<span class="SD_TabNum">' + total  + '</span>';
				break;
		}
		var p = new Ext.Panel
		({
			title: title,
			id: this.tabPanelId + 'Tab' + tabIndex,
			plain:true,
			border: false,
			hideBorders: true,
			header: this.showTabs,
			bodyStyle:'background-color:transparent;',
			style: 'padding: 5px; ',
			anchor: '0 0',
			layout: 'anchor'
		});
		this.addSearchResultPagingControl(tabName, p, Fn);
		return p;
	}
	this.getCategoriesFilter = function()
	{
		var s = '';
		var all = true;
		var none = true;
		var first = true;
		for(var i = 0; i<this.categoryCheckbox.length; i++)
		{
			if(this.categoryCheckbox[i].getValue())
			{
				s = s + (first ? '' : ',') + this.categoryCheckbox[i].tag;
				first = false;
				none = false;
			}
			else all = false;
		}
		if(all) return '***all';
		if(none) return '***none';
		return s;
	}
	this.getFormatFilter = function()
	{
		var s = '';
		var all = true;
		var none = true;
		var first = true;
		for(var i = 0; i<this.formatCheckbox.length; i++)
		{
			if(this.formatCheckbox[i].getValue())
			{
				s = s + (first ? '' : ',') + this.formatCheckbox[i].tag;
				first = false;
				none = false;
			}
			else all = false;
		}
		if(all) return '***all';
		if(none) return '***none';
		return s;
	}
	this.getFilter = function(cbs)
	{
		var s = '';
		var all = true;
		var none = true;
		var first = true;
		for(var i = 0; i<cbs.length; i++)
		{
			if(cbs[i].getValue())
			{
				s = s + (first ? '' : ',') + cbs[i].tag;
				first = false;
				none = false;
			}
			else all = false;
		}
		if(all) return '***all';
		if(none) return '***none';
		return s;
	}
	this.getRDBFilter = function()
	{
		var s = '';
		var all = true;
		var none = true;
		var first = true;
		var i=0;
		for(var vl in this.searchFilter)
		{
			if(vl.substr(0,4) == 'RDB-')
			{
				var id = vl.substr(4);
				for(var pp =0;pp<this.contentTypeCheckboxes.length;pp++)
				{
					if(this.contentTypeCheckboxes[pp].tag == vl)
					{
						if(this.contentTypeCheckboxes[pp].getValue())
						{
							s = s + (first ? '' : ',') + id;
							first = false;
							none = false;
						}
						else all = false;
					}
				}
			}
		}
		if(all) return '***all';
		if(none) return '***none';
		return s;
	}
	this.setRefineCheckboxesState = function(prms)
	{
		var disabled = $KB.FixNull(prms.Disabled,false);
		Ext.getCmp(this.refineWidgetId + '-CTSelectAll').setDisabled(disabled);
		Ext.getCmp(this.refineWidgetId + '-CategorySelectAll').setDisabled(disabled);
		Ext.getCmp(this.refineWidgetId + '-FormatSelectAll').setDisabled(disabled);
		for(var i=0;i<this.refineCheckboxes.length;i++)
		{
			this.refineCheckboxes[i].setDisabled(disabled);
		}
	}
	this.refineSearchRefresh = function()
	{
		this.setRefineCheckboxesState({Disabled:true});
		var thisObject = this;
		this.oldFilters = {};
		this.oldFilters.ArticlesChecked = this.searchFilter.ArticlesChecked ? 1 : 0;
		this.oldFilters.FAQsChecked = this.searchFilter.FAQsChecked ? 1 : 0;
		this.oldFilters.ForumsChecked = this.searchFilter.ForumsChecked ? 1 : 0;
		this.oldFilters.WikisChecked = this.searchFilter.WikisChecked ? 1 : 0;
		this.oldFilters.GlossaryChecked = this.searchFilter.GlossaryChecked ? 1 : 0;
		this.oldFilters.SFChecked = this.searchFilter.SFChecked ? 1 : 0;
		this.oldFilters.RSChecked = this.searchFilter.RSChecked ? 1 : 0;
		this.oldFilters.RFSChecked = this.searchFilter.RFSChecked ? 1 : 0;
		this.oldFilters.RDBChecked = this.searchFilter.RDBChecked ? 1 : 0;
		this.oldFilters.Categories = this.getCategoriesFilter();
		this.oldFilters.Formats = this.getFormatFilter();
		this.oldFilters.RDBs = this.getRDBFilter();
		this.oldFilters.KBs = this.getFilter(this.kbCheckbox);
		this.oldFilters.Atts = this.getFilter(this.attCheckbox);
		
		DirectRequest.GetRefinedSearchResults(
			this.oldFilters.ArticlesChecked,
			this.oldFilters.FAQsChecked,
			this.oldFilters.ForumsChecked,
			this.oldFilters.WikisChecked,
			this.oldFilters.GlossaryChecked,
			this.oldFilters.SFChecked,
			this.oldFilters.RSChecked,
			this.oldFilters.RFSChecked,
			this.oldFilters.RDBChecked,
			this.oldFilters.Categories,
			this.oldFilters.Formats,
			this.oldFilters.RDBs,
			this.oldFilters.KBs,
			this.oldFilters.Atts,
			this.sessionVariableName,
			function(result, response)
			{
				var Fn = DirectRequest.GetSearchResultItems;
				thisObject.searchResult = result;
				thisObject.searchResultsTabPanel.remove(Ext.getCmp(thisObject.tabPanelId + 'Tab0'), true);
				var p = new Ext.Panel
					({
						title: thisObject.mainTabTitle + ' (' + result[0].TotalCount + ')',
						id: thisObject.tabPanelId + 'Tab0',
						plain:true,
						border: false,
						hideBorders: true,
						header: thisObject.showTabs,
						style: 'padding: 5px; ',
						anchor: '0 0',
						layout: 'anchor'
					});
				thisObject.addSearchResultPagingControl('All', p, Fn);
				thisObject.searchResultsTabPanel.insert(0, p);
				if(thisObject.showTabs) thisObject.searchResultsTabPanel.setActiveTab(0);
				thisObject.searchResultsTabPanel.doLayout(false, true);
				thisObject.setRefineCheckboxesState.defer(500, thisObject,[{Disabled:false}]);
		});
	}
	//public methods
	this.DestroyObjects = function()
	{
		this.displayContainer.remove(this.MainCont,true);
		var oldData = $KB.DestroyWidget(this.refineWidgetId);
		var r = {
			'WidgetExisted' : oldData.Existed,
			'WidgetOwnerId' : oldData.OwnerId,
			'WidgetIndex' : oldData.Index
		}
		return r;
	}
	this.HideRefineWidget = function()
	{
		if(this.showRefineWidget)
		{
			Ext.getCmp(this.refineWidgetId).hide();
		}
	}
	this.ShowRefineWidget = function()
	{
		if(this.showRefineWidget)
		{
			Ext.getCmp(this.refineWidgetId).show();
		}
	}
	//initiate the object
	this.init({SearchWithin: false, SearchWithinText: ''});
}
$KB.ButtonList = function(params)
{
	this.id = params.id;
	$KB['buttonList' + this.id] = this;
	this.ButtonLabel = $KB.FixNull(params.ButtonLabel,$KB.LZ('Forum_Tags', 'Tags'));
	this.isForum = $KB.FixNull(params.isForum, false);
	this.Cls = $KB.FixNull(params.Cls,'');
	this.Post = $KB.FixNull(params.Post, 0);
	this.useFileUpload = $KB.FixNull(params.useFileUpload,false);
	this.allowAdd = $KB.FixNull(params.AllowAdd,false);
	this.allowDelete = $KB.FixNull(params.AllowDelete,false);
	this.addFunction = $KB.FixNull(params.AddFunction,null);
	this.deleteFunction = $KB.FixNull(params.DeleteFunction,null);
	this.areLinks = $KB.FixNull(params.areLinks,false);
	this.linkIsFunction = $KB.FixNull(params.linkIsFunction,true);
	this.title = $KB.FixNull(params.Title, '');
	this.items = $KB.FixNull(params.Items,[]);
	var me = this;
	this.init = function()
	{
		var owner = null;
		if(Ext.isDefined(this.cont))
		{
			owner = this.cont.ownerCt;
			if(owner != null)
			{
				owner.remove(this.cont,true);
			}
		}
		var itms = [];
		$KB.highlightFunc = this.highlight;
		$KB['tagDeleteFunc' + this.id] = this.remove;
		itms[0] =
		{
			xtype:'box',
			cls:'FL SD_ArtInfoLabel',
			autoEl:
			{
				autoWidth: true,
				autoHeight: true,
				tag:'div',
				html:me.ButtonLabel
			}
		};
		for(var i=0;i<this.items.length;i++)
		{
			var txt = $KB.FixNull(this.items[i].Text,'');
			var hrefs = '';
			var hrefe = '';
			if (this.areLinks != null && this.areLinks != false)
			{
				if (this.linkIsFunction)
				{
					hrefs = '<a href=\'javascript:' + $KB.FixNull(this.items[i].Link,'') + '\'>';
					hrefe = '</a>';
				} else
				{
					hrefs = '<a href=\'' + $KB.FixNull(this.items[i].Link,'') + '\'>';
					hrefe = '</a>';
				}
			}
			var htm = '<div id="' + this.id + 'Item' + i + '" onmouseover="$KB.highlightFunc(\''
			 + this.id + 'Item' + i + '\', \'' + this.id + 'X' + i + 
			 '\',true);" onmouseout="$KB.highlightFunc(\'' +
			  this.id + 'Item' + i + '\', \'' + this.id + 'X' + i +
			   '\',false);" class="FL SD_GenericTag TagNoLight"><div style="padding-right: 3px" class="FL SD_GenericTagLink" ' +
			   '>' + hrefs +  $KB.escTag(txt) + hrefe + '</div><div id="' + this.id + 'X' + i +
			     '" title="' + $KB.LZ('Delete', 'Delete') +
			      '" class="FL icon_x SD_WikiTagX" onclick="$KB.tagDeleteFunc' + this.id + '(\'' +
			       this.id + '\',' + i + ');"></div></div>';
			itms[i+1] =
			{
				xtype:'container',
				autoEl:
				{
					autoWidth: true,
					autoHeight: true,
					tag:'div',
					html:htm
				}
			};
		}
		if(this.allowAdd)
		{
			itms[itms.length] =
			{
				xtype:'box',
				cls:'FL SD_WikiTagAdd',
				id:this.id + 'addTag',
				autoEl:
				{
					autoWidth: true,
					tag:'div',
					html:'+'
				},
				listeners:
				{
					render:function(comp)
					{
						comp.el.on('click',function() {me.add(me.id);});
					}
				}
			};
		}
		this.cont = new Ext.Container
		(
			{
				id:this.id,
				cls:this.Cls,
				items:itms
			}
		);
		this.UIElement = this.cont;
		if(owner != null)
		{
			owner.add(this.cont);
			owner.doLayout(false,true);
			owner.doLayout(false,true);
		}
	}
	this.remove = function(id, index)
	{
		if(me.allowDelete)
		{
			if(me.deleteFunction != null)
			{
				me.deleteFunction(me, me.items[index].Id);
			}
		}
	}
	this.add = function(id)
	{
		var frm = new Ext.FormPanel
		(
			{
				labelAlign:'top',
				anchor:'0 0',
				bodyStyle:'background-color:transparent; padding:8px; ',
				frame:false,hideBorders:true,border:false,
				defaults:
				{
					labelSeparator:''
				},
				items:
				[
					{
						xtype:'textfield',fieldLabel:me.ButtonLabel,anchor:'100%',id:me.id+'tagName',
						enableKeyEvents:true,
						listeners:
						{
							keypress:function(tf,e)
							{
								if(e.keyCode == 13)
								{
									me.addTag();
								}
							}
						}
					}
				],
				buttons:
				[
					{
						xtype:'button',
						text:$KB.LZ('Wiki_Tag_Add', 'Add'),
						handler:function()
						{
							me.addTag();
						}
					},
					{
						xtype:'button',
						text:$KB.LZ('Cancel', 'Cancel'),
						handler:function() {Ext.getCmp(me.id + 'addTagWindow').close();}
					}
				]
			}
		);
		var frmUpload = new Ext.FormPanel
		(
			{
				id: 'uploadAttachment' + me.Post.toString(),
				labelAlign:'top',
				anchor:'0 0',
				fileUpload: true,
				waitTitle: 'Please wait for the file to upload...',
				headers: {'Content-type:':'multipart/form-data'},
				api: { submit: DirectRequest.AddPostAttachment },
				bodyStyle:'background-color:transparent; padding:8px; ',
				frame:false,hideBorders:true,border:false,
				defaults:
				{
					labelSeparator:''
				},
				items:
				[
					{
						xtype:'textfield',inputType: 'file',
						fieldLabel:me.ButtonLabel,anchor:'100%',id:me.id+'fileUpload',
						name: 'file',
						buttonText: '',
						enctype : 'multipart/form-data',
						enableKeyEvents:true,
						buttonCfg:
						{
							iconCls: 'upload-icon'
						},
						listeners:
						{
							keypress:function(tf,e)
							{
								if(e.keyCode == 13)
								{
									me.addTag(frmUpload);
								}
							}
						}
					},
					{ xtype: 'hidden', id: 'attachForumPost', name: 'PostId',  value: me.Post }
				],
				buttons:
				[
					{
						xtype:'button',
						text:$KB.LZ('Wiki_Tag_Add', 'Add'),
						handler:function()
						{
							me.addTag(frmUpload);
						}
					},
					{
						xtype:'button',
						text:$KB.LZ('Cancel', 'Cancel'),
						handler:function() {Ext.getCmp(me.id + 'addTagWindow').close();}
					}
				]
			}
		);
		var window = new Ext.Window
		(
			{
				title: this.useFileUpload ? 'Add New Attachment' : $KB.LZ('Wiki_Tag_Add_Title', 'Add New Tag'),
				width:300,
				height:120,
				modal:true,
				items: this.useFileUpload ? frmUpload : frm,
				layout:'anchor',
				id:me.id + 'addTagWindow'
			}
		);
		window.show();
		Ext.getCmp(me.id+'tagName').focus(true, true);
	}
	this.addTag = function(frm)
	{
		var tagName = Ext.getCmp(me.id+'tagName').getValue();
		if(me.addFunction != null)
		{
			me.addFunction(me, tagName, frm);
		}
	}
	this.highlight = function(contId, xId, val)
	{
		if(me.allowDelete)
		{
			var cont = document.getElementById(contId);
			var ele = document.getElementById(xId);
			if(val)
			{
				ele.style.visibility = 'visible';
				ele.style.marginLeft = 4;
				cont.style.paddingLeft = 3;
				cont.className = 'FL SD_GenericTag TagHighLight';
			}
			else
			{
				ele.style.visibility = 'hidden';
				cont.style.paddingLeft = 7;
				ele.style.marginLeft = 0;
				cont.className = 'FL SD_GenericTag TagNoLight';
			}
		}
	}
	this.AddButton = function(item)
	{
		var cnt = me.items.length;
		me.items[cnt] = item;
		me.init();
	}
	this.SetItems = function(items)
	{
		this.items = items;
		this.init();
	}
	this.RemoveButton = function(id)
	{
		var cnt = this.items.length;
		var newItems = [];
		var pos = 0;
		for(var i=0;i<cnt;i++)
		{
			if(this.items[i].Id != id)
			{
				newItems[pos] = this.items[i];
				pos++;
			}
		}
		this.items = newItems;
		this.init();
	}
	this.UpdatePermissions = function(prms)
	{
		this.allowAdd = $KB.FixNull(prms.AllowAdd,false);
		this.allowDelete = $KB.FixNull(prms.AllowDelete,false);
		this.init();
	}
	this.GetItems = function()
	{
		return this.items;
	}
	this.GetItemsTextMinus = function(id)
	{
		var txt = '';
		var c = '';
		for(var i=0;i<this.items.length;i++)
		{
			if(this.items[i].Id == id) continue;
			txt = txt + c + this.items[i].Text;
			c = ',';
		}
		return txt;
	}
	this.init();
}
$KB.WikiView = function(params)
{
	//private fields
	this.wikiId = params.WikiId,
	this.title = "";
	this.content = "";
	this.tags = "";
	this.templateId = -1;
	this.templateName = "";
	this.newTitle = "";
	this.newContent = "";
	this.isEditable = false;
	this.editWikiPanelId = params.EditWikiPanelId;
	this.displayContainer = params.DisplayContainer;
	this.onLoad = params.OnLoad;
	//private methods
	this.init = function()
	{
		this.createRenderers();
		this.loadArticle();
	}
	this.loadArticle = function() {
		var thisObject = this;
		DirectRequest.GetWikiData(this.wikiId, function(result, response) {
			thisObject.historyData = new Ext.data.ArrayStore
				(
					{
						autoDestroy: false,
						remoteSort: false,
						data: result.History,
						fields: [
									{ name: 'DateCreated', type: 'date' },
									{ name: 'Description', type: 'string' },
									{ name: 'CreatedbyName', type: 'string' },
									{ name: 'CreatedByUserId', type: 'int' }
								]
					}
				);
			var cnt = thisObject.historyData.data.length;
			for(var i = 0; i < cnt; i++) {
				thisObject.historyData.data.items[i].data = thisObject.historyData.data.items[i].json;
			}
			thisObject.content = result.Content;
			thisObject.newContent = result.Content;
			var tagCount = result.TagCount;
			thisObject.templateName = result.TemplateName;
			thisObject.templateId = result.TemplateID;
			thisObject.title = result.Title;
			thisObject.newTitle = result.Title;
			thisObject.isEditable = result.IsEditable;
			var tagString = '';
			var tagBox = [];
			for(var i = 0; i < tagCount; i++)
			{
				tagBox[i] = {Id:result.Tags[i].TagId,
							Text:result.Tags[i].TagName,
							Link: 'kbWiki.TagCloudClicked(' + result.Tags[i].TagId 
							+ ',"' + $KB.replaceAll(result.Tags[i].TagName) +  '");'
							};
				if(i != (tagCount-1))
				{
					tagString = tagString + result.Tags[i].TagName + '\r\n';
				}
				else tagString = tagString + result.Tags[i].TagName;
			}
			thisObject.tags = tagString;
			var allowAddTag = false;
			var allowDeleteTag = false;
			if($KB.LoggedIn && $KB.GlobalData.User.Profile != null)
			{
				allowAddTag = $KB.GlobalData.User.Profile.WikiManagement.AddTag;
				allowDeleteTag = $KB.GlobalData.User.Profile.WikiManagement.DeleteTag;
			}
			thisObject.TagButtonList = new $KB.ButtonList
			(
				{
					Id:'wikiTags',
					AllowAdd:allowAddTag,
					AllowDelete:allowDeleteTag,
					areLinks: true,
					Items: tagBox,
					AddFunction:function(buttonList, tagName)
					{
						var tags = buttonList.GetItemsTextMinus(null);
						if(tags.trim() == '') tags = tagName;
						else tags = tags + ',' + tagName;
						DirectRequest.UpdateWikiTags(thisObject.wikiId,tags,function(res,resp)
						{
							if($KB.CheckValueResponse(resp))
							{
								var r = [];
								for(var i=0;i<res.Value.length;i++)
								{
									r[i] = {Text:res.Value[i].TagName,Id:i,Link: 'kbWiki.TagCloudClicked(' + res.Value[i].TagId 
							+ ',"' + $KB.replaceAll(res.Value[i].TagName) +  '");'};
								}
								buttonList.SetItems(r);
							}
						});
						Ext.getCmp(buttonList.id + 'addTagWindow').close();
					},
						DeleteFunction:function(buttonList, tagId)
						{
							var tags = buttonList.GetItemsTextMinus(tagId);
							DirectRequest.UpdateWikiTags(thisObject.wikiId,tags,function(res,resp)
							{
								var r = [];
								for(var i=0;i<res.Value.length;i++)
								{
									r[i] = {Text:res.Value[i].TagName,Id:i};
								}
								buttonList.SetItems(r);
							});
						}
				}
			);
			thisObject.createWikiUI();
		});
	}
	this.createRenderers = function() {
		this.renderers =
			{
				WikiHistoryCreatedBy: function(value, p, r)
				{
					return String.format
					(
						'<div> {0} </div>',
						$KB.escTag(r.json.CreatedbyName)
					);
				},
				WikiHistoryModDate: function(value, p, r)
				{
					return String.format
					(
						'<div> {0} </div>',
						r.json.DateCreated
					);
				},
				WikiHistoryDescription: function(value, p, r)
				{
					return String.format
					(
						'<div> {0} </div>',
						$KB.escTag(r.json.Description)
					);
				}
			};
	}
	this.createWikiUI = function() {
		var thisObject = this;
		this.historyGrid = new Ext.grid.GridPanel({
			frame: false,
			stripeRows: true,
			scroll: true,
			columnLines: true,
			border: false,
			disableSelection: true,
			autoHeight: true,
			store: this.historyData,
			trackMouseOver: false,
			showMenu: false,
			menuDisabled: true,
			columns:
					[
						{
							header: $KB.LZ('Wiki_Hist_CreatedBy', 'Created By'),
							width: 100,
							sortable: true, 
							menuDisabled: true, 
							renderer: this.renderers.WikiHistoryCreatedBy 
						},
						{
							header: $KB.LZ('Wiki_Hist_Date', 'Date Modified'),
							width: 100,
							sortable: true, 
							menuDisabled: true, 
							renderer: this.renderers.WikiHistoryModDate 
						},
						{
							header: $KB.LZ('Wiki_Hist_Desc', 'Description'),
							width: 200,
							sortable: true, 
							menuDisabled: true, 
							renderer: this.renderers.WikiHistoryDescription 
						}
					],
			remoteSort: false,
			listeners: {
				headerclick: function(grid, colIndex, e)
					{
						switch(colIndex) {
							case 0: thisObject.historyData.sort('CreatedbyName'); break;
							case 1: thisObject.historyData.sort('DateCreated'); break;
							case 2: thisObject.historyData.sort('Description'); break;
						}
						thisObject.historyGrid.doLayout();
					}
			}
		});
		this.editWiki = new Ext.FormPanel
		(
			{
				id: this.editWikiPanelId,
				frame: true,
				anchor: '0 0',
				header: false,
				defaults:
				{
					labelSeparator: ''
				},
				items:
				[
					new Ext.form.TextField
					(
						{
							id: this.editWikiPanelId + 'Title',
							fieldLabel: $KB.LZ('Wiki_Title', 'Wiki Title'),
							value: this.title,
							width: 280
						}
					),
					new Ext.form.TextField
					(
						{
							id: this.editWikiPanelId + 'Template',
							fieldLabel: $KB.LZ('Wiki_Selected_Template', 'Selected Template'),
							width: 280,
							disabled: true,
							value: this.templateName
						}
					),
					{
						xtype:'container',
						anchor:'0 -70',
						id:this.editWikiPanelId + 'CuteEditor',
						autoEl:
						{
							tag:'div'
						}
					}
				],
				buttons:
				[
					{
						text: $KB.LZ('Wiki_Discard', 'Discard'),
						handler: function(b, e)
						{
							thisObject.newContent = thisObject.editWikiEditor.getHTML();
							thisObject.newTitle = Ext.get(thisObject.editWikiPanelId + 'Title').getValue();
							Ext.MessageBox.confirm($KB.LZ('Confirm', 'Confirm'), $KB.LZ('Wiki_Discard_Conf', 'Are you sure you want to discard any changes you\'ve made?'), thisObject.discardWikiChangesClicked, thisObject);
						}
					},
					{
						text: $KB.LZ('Wiki_Update', 'Update'),
						handler: function(b, e)
						{
							thisObject.newContent = thisObject.editWikiEditor.getHTML();
							thisObject.newTitle = Ext.get(thisObject.editWikiPanelId + 'Title').getValue();
							Ext.MessageBox.confirm($KB.LZ('Confirm', 'Confirm'), $KB.LZ('Wiki_Update_Conf', 'Are you sure you want to update this Wiki?'), thisObject.updateWikiClicked, thisObject);
						}
					}
				]
			}
		);
		var viewWikiPanel = new Ext.Panel
		({
			title: this.title,
			id: this.editWikiPanelId + 'TabPage1',
			anchor: '0 0',
			layout:'anchor',
			style: 'padding-left: 10px; padding-top: 10px; ',
			preventBodyReset: true,
			items:
			[
				{
					xtype:'container',
					id:this.editWikiPanelId + 'wikiCont',
					anchor:'0 0',
					autoScroll:true,
					autoEl:
					{
						tag:'iframe',
						id:this.editWikiPanelId + 'wikiContChild',
						src:'/kb/article?ArticleId=' + this.wikiId + '&Source=Wiki&islink=true',
						align: 'left',
						scrolling: 'auto',
						marginwidth:'8px',
						marginheight:'8px',
						hspace:'10px',
						frameborder: '0'
					}
				}
			]
		});
		var editHidden = true;
		if($KB.LoggedIn) editHidden = !( ($KB.GlobalData.User.Profile.WikiManagement.Edit) && (!$KB.GlobalData.User.IsWikiSuspended) && (this.isEditable) );
		this.editWikiPanel = new Ext.Panel
		({
			title: $KB.LZ('Forum_Edit', 'Edit'),
			id: this.editWikiPanelId + 'TabPage2',
			anchor:'0 0',
			layout:'anchor',
			items:
			[
				this.editWiki
			]
		});
		var wikiHistoryPanel = new Ext.Panel
		({
			title: $KB.LZ('Wiki_View_History', 'View History'),
			id: this.editWikiPanelId + 'TabPage3',
			items: [ this.historyGrid ],
			autoScroll:true
		});
		var thisObject = this;
		var itms = [];
		itms[0] = viewWikiPanel;
		if(editHidden) itms[1] = wikiHistoryPanel;
		else
		{
			itms[1] = this.editWikiPanel;
			itms[2] = wikiHistoryPanel;
		}
		var atpDef = 
		{
			activeTab: 0,
			border: false,
			id: this.editWikiPanelId + 'artTabPanel',
			frame: false,
			anchor:'0 -50',
			plain:true,
			items: itms,
			listeners:
			{
				'tabchange': function(tabPanel, tab)
				{
					$KB.RefreshCustomTab(thisObject.editWikiPanelId + 'artTabPanel','Children', tab);
					if(tab.id == thisObject.editWikiPanelId + 'TabPage2') {
						thisObject.editWikiEditor = new $KB.CuteEditor();
						thisObject.editWikiEditor.setHTML(thisObject.content);
						thisObject.editWikiEditor.onLoad = function() {thisObject.content = thisObject.editWikiEditor.getHTML();};
						Ext.get(thisObject.editWikiPanelId + 'CuteEditor').dom.innerHTML = thisObject.editWikiEditor.getFrame();
						Ext.getCmp(thisObject.editWikiPanelId + 'Title').setValue(thisObject.title);
					}
					else
					{
						if(!$KB.isNull(thisObject.editWikiEditor))
						{
							thisObject.editWikiEditor.close();
							thisObject.editWikiEditor = null;
						}
					}
				}
			}
		};
		$KB.AddCustomTabOptions(thisObject.editWikiPanelId + 'artTabPanel','Children',atpDef);
		this.articleTabPanel = new Ext.TabPanel(atpDef);
		this.articleToolbar = new $KB.ArticleToolbar(
		{
			Id:this.editWikiPanelId + 'toolbar',
			ArticleId:this.wikiId,
			Source:'Wiki',
			Title:this.title,
			Component:Ext.getCmp(this.editWikiPanelId + 'wikiCont'),
			IsFrame:false,
			Visibility:
			{
				Edit:false
			}
		});
		var artInfo = {
			xtype:'container',
			autoHeight: true,
			items:
			[
				this.articleToolbar.Control,
				{
					xtype:'container',
					autoHeight:true,
					items:this.TagButtonList.UIElement
				}
			]
		};
		this.mainCont = new Ext.Container(
		{
			layout:'anchor',
			frame:true,
			anchor:'0 -10',
			defaults:
			{
				style:'padding:5px;'
			},
			items:
			[
				artInfo,
				this.articleTabPanel
			]
		});
		this.displayContainer.add(this.mainCont);
		this.displayContainer.doLayout(false, true);
		this.onLoad({'Title': this.title});
	}
	this.discardWikiChangesClicked = function(btn)
	{
		if(btn == 'yes')
		{
			this.articleTabPanel.setActiveTab(0);
		}
	}
	this.updateWikiClicked = function(btn)
	{
		var thisObject = this;
		if(btn == 'yes')
		{
			if(thisObject.newContent != thisObject.content) {
				DirectRequest.SaveWiki(
					thisObject.wikiId,
					thisObject.newTitle,
					thisObject.templateId,
					thisObject.newContent,
					'[-1]',
					function(result, response)
					{
						if($KB.CheckValueResponse(response))
						{
							thisObject.isEditable = result.Value;
							thisObject.DestroyObjects();
							thisObject.loadArticle(thisObject.wikiId, thisObject.newTitle);
						}
					}
				);
			}
			else
			{
				DirectRequest.UpdateWiki(
					thisObject.wikiId,
					thisObject.newTitle,
					thisObject.newContent,
					'[-1]',
					thisObject.templateId,
					function(result, response)
					{
						if($KB.CheckValueResponse(response))
						{
							thisObject.isEditable = result.Value;
							thisObject.DestroyObjects();
							thisObject.loadArticle(thisObject.wikiId, thisObject.newTitle);
						}
					}
				);
			}
		}
	}
	//public methods
	this.CloseCuteEditor = function()
	{
		if(typeof(this.editWikiEditor) != 'undefined')
		{
			this.articleTabPanel.setActiveTab(0);//this automatically closes the cute editor
		}
	}
	this.GetCuteEditor = function()
	{
		return this.editWikiEditor;
	}
	this.DestroyObjects = function()
	{
		if(!$KB.isNull(this.editWikiEditor)) this.editWikiEditor.close();
		this.editWikiEditor = null;
		this.displayContainer.remove(this.mainCont, true);
	}
	this.HideEdit = function()
	{
		if(this.articleTabPanel.items.contains(this.editWikiPanel))
			this.articleTabPanel.remove(this.editWikiPanel,false);
	}
	this.ShowEdit = function()
	{
		if(this.isEditable)
		{
			if(!this.articleTabPanel.items.contains(this.editWikiPanel))
				this.articleTabPanel.insert(1,this.editWikiPanel);
		}
		else this.HideEdit();
	}
	this.UpdatePermissions = function()
	{
		var allowAddTag = false;
		var allowDeleteTag = false;
		if($KB.LoggedIn && $KB.GlobalData.User.Profile != null)
		{
			allowAddTag = $KB.GlobalData.User.Profile.WikiManagement.AddTag;
			allowDeleteTag = $KB.GlobalData.User.Profile.WikiManagement.DeleteTag;
		}
		this.TagButtonList.UpdatePermissions({AllowAdd:allowAddTag,AllowDelete:allowDeleteTag});
	}
	//initialize this object
	this.init();
};
$KB.LoadGlobalData = function()
{
	var data = $KB.Settings.GlobalData;
	Ext.ns('$KB.GlobalData');
	var ftFieldDef =
	[
		{ name: 'FileExt', type: 'string' },
		{ name: 'Name', type: 'string' }
	];
	var ftFields = {fields: ftFieldDef, idIndex: 0};
	$KB.GlobalData.FileTypes = new Ext.data.ArrayStore(ftFields);
	var ftRecord = Ext.data.Record.create(ftFieldDef);
	var langFieldDef =
	[
		{ name: 'Id', type: 'int' },
		{ name: 'Name', type: 'string' }
	];
	var langFields = {fields: langFieldDef, idIndex: 0};
	$KB.GlobalData.Languages = new Ext.data.ArrayStore(langFields);
	var langRecord = Ext.data.Record.create(langFieldDef);
	var ftRecords = new Array();
	for(var i = 0; i < data.FileTypeCount; i++)
	{
		var r = new ftRecord({FileExt: data.FileTypes[i].Key, Name: data.FileTypes[i].Value});
		ftRecords[i] = r;
	}
	$KB.GlobalData.FileTypes.add(ftRecords);
	var langRecords = new Array();
	for(var i = 0; i < data.LanguageCount; i++)
	{
		var r = new langRecord({Id: data.Languages[i].Key, Name: data.Languages[i].Value});
		langRecords[i] = r;
	}
	$KB.GlobalData.Languages.add(langRecords);
	$KB.GlobalData.Profile = data.Profile;
	$KB.GlobalData.WikiPortalConfig = data.WikiPortalConfig;
	$KB.GlobalData.PortalProperties = data.PortalProperties;
	$KB.GlobalData.WidgetManagement = data.WidgetManagement;
	$KB.GlobalData.PortalArticleInfo = data.PortalArticleInfo;
	$KB.GlobalData.ShowRatings = data.ShowRatings;
	$KB.GlobalData.Localization = data.Localization;
	$KB.GlobalData.SearchResultDisplay = data.SearchResultDisplay;
	$KB.GlobalData.User = data.User;
	$KB.GlobalData.FileTypeTitle = data.FileTypeTitle;
	$KB.GlobalData.SessionTimeoutWarning = data.SessionTimeoutWarning;
	$KB.GlobalData.SessionTimeout = data.SessionTimeout;
}
$KB.CreatePresentationAPI = function()
{
	Ext.ns('PresentationAPI.Home','PresentationAPI.Wiki','PresentationAPI.Forum');
	//Global Methods
	PresentationAPI.Alert = $KB.alert;
	//Home Tab Methods
	PresentationAPI.Home.OpenChat = function() { $KB.OpenChat('home'); }
	PresentationAPI.Home.Select = function() {$KB.TabManager.setActiveTab('home');}
	//Wiki Tab Methods
	PresentationAPI.Wiki.Select = function() {$KB.TabManager.setActiveTab('wiki');}
	//Forum Tab Methods
	PresentationAPI.Forum.Select = function() {$KB.TabManager.setActiveTab('forum');}
}
$KB.SetUserData = function(userData)
{
	$KB.ShowLoginStatus();
	$KB.GlobalData.User = userData;
	$KB.LoggedIn = (userData != null && userData.UserID > 0);	
	if ($KB.Settings.ShowLoginStatus)
	{
		var UserBarLabel = Ext.getCmp('kbUserNameLabel').el.dom.firstChild;
		var btnUserLogin = Ext.getCmp("btnUserLogin");
		var hasLogin = (btnUserLogin != null);
		if ($KB.LoggedIn)
		{
			UserBarLabel.innerHTML = $KB.LZ("Welcome", "Welcome, {0}", [$KB.GlobalData.User.FirstName + ' ' + $KB.GlobalData.User.LastName]);
			if (hasLogin) btnUserLogin.setText($KB.replaceSpaces($KB.LZ('Login_Out', 'Log Out')));
 			if(Ext.isDefined($KB.SettingsTab)) $KB.PageTabs.add($KB.SettingsTab);
		}
		else
		{
			UserBarLabel.innerHTML = "&nbsp;";
			if (hasLogin) btnUserLogin.setText($KB.replaceSpaces($KB.LZ('Login_In', 'Log In')));
			if(Ext.isDefined($KB.SettingsTab)) $KB.PageTabs.remove($KB.SettingsTab,false);
		}
		$KB.LoginStatus.doLayout();
	}
	$KB.TabManager.refresh();
}
$KB.doLayout = function(s,f)
{
	var s = $KB.FixNull(s, false);
	var f = $KB.FixNull(f, false);
	if (Ext.isDefined($KB.PageTabs))
	{
		$KB.PageTabs.activeTab.doLayout(s,f);
	}
	else $KB.PageViewPort.doLayout(s,f);
}
$KB.AutoSizeGridCols = function(grid, width, ColsToPad, minWidth)
{
	if (width == null || grid.hidden || width < $KB.FixNullorEmpty(minWidth, 500)) return;
	var cm = grid.getColumnModel();
	var cwt = 2;
	for (var key in cm.lookup)
	{
		if (ColsToPad.indexOf(key)< 0)
		{
			var col = cm.getColumnById(key);
			if (!col.hidden) cwt += col.width;
		}
	}
	var colWidth = Math.floor((width - cwt) / ColsToPad.length);
	var LastWidth = $KB.FixNullorEmpty(grid.LastAutoSizeWidth, -1);
	if (colWidth > 0 && LastWidth != colWidth)
	{
		for (var i = 0; i < ColsToPad.length; i++)
		{
			var ci = cm.getIndexById(ColsToPad[i]);
			if (ci > -1) cm.setColumnWidth(ci, colWidth);
		}
	}
	grid.LastAutoSizeWidth = colWidth;
}
$KB.AssignerPanel = function(params)
{
	if (!Ext.isDefined($KB.AssignerPanels)) $KB.AssignerPanels = [];
	params.Index = $KB.AssignerPanels.length;
	$KB.AssignerPanels.push(this);
	params.paneWidth = $KB.FixNullorEmpty(params.paneWidth, 200);
	params.actionIds = { left: [], right: [] };
	this.addData = function(data)
	{
		params.stores = { left: BuildStore('left', data), right: BuildStore('right', data) };
		params.stores['right'].each
		(
			function(r)
			{
				var rLeft = params.stores['left'].getById(r.data[params.idProperty]);
				if (rLeft != null) params.stores['left'].remove(rLeft);
			}
		);
		fillPanes();
	}
	function BuildStore(side, data)
	{
		return new Ext.data.JsonStore
		(
			{
				idProperty: params.idProperty,
				root: '',
				fields:
				[
					{name: params.idProperty, type: 'int'},
					{name: params.itemProperty, type: 'string'}
				],
				data: data[params[side + 'DataName']]
			}
		);
	}
	function fillPanes()
	{
		fillPane('left');
		fillPane('right');
	}
	function fillPane(side)
	{
		var store  = params.stores[side];
		store.sort(params.itemProperty);
		SetButtonState(side);
		var s = "";
		store.each
		(
			function(r)
			{
				var id = r.data[params.idProperty];
				var item = r.data[params.itemProperty];
				var sel = (params.actionIds[side].indexOf(id) > -1 ? "_sel" : "");
				s += '<div class="SD_ListBoxItem' + sel + '"'
						+ $KB.BuildClick('$KB.AssignerPanels[' + params.Index + '].itemClick(this,' + id + ',\'' + side + '\')')
						+ '>' + item + '</div>';
			}
		)
		Ext.get('pane' + params.assignerId + side).dom.innerHTML = s;
	}
	this.itemClick = function(item, id, side)
	{
		var bSelected = params.actionIds[side].indexOf(id) < 0;
		item.className = "SD_ListBoxItem"  + (bSelected ? "_sel" : "");
		if (bSelected)
		{
			params.actionIds[side].push(id);
		}
		else
		{
			params.actionIds[side].remove(id);
		}
		item.moData = null;
		SetButtonState(side);
	}
	function SetButtonState(side)
	{
		var direction = $KB.Opposite(side, 'left', 'right');
		Ext.getCmp('btn' + params.assignerId +  "_" + direction).setDisabled(params.actionIds[side].length == 0);
	}
	function CreatePane(PaneSide)
	{
		return new Ext.Container
		(
			{
				layout: 'form',
				border: false,
				width: params.paneWidth,
				height: params.height,
				labelAlign: 'top',
				padding: '0',
				defaults:
				{
					labelSeparator: ''
				},
				items:
				[
					{
						xtype: 'container',
						padding: '0',
						id: 'pane' + params.assignerId +PaneSide,
						fieldLabel: params[PaneSide + 'Label'],
						cls: 'SD_ListPanel',
						width: params.paneWidth,
						height: params.height-40
					}
				]
			}
		);
	}
	function CreateBtn(direction)
	{
		return new Ext.Button
		(
			{
				id: 'btn' + params.assignerId +  "_" + direction,
				iconCls: 'btn-arrow-' + direction,
				width: 20,
				style: 'margin-bottom: 10px',
				disabled: true,
				handler: function () { $KB.AssignerPanels[params.Index].buttonClick(this) }
			}
		)
	}
	this.buttonClick = function(btn)
	{
		var direction = ($KB.LastSplitItem(btn.id, "_"));
		var side = $KB.Opposite(direction, 'left', 'right');
		params[direction + 'ButtonAction']
		(
			params.actionIds[side].join(','),
			function (res, resp)
			{
				if (res == true)
				{
					var aS = params.stores[params[side + 'DataName']];
					var bS = params.stores[params[direction + 'DataName']];
					for (var i =0; i < params.actionIds[side].length; i++ )
					{
						var r = params.stores[side].getById(params.actionIds[side][i]);
						params.stores[direction].add(r);
						params.stores[side].remove(r);
					}
					params.actionIds[side] = [];
					fillPanes();
				}
			}
		);
	}
	this.pane_left = CreatePane('left');
	this.pane_right = CreatePane('right');
	this.btn_left = CreateBtn('left');
	this.btn_right = CreateBtn('right');
	this.Panel = new Ext.Container
	(
		{
			layout: 'column',
			height: params.height,
			style: params.bodyStyle,
			width: params.paneWidth * 2 + 100,
			items:
			[
				this.pane_left,
				{
					width: 40,
					border: false,
					padding: '70 10 5 10',
					layout: 'form',
					items:
					[
						this.btn_right,
						this.btn_left
					]
				},
				this.pane_right
			]
		}
	)
	params.container.add(this.Panel);
	params.container.doLayout();
}
$KB.CookieData = function()
{
	this.cookieLife = 1000; //in days
	this.Data = {};
	this.init = function()
	{
		this.getData();
	}
	this.setCookie = function()
	{
		var exdate=new Date();
		exdate.setDate(exdate.getDate()+this.cookieLife);
		var cv = "";
		var dl = "";
		for(var c in this.Data)
		{
			cv = cv + dl + escape(c) + ">>>" + escape(this.Data[c]);
			dl = "___";
		}
		document.cookie="kbuserdata="+cv+";expires="+exdate.toGMTString();
	}
	this.getData = function()
	{
		var cv = Ext.util.Cookies.get("kbuserdata");
		if(cv == null) return;
		var spl = cv.split("___");
		for(var i=0;i<spl.length;i++)
		{
			var spl2 = spl[i].split(">>>");
			if(spl2.length==2)
			{
				var nme = unescape(spl2[0]);
				var val = unescape(spl2[1]);
				this.Data[nme] = val;
			}
		}
	}
	this.init();
	//public methods
	this.SaveAll = function()
	{
		this.setCookie();
	}
	this.Save = function(params)
	{
		for(var c in params)
		{
			this.Data[c] = params[c];
		}
		this.setCookie();
	}
	this.SetData = function(params)
	{
		for(var c in params)
		{
			this.Data[c] = params[c];
		}
	}
}
$KB.PortalDrop = function(e)
{
	e.panel.newOwnerId = e.column.id;
	var tab = $KB.PageTabs.getActiveTab().itemId.toLowerCase();
	switch(tab)
	{
		case 'hometab': kbHome.LocationKeeper.SavePositions(); break;
		case 'wikitab': kbWiki.LocationKeeper.SavePositions(); break;
		case 'glossarytab': kbGlossary.LocationKeeper.SavePositions(); break;
		case 'forumtab': kbForum.LocationKeeper.SavePositions(); break;
		default:break;
	}
}
$KB.HideRightPane = function(params)
{
	var cmp = Ext.get(params.Tab + 'PaneRight');
	var width = cmp.getWidth();
	if(width > 0)
	{
		$KB[params.Tab + 'PaneRightWidth'] = cmp.getWidth();
	}
	cmp.setVisible(false);
	$KB.doLayout($KB.FixNull(params.ShallowLayout,false), false);
}
$KB.ShowRightPane = function(params)
{
	var cmp = Ext.get(params.Tab + 'PaneRight');
	cmp.setVisible(true);
	var width = $KB.FixNullorEmpty($KB[params.Tab + 'PaneRightWidth'],null);
	if(width != null) cmp.setWidth(width);
	$KB.doLayout($KB.FixNull(params.ShallowLayout,false), false);
}
$KB.ArticleToolbar = function(params)
{
	if(typeof(params.Visibility) == 'undefined')
	{
		this.visibility =
		{
			Print: $KB.GlobalData.PortalArticleInfo.PrintArticle,
			Email: $KB.GlobalData.PortalArticleInfo.EmailArticle,
			Bookmark: $KB.GlobalData.PortalArticleInfo.BookmarkArticle,
			Download: $KB.GlobalData.PortalArticleInfo.DownloadArticle,
			CopyLink: $KB.GlobalData.PortalArticleInfo.CopyArticleLink,
			Rating: $KB.GlobalData.ShowRatings,
			Edit:true
		}
	}
	else
	{
		this.visibility =
		{
			Print: $KB.FixNullorEmpty(params.Visibility.Print, $KB.GlobalData.PortalArticleInfo.PrintArticle),
			Email: $KB.FixNullorEmpty(params.Visibility.Email, $KB.GlobalData.PortalArticleInfo.EmailArticle),
			Bookmark: $KB.FixNullorEmpty(params.Visibility.Bookmark, $KB.GlobalData.PortalArticleInfo.BookmarkArticle),
			Download: $KB.FixNullorEmpty(params.Visibility.Download, $KB.GlobalData.PortalArticleInfo.DownloadArticle),
			CopyLink: $KB.FixNullorEmpty(params.Visibility.CopyLink, $KB.GlobalData.PortalArticleInfo.CopyArticleLink),
			Rating: $KB.FixNullorEmpty(params.Visibility.Rating, $KB.GlobalData.ShowRatings),
			Edit:$KB.FixNullorEmpty(params.Visibility.Edit, true)
		}
	}
	this.highlight = '#6ec6f1';
	this.id = params.Id;
	this.title = $KB.FixNullorEmpty(params.Title,'');
	this.infoPanel = $KB.FixNullorEmpty(params.InfoPanel,null);
	this.onLoad = $KB.FixNullorEmpty(params.OnLoad,null);
	this.articleLinkFn = $KB.FixNull(params.ArticleLinkFn,null);
	this.isSnapIn = $KB.FixNull(params.IsSnapIn,false);
	this.lastArticlesParams = $KB.FixNull(params.LastArticlesParams,[]);
	
	this.tb = new Ext.Toolbar(
	{
		autoWidth:true
	});
	this.cont = new Ext.Container(
	{
		id:this.id,
		items: this.tb,
		autoWidth:true
	});
	this.Control = this.cont;
	$KB[this.id + 'get'] = this;
	this.like = '';
	this.dislike = '';
	this.IsEmpty = false;
	var me = this;
	this.init = function()
	{
		if( (typeof(params.ArticleId) != 'undefined') && (typeof(params.Source) != 'undefined') && (typeof(params.Component) != 'undefined') )
		{
			var db = $KB.FixNullorEmpty(params.DB, '');
			var query = $KB.FixNullorEmpty(params.Query, '');
			var isFrame = $KB.FixNullorEmpty(params.IsFrame,true);
			this.setArticle({Id:params.ArticleId,Title:this.title,Component:params.Component,IsFrame:isFrame,Source:params.Source,DB:db,Query:query});
		}
	}
	this.drawUI = function()
	{
		var src = $KB.FixNullorEmpty(params.Source,'').toLowerCase();
		var pos = 0;
		var itms = [];
		var printPos = -1;
		var emailPos = -1;
		var bookmarkPos = -1;
		var downloadPos = -1;
		var copyArticleLinkPos = -1;
		var socialPos = -1;
		if(this.visibility.Print)
		{
			itms[pos] =
			{
				xtype:'box',id:this.id+'printdiv',
				tbCtrl: this,
				autoEl:
				{
					tag:'div',
					cls:'icon_printer SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Print', 'Print'),
					onclick:'$KB.' + this.id + 'get.print();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			printPos = pos;
			pos++;
		}
		if(this.visibility.Email)
		{
			itms[pos] =
			{
				xtype:'box',id:this.id+'emaildiv',
				autoEl:
				{
					tag:'div',
					cls:'icon_email SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Email', 'Email'),
					onclick:'$KB.' + this.id + 'get.email();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			emailPos = pos;
			pos++;
		}
		if(this.visibility.Bookmark)
		{
			itms[pos] =
			{
				xtype:'box',id:this.id+'bookmarkdiv',
				autoEl:
				{
					tag:'div',
					cls:'icon_bookmark SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Bookmark', 'Bookmark'),
					onclick:'$KB.' + this.id + 'get.bookmark();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			bookmarkPos = pos;
			pos++;
		}
		if(this.visibility.Download)
		{
			itms[pos] =
			{
				xtype:'box',id:this.id+'downloaddiv',
				autoEl:
				{
					tag:'div',
					cls:'icon_download SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Download', 'Download'),
					onclick:'$KB.' + this.id + 'get.download();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			downloadPos = pos;
			pos++;
		}
		if(this.visibility.CopyLink)
		{
			itms[pos] =
			{
				xtype:'box',id:this.id+'copylinkdiv',
				autoEl:
				{
					tag:'div',
					cls:'icon_articlelink SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Link', 'Copy Article Link'),
					onclick:'$KB.' + this.id + 'get.articleLink();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			copyArticleLinkPos = pos;
			pos++;
		}
		if($KB.GlobalData.PortalArticleInfo.SocialMedia)
		{
			itms[pos] =
			{
				xtype:'box',
				autoEl:
				{
					tag:'div',
					cls:'icon_facebook SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Facebook', 'Facebook'),
					onclick:'$KB.' + this.id + 'get.facebook();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			socialPos = pos;
			pos++;
			itms[pos] =
			{
				xtype:'box',
				autoEl:
				{
					tag:'div',
					cls:'icon_twitter SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Twitter', 'Twitter'),
					onclick:'$KB.' + this.id + 'get.twitter();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			pos++;
			itms[pos] =
			{
				xtype:'box',
				autoEl:
				{
					tag:'div',
					cls:'icon_digg SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Digg', 'Digg'),
					onclick:'$KB.' + this.id + 'get.digg();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			pos++;
			itms[pos] =
			{
				xtype:'box',
				autoEl:
				{
					tag:'div',
					cls:'icon_delicious SD_ArticleToolbarItem',
					title:$KB.LZ('Article_Delicious', 'Delicious'),
					onclick:'$KB.' + this.id + 'get.delicious();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			};
			pos++;
		}
		var ordered = [];
		//"print,email,bookmark,download,subscribe,notes,editArticle,suggest,suggestEmail,articleCat,copyArticleLink,socialMedia"
		var oItms = $KB.GlobalData.PortalArticleInfo.Order.split(',');
		var oPos = 0;
		function addOItem(ps,num)
		{
			if(ps > -1)
			{
				num = $KB.FixNull(num,1);
				for(var i=0;i<num;i++)
				{
					if(oPos != 0)
					{
						ordered[oPos] = '-';
						oPos++;
					}
					ordered[oPos] = itms[ps+i];
					oPos++;
				}
			}
		}
		for(var x =0;x<oItms.length; x++)
		{
			var oitm = oItms[x];
			switch(oitm.toLowerCase())
			{
				case 'print':addOItem(printPos);break;
				case 'email':addOItem(emailPos);break;
				case 'bookmark':addOItem(bookmarkPos);break;
				case 'download':addOItem(downloadPos);break;
				case 'copyarticlelink':addOItem(copyArticleLinkPos);break;
				case 'socialmedia':addOItem(socialPos,4);break;
			}
			
		}
		if(this.visibility.Edit)
		{
			ordered.push(
			{
				xtype:'box',id:this.id+'editdiv',
				autoEl:
				{
					tag:'div',
					cls:'SD_ArticleToolbarItem',
					style:'height:18px;',
					html:$KB.LZ('Article_More_Info', 'More Info...'),
					title:$KB.LZ('Article_More_Info', 'More Info...'),
					onclick:'$KB.' + this.id + 'get.edit();',
					onmouseover:'$KB.elementFromEvent(event).style.backgroundColor=\'' + this.highlight + '\';',
					onmouseout:'$KB.elementFromEvent(event).style.backgroundColor=\'transparent\';'
				}
			});
		}
		if(this.visibility.Rating)
		{
			if ( (src == "forum") || (src == "article") || (src == "wiki") || (src == "faq") )
			{
				ordered.push('->');
				this.ratingtoolCont = new Ext.Container
				(
					{
						width:110
					}
				);
				this.ratingtool = new $KB.RatingTool({source:this.source,sourceId:this.aid, container:this.ratingtoolCont});
				ordered.push(this.ratingtoolCont);
			}
		}
		if(ordered.length > 0)
		{
			this.tb.add
			(
				ordered
			);
			this.tb.doLayout(false,true);
		}
		else this.IsEmpty = true;
	}
	this.callPrint = function()
	{
		var prtContent = document.getElementById(this.component.id);
		var WinPrint =
		window.open('','','left=0,top=0,width=1,height=1,t oolbar=0,scrollbars=0,status=0');
		WinPrint.document.write(prtContent.innerHTML);
		WinPrint.document.close();
		WinPrint.focus();
		WinPrint.print();
		WinPrint.close();
	}
	this.bookmarkUrl = function(url,title)
	{
		if (window.sidebar) 
		{ 
			//Firefox
			window.sidebar.addPanel(title, url,"");	
		} 
		else if(window.opera && window.print) 
		{ 
			//Opera
			var elem = document.createElement('a');
			elem.setAttribute('href',url);
			elem.setAttribute('title',title);
			elem.setAttribute('rel','sidebar');
			elem.click();
		}
		else if(window.external && Ext.isIE) 
		{ 
			// IE
			window.external.AddFavorite( url, title);
		}
		else 
		{
			$KB.alert($KB.LZ('Article_No_Browser_Support', "Your browser doesn't support this feature. Click on button to the right to copy the Article link manually."));
		}
	}
	this.getArticleUrl = function()
	{
		var pp = $KB.GlobalData.PortalProperties;
		var src = this.source;
		var articleId = this.aid;
		if(src.toLowerCase() == 'faq')
		{
			src = 'Article';
			articleId = this.actualArticleId;
		}
		else if(src.toLowerCase() == 'forum')
		{
			return document.location.protocol + '//' + document.location.host + '?PostId=' + articleId;
		}
		return document.location.protocol + '//' + document.location.host + '/kb/article?ArticleId=' + articleId + '&source=' + src + ( (this.db != '') ? '&DB=' + this.db : '') + ( (this.query != '') ? '&DBQuery=' + this.db : '') + '&c=' + pp.ClientId + '&cid=' + pp.PortalId;
	}
	this.getArticleShareUrl = function()
	{
		return this.rawurlencode(this.getArticleUrl());
	}
	this.rawurlencode = function(str) {
		str = (str + '').toString();
		return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
		replace(/\)/g, '%29').replace(/\*/g, '%2A');
	}
	this.print = function()
	{
		var o = null;
		if(this.isFrame) o = this.component.el.dom.getElementsByTagName("iframe")[0].contentWindow;
		else if(this.source.toLowerCase() == 'wiki') o = this.component.getEl().dom.contentWindow;
		else this.callPrint();
		if(o != null)
		{
			o.focus();
			o.print();
		}
	}
	this.email = function()
	{
		var thisObject = this;
		$KB.HideArticleIFrame();
		var window = new Ext.Window(
		{
			renderTo:Ext.getBody(),
			id:this.id + 'emailwindow',
			layout:'anchor',
			closable: true,
			modal:true,
			width:400,
			height:300,
			title:$KB.LZ('Article_Email_Title', 'Email This Article'),
			listeners:
			{
				close:function() {$KB.ShowArticleIFrame();}
			},
			items:
			[
				{
					xtype:'form',
					labelAlign:'top',
					anchor:'0 0',
					bodyStyle:'background-color:transparent; padding:8px; ',
					frame:false,hideBorders:true,border:false,
					defaults:
					{
						labelSeparator:''
					},
					items:
					[
						{
							xtype:'textfield',fieldLabel:$KB.LZ('Article_Email_To', 'To'),anchor:'100%',id:this.id+'emailTo',
							validator: function(val)
							{
								var re = new RegExp(".+\@.+\..+");
								if (re.test(val))
									return true;
								else
									return $KB.LZ("ATR_ValueInvalid","The value in this field is invalid");
							}						
						},
						{xtype:'textfield',fieldLabel:$KB.LZ('Article_Email_Subject', 'Subject'),anchor:'100%',id:this.id+'emailSubject'},
						{xtype:'textarea',fieldLabel:$KB.LZ('Article_Email_Body', 'Body'),anchor:'100% -92',id:this.id+'emailBody'}
					]
				}
			],
			buttons:
			[
				{
					xtype:'button',
					text:$KB.LZ('Article_Email_Send', 'Send'),
					handler:function()
					{
						var tofield = Ext.getCmp(thisObject.id+'emailTo');
						if(tofield.isValid())
						{
							var eTo = tofield.getValue();
							var eSubject = Ext.getCmp(thisObject.id+'emailSubject').getValue();
							var eBody = Ext.getCmp(thisObject.id+'emailBody').getValue() + '\r\n\r\n' + thisObject.getArticleUrl() + '\r\n\r\n';
							DirectRequest.Email(eTo, eSubject, eBody, thisObject.source, thisObject.aid,function(res,resp)
							{
								if(resp.status)
								{
									if(res)
									{
										$KB.alert($KB.LZ('Article_Email_Send_Conf', 'Email has been sent.  The article will be included as an attachment to the email.'),$KB.LZ('Article_Email', 'Email'));
										Ext.getCmp(thisObject.id + 'emailwindow').close();
									}
								}
								else
								{
									$KB.alert($KB.LZ('Article_Email_Send_Err', 'An unknown error occured while attempting to send the email.'));
								}
							});
						}
						else $KB.alert($KB.LZ('Article_Email_Send_Invalid', 'Email is not valid.'),$KB.LZ('Article_Email', 'Email'));
					}
				},
				{
					xtype:'button',
					text:$KB.LZ('Cancel', 'Cancel'),
					handler:function() {Ext.getCmp(thisObject.id + 'emailwindow').close();}}
			]
		});
		window.show();
	}
	this.bookmark = function()
	{
		this.bookmarkUrl(this.getArticleUrl(), this.title);
	}
	this.download = function(attIndex)
	{
		var attind = $KB.FixNull(attIndex,'-1');
		var src = this.source;
		var articleId = this.aid;
		if(src.toLowerCase() == 'faq')
		{
			src = 'Article';
			articleId = this.actualArticleId;
		}
		var attEnding = (attind == '-1') ? '' : ('&AttIndex=' + attind);
		document.location = '/kb/article?ArticleId=' + articleId + '&cid=' + $KB.GlobalData.PortalProperties.PortalId +  '&download=true&islink=true&source=' + src + ( (this.db != '') ? '&DB=' + this.db : '') + ( (this.query != '') ? '&DBQuery=' + this.db : '') + attEnding;
	}
	this.articleLink = function()
	{
		var thisObject = this;
		var al = this.getArticleUrl();
		$KB.HideArticleIFrame();
		var window = new Ext.Window(
		{
			renderTo:Ext.getBody(),
			layout:'anchor',
			id:this.id + 'linkwindow',
			closable: true,
			modal:true,
			width:400,
			height:150,
			minHeight:150,
			maxHeight:150,
			minWidth:400,
			title:$KB.LZ('Article_Link', 'Copy Article Link'),
			resizable:true,
			resizeHandles:'w e',
			listeners:
			{
				close:function() {$KB.ShowArticleIFrame();}
			},
			items:
			[
				{
					xtype:'form',
					anchor:'0 0',
					bodyStyle:'background-color:transparent; padding:8px; ',
					frame:false,hideBorders:true,border:false,
					labelAlign:'top',
					defaults:
					{
						labelSeparator:''
					},
					items:
					[
						{
							xtype:'textfield',
							readOnly:true,
							fieldLabel:$KB.LZ('Article_Link_Label', 'Right-click the text below and click copy.'),
							anchor:'100%',
							value:al,
							selectOnFocus:true
						}
					]
				}
			],
			buttons:
			[
				{xtype:'button',text:$KB.LZ('Close', 'Close'),handler:function() {Ext.getCmp(thisObject.id + 'linkwindow').close();}}
			]
		});
		window.show();
	}
	this.feedback = function()
	{
		var thisObject = this;
		$KB.HideArticleIFrame();
		var window = new Ext.Window(
		{
			renderTo:Ext.getBody(),
			id:this.id + 'feedbackwindow',
			layout:'fit',
			closable: true,
			modal:true,
			width:400,
			height:350,
			title:$KB.LZ('Article_Feedback', 'Article Feedback'),
			resizable:false,
			listeners:
			{
				close:function() {$KB.ShowArticleIFrame();}
			},
			items:
			[
				{
					xtype:'form',
					labelAlign:'top',
					bodyStyle:'background-color:transparent;padding:4px;',
					hideBorders:true,
					border:false,
					items:
					[
						{
							xtype:'textarea',
							id:thisObject.id + 'feedbackTB',
							emptyText: $KB.LZ('Article_Feedback_emptytext', 'Enter your feedback,maximum of 250 characters'),
							anchor:'100%',
							height:260,
							maxLength:250,
							enforceMaxLength:true,
							fieldLabel:$KB.LZ('Article_Feedback_Label', 'Type your feedback here')
						}
					],
					buttons:
					[
						{
							xtype:'button',text:$KB.LZ('Article_Feedback_Send', 'Send Feedback'),
							handler:function()
							{
								var txt = Ext.getCmp(thisObject.id + 'feedbackTB').getValue();
								if(txt.trim() != '')
								{
								    if(txt.length > 250)
								    {
								        $KB.alert($KB.LZ('Article_Feedback_maxlength_Err', 'Please simplify your feedback.  Maximum of 250 characters.'),$KB.LZ('Article_Feedback', 'Article Feedback'));
								         return; 
								    }
									DirectRequest.SendArticleFeedback(thisObject.aid, txt, function(res,resp)
									{
										if(res == false)
										{
											$KB.alert($KB.LZ('Article_Feedback_Send_Err', 'Unable to send feedback for this article.  Please contact an administrator.'),$KB.LZ('Article_Feedback', 'Article Feedback'), function() {Ext.getCmp(thisObject.id + 'feedbackwindow').close();});
										}
										else
										{
											$KB.alert($KB.LZ('Article_Feedback_Send_Conf', 'Feedback has been sent.'),$KB.LZ('Article_Feedback', 'Article Feedback'), function() {Ext.getCmp(thisObject.id + 'feedbackwindow').close();});
										}
									});
								}
								else $KB.alert($KB.LZ('Article_Feedback_Send_Invalid', 'Please provide some feedback before submitting.'),$KB.LZ('Article_Feedback', 'Article Feedback'));
							}
						},
						{
							xtype:'button', text:$KB.LZ('Cancel', 'Cancel'),
							handler:function()
							{
								Ext.getCmp(thisObject.id + 'feedbackwindow').close();
							}
						}
					]
				}
			]
		});
		window.show();
	}
	this.externalNotes = function(notes)
	{
		var thisObject = this;
		$KB.HideArticleIFrame();
		var window = new Ext.Window(
		{
			renderTo:Ext.getBody(),
			id:this.id + 'externalnotes',
			closable: true,
			modal:true,
			width:400,
			height:350,
			title:$KB.LZ('Article_Notes', 'Article Notes'),
			bodyStyle:'padding:5px;',
			resizable:false,
			listeners:
			{
				close:function() {$KB.ShowArticleIFrame();}
			},
			items:
			[
				{
					xtype:'form',
					labelAlign:'top',
					bodyStyle:'background-color:transparent;',
					hideBorders:true,
					border:false,
					items:
					[
						{
							xtype:'textarea',
							id:thisObject.id + 'externalnotesTB',
							value:notes,
							readOnly:true,
							width:374,
							height:260,
							hideLabel:true
						}
					],
					buttons:
					[
						{
							xtype:'button', text:$KB.LZ('OK', 'OK'),
							handler:function()
							{
								Ext.getCmp(thisObject.id + 'externalnotes').close();
							}
						}
					]
				}
			]
		});
		window.show();
	}
	this.doSubscribe = function(window)
	{
		var thisObject = this;

		var emailTb = Ext.getCmp(thisObject.id + 'subscribewindowTB');
		var email = emailTb.getValue();
		if(emailTb.isValid())
		{
			DirectRequest.ArticleSubscribe(email, thisObject.aid, true, function(res,resp)
			{
				if(res == false)
				{
					$KB.alert($KB.LZ('Article_Subscribe_Err', 'Unable to subscribe to this article.  Please contact an administrator.'),$KB.LZ('Article_Subscribe', 'Article Subscription'), function() {Ext.getCmp(thisObject.id + 'subscribewindow').close();});
				}
				else
				{
					$KB.alert($KB.LZ('Article_Subscribe_Conf', 'You have subscribed to this article.'),$KB.LZ('Article_Subscribe', 'Article Subscription'), function() {Ext.getCmp(thisObject.id + 'subscribewindow').close();});
				}
			});
		}
		else $KB.alert($KB.LZ('Article_Subscribe_Invalid', 'Email is not valid.'),$KB.LZ('Article_Subscribe', 'Article Subscription'));
	}
	this.subscribe = function(email)
	{
		var thisObject = this;
		$KB.HideArticleIFrame();
		var window = new Ext.Window(
		{
			renderTo:Ext.getBody(),
			id:this.id + 'subscribewindow',
			layout:'fit',
			closable: true,
			modal:true,
			width: 325,
			height: 120,
			title:$KB.LZ('Article_Subscribe', 'Article Subscription'),
			resizable:false,
			listeners:
			{
				close:function() {$KB.ShowArticleIFrame();}
			},
			items:
			[
				{
					xtype:'form',
					labelAlign:'top',
					bodyStyle:'background-color:transparent;padding:4px;',
					hideBorders:true,
					border:false,
					items:
					[
						{
							xtype:'textfield',
							id:thisObject.id + 'subscribewindowTB',
							enableKeyEvents: true,
							anchor:'100%',
							fieldLabel:$KB.LZ('Email', 'Email'),
							labelSeparator:'',
							value:email,
							validator: function(val)
							{
								var re = new RegExp(".+\@.+\..+");
								if (re.test(val))
									return true;
								else
									return $KB.LZ("ATR_ValueInvalid","The value in this field is invalid");
							},
							listeners:
							{
								keypress:function(tf,e)
								{
									if(e.keyCode == 13)
									{
										thisObject.doSubscribe(window);
									}
								}
							}
						}
					],
					buttons:
					[
						{
							xtype:'button',text:$KB.LZ('Article_Subscribe_Btn', 'Subscribe'),
							id:thisObject.id + 'subscribewindowSubscribeBtn',
							handler:function()
							{
								thisObject.doSubscribe();
							}
						},{
							xtype:'button',text:$KB.LZ('Article_Unsubscribe_Btn', 'Unsubscribe'),
							handler:function()
							{
								var emailTB = Ext.getCmp(thisObject.id + 'subscribewindowTB');
								var email = emailTB.getValue();
								if(emailTB.isValid())
								{
									DirectRequest.ArticleSubscribe(email, thisObject.aid, false, function(res,resp)
									{
										if(res == false)
										{
											$KB.alert($KB.LZ('Article_Unsubscribe_Err', 'Unable to unsubscribe to this article.  Please contact an administrator.'),$KB.LZ('Article_Subscribe', 'Article Subscription'), function() {Ext.getCmp(thisObject.id + 'subscribewindow').close();});
										}
										else
										{
											$KB.alert($KB.LZ('Article_Unsubscribe_Conf', 'You have unsubscribed yourself from this article.'),$KB.LZ('Article_Subscribe', 'Article Subscription'), function() {Ext.getCmp(thisObject.id + 'subscribewindow').close();});
										}
									});
								}
								else $KB.alert($KB.LZ('Article_Subscribe_Invalid', 'Email is not valid.'),$KB.LZ('Article_Subscribe', 'Article Subscription'));
							}
						},
						{
							xtype:'button', text:$KB.LZ('Cancel', 'Cancel'),
							handler:function()
							{
								Ext.getCmp(thisObject.id + 'subscribewindow').close();
							}
						}
					]
				}
			]
		});
		window.show();
	}
	this.relatedLinks = function()
	{
		var rl = $KB[this.id + 'relatedLinks'];
		
		var itms = [];
		itms[0] =
		{
			xtype:'box',
			cls:'SD_ArtInfoTitle',
			autoEl:
			{
				tag:'div',
				html:$KB.LZ('Article_', 'Related Links for article #') + this.aid.toString() + ': "<span style="font-style:italic;">' + this.title + '</span>"'
			}
		};
		for(var x=0;x<rl.length;x++)
		{
			itms[x+1] =
			{
				xtype:'box',
				cls:'SD_ArtInfoLink',
				autoEl:
				{
					tag:'div',
					html:rl[x],
					onmouseover:'Ext.ux.btnMO(this,true);',
					onmouseout:'Ext.ux.btnMO(this,false);',
					onclick:'window.open(\'' + rl[x] + '\');'
				}
			};
		}
		$KB.HideArticleIFrame();
		var window = new Ext.Window
		(
			{
				renderTo:Ext.getBody(),
				id:this.id + 'relatedlinks',
				closable: true,
				modal:true,
				autoHeight:true,
				width: 500,
				title:$KB.LZ('Article_Related_Links', 'Related Links'),
				resizable:false,
				listeners:
				{
					close:function() {$KB.ShowArticleIFrame();}
				},
				items: 
				{
					xtype:'container',
					style:'padding:5px;',
					items:itms
				},
				buttons:
				{
					text:$KB.LZ('Close', 'Close'),
					handler:function()
					{
						window.close();
					}
				}
			}
		);
		window.show();
	}
	this.relatedGroups = function()
	{
		var rg = $KB[this.id + 'relatedGroups'];
		var itms = [];
		itms[0] =
		{
			xtype:'box',
			cls:'SD_ArtInfoTitle',
			autoEl:
			{
				tag:'div',
				html:$KB.LZ('Article_Related_Body', 'Related Articles for article #') + this.aid.toString() + ': "<span style="font-style:italic;">' + this.title + '</span>"'
			}
		};
		var pos = 1;
		for(var x=0;x<rg.length;x++)
		{
			itms[pos] =
			{
				xtype:'box',
				cls:'SD_ArtInfoRelatedGroup',
				autoEl:
				{
					tag:'div',
					html:(rg[x].GroupName.trim() == '') ? $KB.LZ('No_Category', '[No Category]') : rg[x].GroupName
				}
			};
			pos++;
			for(var y=0;y<rg[x].Articles.length;y++)
			{
				var art = rg[x].Articles[y];
				itms[pos] =
				{
					xtype:'box',
					cls:'SD_ArtInfoLink',
					autoEl:
					{
						tag:'div',
						html:art.Value,
						onmouseover:'Ext.ux.btnMO(this,true);',
						onmouseout:'Ext.ux.btnMO(this,false);',
						onclick:'$KB.' + this.id + 'articleLinkFn({ArticleId:' + art.Key + ',Title:\'' + $KB.escStr(art.Value) + '\',ShowToolbar:true,Source:\'Article\',ItemType:\'Article\'},function(){Ext.getCmp(\'' + this.id + 'relatedarticles\').close();});'
					}
				};
				pos++;
			}
		}
		$KB.HideArticleIFrame();
		var window = new Ext.Window
		(
			{
				renderTo:Ext.getBody(),
				id:this.id + 'relatedarticles',
				closable: true,
				modal:true,
				autoHeight:true,
				title:$KB.LZ('Article_Related', 'Related Articles'),
				width: 500,
				resizable:false,
				listeners:
				{
					close:function() {$KB.ShowArticleIFrame();}
				},
				items: 
				{
					xtype:'form',
					style:'padding:5px;',
					border:false,
					items:itms,
					buttons:
					{
						text:$KB.LZ('Close', 'Close'),
						handler:function()
						{
							window.close();
						}
					}
				}
			}
		);
		window.show();
	}
	this.articleClicked = function(params,fn,fromBack)
	{
		fromBack = $KB.FixNull(fromBack,false);
		if(fromBack)
		{
			var lastParams = me.lastArticlesParams.pop();
			me.articleLinkFn(lastParams,function(){},me.lastArticlesParams,me.articleClicked,fromBack);
		}
		else
		{
			me.lastArticlesParams.push({ArticleId:me.aid,Title:me.title,ShowToolbar:true,Source:'Article',ItemType:'Article'});
			me.articleLinkFn(params,fn,me.lastArticlesParams,me.articleClicked,fromBack);
		}
	}
	$KB[this.id + 'articleLinkFn'] = this.articleClicked;
	this.facebook = function() {window.open('http://www.facebook.com/share.php?u=' + this.getArticleShareUrl());}
	this.twitter = function() {window.open('http://www.twitter.com/home?status=Currently+reading+"' + this.title.replace(/ /g,'+') + '".+' + this.getArticleShareUrl());}
	this.digg = function() {window.open('http://www.digg.com/submit?phase=2&url=' + this.getArticleShareUrl());}
	this.delicious = function() {window.open('http://www.del.icio.us/post?url=' + this.getArticleShareUrl() + '&title=' + this.title);}
	this.editArticle = function()
	{
		window.open($KB.GlobalData.PortalProperties.AdminURL + "/index.aspx?aid=" + this.aid.toString());
	}
	this.edit = function()
	{
		switch(this.source.toLowerCase())
		{
			case 'wiki': 
				if(this.isSnapIn)
				{
					var url = location.protocol + '//' + location.host + '?WikiId=' + this.aid;
					window.open(url);
				}
				else $KB.open({WikiAction:'LoadWiki',WikiId:this.aid},'Wiki'); 
				break;
		}
	}
	this.setBtnVis = function(btn,visible)
	{
		switch(btn.toLowerCase())
		{
			case 'print': case 'printer': Ext.getCmp(this.id+'printdiv').setVisible(visible); this.visibility.Print = visible; break;
			case 'email': Ext.getCmp(this.id+'emaildiv').setVisible(visible); this.visibility.Email = visible; break;
			case 'download': Ext.getCmp(this.id+'downloaddiv').setVisible(visible); this.visibility.Download = visible; break;
			case 'copylink': case 'copy': case 'copyarticlelink': Ext.getCmp(this.id+'copylinkdiv').setVisible(visible); this.visibility.CopyLink = visible; break;
			case 'bookmark': Ext.getCmp(this.id+'bookmarkdiv').setVisible(visible); this.visibility.Bookmark = visible; break;
			case 'edit': Ext.getCmp(this.id+'editdiv').setVisible(visible); this.visibility.Edit = visible; break;
			case 'rate': case 'rating': this.ratingtool.Control.setVisible(visible); this.visibility.Rating = visible; break;
		}
	}
	//public methods
	this.SetButtonVisibility = function(btns,visible)
	{
		var isArray = btns instanceof Array;
		if(!isArray) this.setBtnVis(btns,visible);
		else
		{
			for(var i = 0; i< btns.length; i++)
			{
				var btn = btns[i];
				this.setBtnVis(btn,visible);
			}
		}
	}
	this.Destroy = function()
	{
		$KB[this.id + 'get'] = null;
		if(this.tb.ownerCt != null)
		{
			this.tb.ownerCt.remove(this.cont,true);
		}
	}
	this.setArticle = function(prms)
	{
		var thisObject = this;
		if( (prms.Title == '') || (this.infoPanel != null) || (prms.Source.toLowerCase() == 'faq'))
		{
			$KB.BuildArticleInfo(prms, thisObject);
		}
		else
		{
			this.title = prms.Title;
			this.aid = prms.Id;
			this.setArticleData(prms);
			if(this.onLoad != null) this.onLoad(this);
		}
	}
	this.setArticleData = function(prms)
	{
		this.source = prms.Source;
		this.component = prms.Component;
		this.isFrame = prms.IsFrame;
		this.db = $KB.FixNullorEmpty(prms.DB, '');
		this.query = $KB.FixNullorEmpty(prms.Query, '');
		var src = this.source.toLowerCase();
		if ( (src == "glossary") || (src == "sf") || (src == "rdb") || (src == "rs") || (src == "rfs") )
		{
			this.ratingtool = null;
			this.visibility.Rating = false;
		}
		if(src == 'wiki')
		{
			if(typeof(params.Visibility) != 'undefined')
			{
				this.visibility.Edit = $KB.FixNullorEmpty(params.Visibility.Edit, true);
			}
			else this.visibility.Edit = true;
		}
		else this.visibility.Edit = false;
		if(src == 'forum')
		{
			this.visibility.Download = false;
		}
		this.drawUI();
	}
	//initiate the object
	this.init();
}
$KB.HideArticleIFrame = function()
{
	var TabName = $KB.getCurrentTabName();
	if($KB.isNullOrEmpty(TabName)) return;
	var ns = $KB.TabManager.getNS(TabName);
	if($KB.isNullOrEmpty(ns)) return;
	if($KB.isNull(ns.ArticleIFrame)) return;
	if ($KB.isNull(ns.ArticleIFrame.el.dom)) return;
	ns.ArticleIFrame.hide();
}
$KB.ShowArticleIFrame = function()
{
	var TabName = $KB.getCurrentTabName();
	if($KB.isNullOrEmpty(TabName)) return;
	var ns = $KB.TabManager.getNS(TabName);
	if($KB.isNullOrEmpty(ns)) return;
	if($KB.isNull(ns.ArticleIFrame)) return;
	ns.ArticleIFrame.show();
}
$KB.RatingTool = function(params)
{
	params.source = $KB.FixNullorEmpty(params.source,'Article');
	params.container.add(new Ext.Container( { id:'Rate_' + params.source + '_' + params.sourceId + "_" + $KB.getCurrentTabId(), autoEl: {tag:'div', cls:"SD_rating" } }));
	params.container.doLayout();
	if ( !$KB.isNumeric(params.Positive) ||  !$KB.isNumeric(params.Negative) )
	{
		DirectRequest.GetArticleRating
		(
			params.sourceId, params.source,
			function (res, resp)
			{
				$KB.SetRating(res);
				params.container.doLayout(false,true);
			}
		);
	}
	else
	{
		$KB.SetRating(params);
	}
}
$KB.SetRating = function(params)
{
	var data = "{source:'" + params.source + "', sourceId:'" + params.sourceId + "'}";
	var enabled = !$KB.FixNull(params.disabled, false);
	var html = '<div class="SD_ratingItem"'
		if (enabled) html += $KB.BuildClick('$KB.RatingChange(' +  data + ',true);');
		html += 'title="' + $KB.LZ('Article_Rate_Like', '{0} viewers liked this article',[params.Positive]) + '"><span class="icon_thumbup">&nbsp;</span><div>' + params.Positive + '</div></div>' +
		'<div class="SD_ratingItem"'
		if (enabled) html +=  $KB.BuildClick('$KB.RatingChange(' +  data + ',false);');
		html += ' title="' + $KB.LZ('Article_Rate_Dislike', '{0} viewers disliked this article',[params.Negative]) +
		'"><span class="icon_thumbdown">&nbsp;</span><div>' + params.Negative + '</div></div>'
	var cmp = Ext.getCmp('Rate_' + params.source + '_' + params.sourceId + "_" + $KB.getCurrentTabId());
	cmp.removeAll(true);
	cmp.add(new Ext.BoxComponent({autoEl:{tag:'div',html:html}}));
	cmp.doLayout(false,true);
}
$KB.RatingChange = function(params, up)
{
	DirectRequest.SetArticleRating(params.sourceId, params.source, up, $KB.SetRating );
}
$KB.FixSplits = function (BaseElement, splitLineWidth)
{
	var x = BaseElement.el.dom.getElementsByTagName("div");
	for (var iX = 0; iX < x.length; iX++)
	{
		var ocn = x[iX].className;
		if (ocn.indexOf('x-layout-split') > -1)
		{
			if (ocn.indexOf("x-splitbar-v") > -1)
			{
				x[iX].bgMO = "#9FECFF";
				x[iX].bg = "#fcfcff";
				x[iX].style.height = splitLineWidth;
			}
			else
			{
				x[iX].bgMO = "#DEECFD";
				x[iX].bg = "#ffffff";
				x[iX].style.width = splitLineWidth;
			}
			x[iX].onmouseover = function () { this.style.backgroundColor=this.bgMO; };
			x[iX].onmouseout = function () { this.style.backgroundColor=this.bg; };
			x[iX].style.backgroundColor=x[iX].bg;
		}
	}
}
$KB.BuildArticleInfo = function(params, scope)
{
	DirectRequest.GetArticleInfo(params.Source, params.Id, function(res, resp)
	{
		scope.title = res.Title;
		scope.actualArticleId = res.ArticleId;
		scope.aid = res.ArticleId;
		scope.setArticleData(params);
		if (scope.infoPanel != null)
		{
			var content = '<div class="SD_ArtInfoMetadata CB"><span class="SD_ArtInfoLabel">' + $KB.LZ('ArticleId', 'Article Id') + '</span>  ' +
				res.ArticleId +
				 '<div class="SD_ArtInfoMetadata CB"><span class="SD_ArtInfoLabel">' + $KB.LZ('Article_Ext', 'Extension') + '</span>  ' +
				res.Extension +
				'</div><div class="SD_ArtInfoMetadata CB"><span class="SD_ArtInfoLabel">' + $KB.LZ('Article_Viewed', 'Article Viewed') + '</span>  ' +
				res.ArticleViewed +
				'</div><div class="SD_ArtInfoMetadata CB"><span class="SD_ArtInfoLabel">' + $KB.LZ('Article_Reviewed', 'Reviewed') + '</span>  ' +
				$KB.FixNullorEmpty(res.ArticleReviewed, $KB.LZ('Article_Never', 'Never')) + '</div>';
			if(res.Attachments.length != 0)
			{
				var atts = '<div style="margin-top:15px;" class="SD_ArtInfoLabel CB">' + $KB.LZ('Article_Attachments', 'Attachments') + '</div>';
				for(var j=0;j<res.Attachments.length;j++)
				{
					var spl = res.Attachments[j].split('.');
					var ext = '';
					if(spl.length>1) ext = '.' + spl[1];
					var iconClass = $KB.GetExtensionIconClass(ext);
					atts += '<div ' + $KB.BuildClick('$KB.' + scope.id + 'get.download(' + j.toString() + ');') + ' class="CL SD_ArtInfoAttachment"><div class="FL ' + iconClass + '"></div>' + $KB.escTag(res.Attachments[j]) + '</div>';
				}
				content = content + atts;
			}
			var catPanel = null;
			if( (res.Categories.trim() != '') && ($KB.GlobalData.PortalArticleInfo.ArticleCategorization) )
			{
				var cats = '<div style="margin-top:15px;" class="SD_ArtInfoLabel CB">' + $KB.LZ('Article_Categories', 'Categories') + '</div><div class="SD_ArtInfoCategoryItem">' + $KB.escTag(res.Categories).replace(/#!#/g,'</div><div class="SD_ArtInfoCategoryItem">') + '</div>';
				catPanel = new Ext.BoxComponent({autoEl:{tag:'div',html:cats},width:192});
			}
			scope.infoPanel.removeAll(true);
			var pnl1 = new Ext.BoxComponent
			(
				{
					autoEl:
					{
						tag:'div',
						html:content
					},
					width:192
				}
			);
			var spacer = { xtype:'box', height:10 };
			scope.infoPanel.add(pnl1);
			scope.infoPanel.add(spacer);
			
			$KB[scope.id + 'relatedLinks'] = res.RelatedLinks;
			$KB[scope.id + 'relatedGroups'] = res.RelatedGroups;
			if(res.RelatedLinks.length > 0)
			{
				var rl = new Ext.BoxComponent
				(
					{
						cls:'SD_ArtInfoPopout CB',
						autoEl:
						{
							tag:'div',
							html:'<span onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);" class="SD_ArtInfoPopout" ><div title="' + $KB.LZ('Article_Related_Links', 'Related Links') + '" class="SD_ArtInfoPopoutImage icon_popuplink"></div>' + $KB.LZ('Article_Related_Links', 'Related Links') + '</span>',
							onclick:'$KB[\'' + scope.id + 'get\'].relatedLinks();'
						}
					}
				);
				scope.infoPanel.add(rl);
			}
			if( (res.RelatedGroups.length > 0) && (scope.articleLinkFn != null) )
			{
				var rg = new Ext.BoxComponent
				(
					{
						cls:'SD_ArtInfoPopout CB',
						autoEl:
						{
							tag:'div',
							html:'<span onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);" class="SD_ArtInfoPopout" ><div title="' + $KB.LZ('Article_Related', 'Related Articles') + '" class="SD_ArtInfoPopoutImage icon_popuplink"></div>' + $KB.LZ('Article_Related', 'Related Articles') + '</span>',
							onclick:'$KB[\'' + scope.id + 'get\'].relatedGroups();'
						}
					}
				);
				scope.infoPanel.add(rg);
			}
			
			scope.infoPanel.add(spacer);		
			
					//"subscribe,notes,editArticle,suggest,suggestEmail,articleCat"
			var oItms = $KB.GlobalData.PortalArticleInfo.Order.split(',');
			var subscribeO = null;
			var notesO = null;
			var editO = null;
			var suggestO = null;
			var suggestEmailO = null;
			if($KB.GlobalData.PortalArticleInfo.ExternalNotes)
			{
				notesO = new Ext.BoxComponent
				(
					{
						cls:'SD_ArtInfoPopout CB',
						autoEl:
						{
							tag:'div',
							html:'<span onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);" class="SD_ArtInfoPopout" ><div title="' + $KB.LZ("Notes","Notes") + '" class="SD_ArtInfoPopoutImage icon_popuplink"></div>' + $KB.LZ("Notes","Notes") + '</span>',
							onclick:'$KB[\'' + scope.id + 'get\'].externalNotes(\'' + $KB.escStr($KB.FixNullorEmpty(res.ExternalNotes,'')) + '\');'
						}
					}
				);
			}
			if($KB.GlobalData.PortalArticleInfo.ArticleSubscription && res.SubscriptionEnabled)
			{
				subscribeO = new Ext.BoxComponent
				(
					{
						cls:'SD_ArtInfoPopout CB',
						autoEl:
						{
							tag:'div',
							html:'<span onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);" class="SD_ArtInfoPopout" ><div title="' + $KB.LZ('Article_Subscribe', 'Article Subscription') + '" class="SD_ArtInfoPopoutImage icon_popuplink"></div>' + $KB.LZ('Article_Subscribe', 'Article Subscription') + '</span>',
							onclick:'$KB[\'' + scope.id + 'get\'].subscribe(\'' + $KB.escStr($KB.FixNullorEmpty(res.EmailSubscription,'')) + '\');'
						}
					}
				);
			}
			if($KB.GlobalData.PortalArticleInfo.ArticleSuggestion)
			{
				suggestO = new Ext.BoxComponent
				(
					{
						cls:'SD_ArtInfoPopout CB',
						autoEl:
						{
							tag:'div',
							html:'<span onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);" class="SD_ArtInfoPopout" ><div title="' + $KB.LZ('Article_Feedback', 'Article Feedback') + '" class="SD_ArtInfoPopoutImage icon_popuplink"></div>' + $KB.LZ('Article_Feedback', 'Article Feedback') + '</span>',
							onclick:'$KB[\'' + scope.id + 'get\'].feedback();'
						}
					}
				);
			}
			if($KB.GlobalData.PortalArticleInfo.EditArticle)
			{
				editO = new Ext.BoxComponent
				(
					{
						cls:'SD_ArtInfoPopout CB',
						autoEl:
						{
							tag:'div',
							html:'<span onmouseover="Ext.ux.btnMO(this,true);" onmouseout="Ext.ux.btnMO(this,false);" class="SD_ArtInfoPopout" ><div title="' + $KB.LZ('Article_Edit', 'Edit Article') + '" class="SD_ArtInfoPopoutImage icon_popuplink"></div>' + $KB.LZ('Article_Edit', 'Edit Article') + '</span>',
							onclick:'$KB[\'' + scope.id + 'get\'].editArticle();'
						}
					}
				);
			}
			for(var x =0;x<oItms.length;x++)
			{
				var oi = oItms[x];
				switch(oi.toLowerCase())
				{
					case 'subscribe':
						if(subscribeO != null) scope.infoPanel.add(subscribeO);
						break;
					case 'notes':
						if(notesO != null) scope.infoPanel.add(notesO);
						break;
					case 'suggest':
						if(suggestO != null) scope.infoPanel.add(suggestO);
						break;
					case 'editarticle':
						if(editO != null) scope.infoPanel.add(editO);
						break;
					case 'articlecat':
						if(catPanel != null) scope.infoPanel.add(catPanel);
						break;
				}
			}
			scope.infoPanel.doLayout(false,true);
		}
		if(scope.onLoad != null) scope.onLoad(scope);
	});
}
$KB.UserManagement = function(params)
{
	this.id = params.Id;
	this.parent = params.Parent;
	this.anchor = $KB.FixNullorEmpty(params.Anchor,'0 0');
	this.session = $KB.FixNullorEmpty(params.Session,'userManagement');
	this.source = $KB.FixNullorEmpty(params.Source,'forum');
	this.addGrid = function(filter,sortBy,dir)
	{
		
		var thisObject = this;
		this.removeFilterButton= new Ext.Button(
			{
				text: 'Remove Filters',
				cls: '',
				handler: function()
				{
					thisObject.parent.remove(thisObject.grid,true);
					thisObject.addGrid('','','asc');
				}
			 }
		);
		this.removeSearchFilter = function()
		{
			if (Ext.get(thisObject.id+ 'searchtb').dom.value == $KB.LZ('Users_Search', 'Search All Users...'))
			{
				thisObject.parent.remove(thisObject.grid,true);
				thisObject.addGrid('','','asc');
			} else
			{
				var text = Ext.get(thisObject.id+ 'searchtb').dom.value
				thisObject.parent.remove(thisObject.grid,true);
				thisObject.addGrid(text,'','asc');
			}
		}
		var params = { session:this.session,filter:filter,sortBy:sortBy,dir:dir,start: 0, limit: 25 };
		this.store = new Ext.data.DirectStore
		({
			directFn: DirectRequest.GetUserManagementItems,
			id:this.id + 'store',
			paramsAsHash: false,
			paramOrder: 'session,filter,sortBy,dir,start,limit',
			baseParams: params,
			idProperty: 'UserId',
			totalProperty: 'Count',
			root: 'Items',
			autoLoad: true,
			fields:
			[
				{name: 'UserId', type: 'int'},
				{name: 'Username', type: 'string'},
				{name: 'LastName', type: 'string'},
				{name: 'FirstName', type: 'string'},
				{name: 'EmailAddress', type: 'string'},
				{name: 'Suspended', type: 'boolean'}
			]
		});
		this.grid = new Ext.grid.GridPanel({
			store: this.store,
			id:this.id + 'grid',
			anchor:'0 -40',
			tbar: new Ext.ux.PagingToolbar({
				store: this.store,
				displayInfo: true,
				pageSize: 25,
				prependButtons: true,
				doRefresh: this.removeSearchFilter,
				displayMsg: $KB.LZ('PagingToolbar_Displaying', 'Displaying {0} - {1} of {2}'),
				firstText: $KB.LZ('PagingToolbar_First_Page', 'First Page'),
				lastText: $KB.LZ('PagingToolbar_Last_Page', 'Last Page'),
				prevText: $KB.LZ('PagingToolbar_Previous_Page', 'Previous Page'),
				nextText: $KB.LZ('PagingToolbar_Next_Page', 'Next Page'),
				refreshText: $KB.LZ('PagingToolbar_Refresh', 'Refresh'),
				beforePageText: $KB.LZ('PagingToolbar_Before_Page_Text', 'Page'),
				afterPageText: $KB.LZ('PagingToolbar_After_Page_Text', 'of {0}')
			}),
			columns: [
				{header: $KB.LZ('Users_Username', "Username"), width: 200, dataIndex: 'Username', sortable: true},
				{header: $KB.LZ('Last_Name', "Last Name"), width: 120, dataIndex: 'LastName', sortable: true},
				{header: $KB.LZ('First_Name', "First Name"), width: 100, dataIndex: 'FirstName', sortable: true},
				{header: $KB.LZ('Users_Email', "Email Address"), width: 120, dataIndex: 'EmailAddress', sortable: true},
				{header: $KB.LZ('Users_Status', "Status"), width: 40, dataIndex: 'Suspended', renderer: {fn:this.statusRender,scope:this}, sortable: true, resizable:false}
			]
		});
		this.cont = new Ext.Container(
		{
			id:this.id,
			anchor:this.anchor,
			layout:'anchor',
			items:
			[
				{
					xtype:'container',
					height:35,
					id:this.id+'top'
				},
				this.grid
			]
		});
		this.searchControl = new $KB.SearchControl({
			Id:thisObject.id + 'search',
			Width:400,
			Parent:Ext.getCmp(thisObject.id + 'top'),
			SearchClicked: function(text) {
				if(text != $KB.LZ('Users_Search', 'Search All Users...'))
				{
					thisObject.parent.remove(thisObject.grid,true);
					thisObject.addGrid(text,'','asc');
				}
				Ext.get(thisObject.id+ 'searchtb').dom.value = text;
			},
			EmptyText: $KB.LZ('Users_Search', 'Search All Users...')
		});
		this.parent.add(this.cont);
		this.parent.doLayout(false,true);
	}
	$KB[this.id + 'changeStatus'] = function(userId,source,status,thisId,rowIndex)
	{
		if($KB.GlobalData.User.UserID == userId) return;
		var directR = status ? DirectRequest.RestoreUsers : DirectRequest.SuspendUsers;
		var profilemanage;
		if (source == 'wiki')
		{
			profilemanage = $KB.GlobalData.User.Profile.WikiManagement;
			if( (!profilemanage.Restore) && status) 
			{ 
				return; 
			}
			if( (!profilemanage.Suspend) && (!status) ) 
			{
				  return; 
			}
		} else if (source == 'forum')
		{
			profilemanage = $KB.GlobalData.User.Profile.ForumManagement;
			if( (!profilemanage.RestoreForumPost) && status) 
			{ 
				return; 
			}
			if( (!profilemanage.SuspendForumPost) && (!status) ) 
			{
				  return; 
			}
		}
		directR(userId.toString(),source,function(res,resp)
		{
			var rec = Ext.StoreMgr.get(thisId + 'store').getAt(rowIndex);
			rec.set('Suspended',!status);
			rec.commit();
		});
	}
	this.statusRender = function(value, p, r, ri, ci, st)
	{
		var color = ((r.data.Suspended == true) ? 'red' : 'green');
		var bt = ((r.data.Suspended == true) ? 'inset' : 'outset');
		var tt = ((r.data.Suspended == true) ? $KB.LZ('Users_Suspended', 'Status is "Suspended"') : $KB.LZ('Users_Active', 'Status is "Active"'));
		var s = String.format
		(
			'<div style=\'text-align:center;\'><div title=\'' + tt + '\' id=\'' + this.id + 'row{1}\' onclick="$KB.' + this.id + 'changeStatus({1},\'' + this.source + '\',{0},\'' + this.id + '\',' + ri + ');" style="cursor:pointer;width:15px;height:10px;background-color:' + color + ';border:3px ' + bt + ';"></div></div>',
			r.data.Suspended,
			r.data.UserId
		);
		return s;
	}
	this.init = function()
	{
		var thisObject = this;
		DirectRequest.GetUserManagement
		(
			this.session,this.source,function(res,resp)
			{
				thisObject.addGrid('','','asc');
			}
		);
	}
	this.Destroy = function()
	{
		$KB[this.id + 'changeStatus'] = null;
		this.parent.remove(this.grid,true);
	}
	this.init();
}

$KB.BuildURL = function(baseURL)
{
	var x = (baseURL + "?").split("?");
	var p = [ "?" + x[1] ];
	p.push("PortalId=" + $KB.Settings.GlobalData.PortalProperties.PortalId);
	p.push("ClientId=" + $KB.Settings.GlobalData.PortalProperties.ClientId);
	return x[0] + p.join("&");
}

$KB.LogInOut = function(params, btn)
{
	if (Ext.isDefined(btn))
	{
		if (btn.disabled) return;
		Ext.ux.btnDisable(btn, true);
	}
	if ($KB.LoggedIn)
	{
		switch ($KB.Settings.PortalType)
		{
			case "Secure" : case "Personalize":
				window.location =  $KB.BuildURL("/kb/index?logout=true");
				break;
			default:
				$KB.LoggedIn = false;
				DirectRequest.LogOut
				( 
					function() 
					{ 
						$KB.SetUserData(null); 
						if (Ext.isDefined(btn)){ Ext.ux.btnDisable(btn, false) }; 
					}
				)
				break;
		}
	}
	else
	{
		$KB.LoginParams.modal = true;
		$KB.LoginParams.ForceLogin = true,
		$KB.LoginParams.relTo = $KB.FixNullorEmpty(params.relTo, null);
		$KB.LoginParams.OnValidLogin = function(action)
		{
			$KB.SetUserData(action.result.User);
			$KB.ExecIf(params.onLogin);
		};
		$KB.LoginParams.OnClose = function()
		{
			if (Ext.isDefined(btn)){ Ext.ux.btnDisable(btn, false) };
		}
		$KB.OpenViewScript($KB.BuildURL('/kb/login'), $KB.Login);
	}
};
$KB.right = function(str, n)
{
	var s = $KB.FixNullorEmpty(str, "");
	if (!(n < s.length)) return s;
	return s.substr(s.length-n, n);
}
$KB.open = function(params, ActiveTab)
{
	var TabName = $KB.FixNull(ActiveTab, $KB.getCurrentTabName());
	$KB.CurrentParams = $KB.FixParams
	(
		params,
		[
			'ArticleId','ClientId','ForumId','GlossaryId',
			'TermId','IntegrationSearch','anchor','PostId','CategoryId',
			'SFId','SFCId','TabId','ThreadId','WikiAction','WikiId','SearchId','Source'
		],
		'Id'
	);
	if ($KB.CurrentParams.TabId != null)
	{
		TabName = $KB.CurrentParams.TabId;
	}
	else
	{
		var newTabName = "";
		for (var key in $KB.CurrentParams)
		{
			if (($KB.CurrentParams[key] != null))
			{
				switch (key)
				{
					case 'GlossaryId': case 'TermId':
						newTabName='glossary'
						break;
					case 'PostId': case 'ForumId': case 'ThreadId':
						newTabName='forum';
						break;
					case 'WikiId': case 'WikiAction':
						newTabName='wiki';
						break;
					case 'ArticleId':
						if(TabName != 'category') newTabName='home';					
						break;
					case 'CategoryId':
						newTabName='category';
						break;
					case 'SFId': case 'SFCId':
						newTabName = 'SF'
						break;
					case 'IntegrationSearch':
						newTabName = 'home'
						break;
					case 'Source':
						switch($KB.CurrentParams[key].toLowerCase())
						{
							case 'wiki':
								newTabName = 'wiki';
								$KB.CurrentParams.WikiAction = 'loadwiki';
								$KB.CurrentParams.WikiId = $KB.CurrentParams.ArticleId;
								break;					
						}
						break;
				}
			}
			if (newTabName != "")
			{
				TabName = newTabName;
				break;
			 }
		}
	}
	var ns = $KB.TabManager.getNS(TabName);
	$KB.TabManager.setActiveTab(TabName);
	if (ns != null) ns.open($KB.CurrentParams)
}
$KB.MatchByName = function(x, matchArr)
{
	var i = matchArr.join("~").toLowerCase().split("~").indexOf(x.toLowerCase());
	return (i > -1) ? matchArr[i] : "";
}
$KB.CheckBoolResponse = function(response, caughtError, unCaughtError)
{
	var r = response.result;
	if(response.status == true)
	{
		if(!r.IsError)
		{
			if(r.Value == true)
			{
				return true;
			}
		}
		else
		{
			if(typeof(caughtError) != 'undefined') caughtError(r);
			else $KB.alert(r.Message);
		}
	}
	else
	{
		if(typeof(unCaughtError) != 'undefined') unCaughtError(null);
		else $KB.alert($KB.LZ('errGeneral', 'An unknown error has occurred.'));
	}
	return false;
}
$KB.showSearchBar = function(bShow)
{
	var h1 = 0;
	var id = $KB.getCurrentTabName();
	var c1 = Ext.getCmp(id + 'TabSearch');
	var h2 = 25;
	if (!Ext.isDefined(bShow) && $KB.isNull(c1))
	{
		bShow = false;
		h1 = 2;
		h2 = 25;
	}
	else
	{
		bShow = $KB.FixNull(bShow, !c1.hidden);
		c1.setVisible(bShow);
		h1 = bShow ? c1.getHeight() : 0;
		var c2 = Ext.getCmp(id + 'Bar');
		h2 = c2.getHeight();
	}
	var p = Ext.getCmp(id + 'TabTopBars');
	p.setHeight(h1 + h2);
	p.ownerCt.doLayout();
}
$KB.CheckValueResponse = function(response, caughtError, unCaughtError)
{
	var r = response.result;
	if(response.status == true)
	{
		if(!r.IsError)
		{
			return true;
		}
		else
		{
			if(r.ErrorType == 2)//Session Timeout
			{
				var pt = $KB.Settings.PortalType.toLowerCase();
				if((pt == 'personalize') || (pt == 'secure')) window.location =  $KB.BuildURL("/kb/index?logout=true");
			}
			if(typeof(caughtError) != 'undefined') caughtError(r);
			else $KB.alert(r.Message);
		}
	}
	else
	{
		if(typeof(unCaughtError) != 'undefined') unCaughtError(null);
		else $KB.alert($KB.LZ('errGeneral', 'An unknown error has occurred.'));
	}
	return false;
}
$KB.CheckVoidResponse = function(response, caughtError, unCaughtError)
{
	if(response.status == true)
	{
		return true;
	}
	else
	{
		if(typeof(unCaughtError) != 'undefined') unCaughtError(null);
		else $KB.alert($KB.LZ('errGeneral', 'An unknown error has occurred.'));
	}
	return false;
}
$KB.CreateCustomControls = function()
{
	Ext.QuickTips.init();
	if($KB.isNull(Ext.ux.PagingToolbar))
	{
		Ext.ux.PagingToolbar = Ext.extend(Ext.PagingToolbar,
		{
			constructor: function(config)
			{
				Ext.apply(this,
				{
					displayMsg: $KB.LZ('PagingToolbar_Displaying', 'Displaying {0} - {1} of {2}'),
					firstText: $KB.LZ('PagingToolbar_First_Page', 'First Page'),
					lastText: $KB.LZ('PagingToolbar_Last_Page', 'Last Page'),
					prevText: $KB.LZ('PagingToolbar_Previous_Page', 'Previous Page'),
					nextText: $KB.LZ('PagingToolbar_Next_Page', 'Next Page'),
					refreshText: $KB.LZ('PagingToolbar_Refresh', 'Refresh'),
					beforePageText: $KB.LZ('PagingToolbar_Before_Page_Text', 'Page'),
					afterPageText: $KB.LZ('PagingToolbar_After_Page_Text', 'of {0}')
				});
				Ext.ux.PagingToolbar.superclass.constructor.apply(this, arguments);
			}
		});
		Ext.reg('kbpagingtoolbar', Ext.ux.PagingToolbar);
	}
	if($KB.isNull(Ext.ux.AutoSuggestTextBox))
	{
		Ext.ux.AutoSuggestTextBox = Ext.extend(Ext.form.TextField,
		{
			enableKeyEvents:true,
			constructor: function(config)
			{
				var me = this;
				me.popupCls = $KB.FixNull(config.popupCls,'SD_AutoSuggestTBPopup');
				me.popupItemCls = $KB.FixNull(config.popupHighlightCls,'SD_AutoSuggestItem');
				me.popupHighlightCls = $KB.FixNull(config.popupHighlightCls,'SD_AutoSuggestItemHighlight');
				me.waitBuffer = $KB.FixNull(config.waitBuffer,500);
				me.outFunction = $KB.FixNull(config.outFunction,function(){alert('An outFunction must be set.');});
				me.clickFunction = $KB.FixNull(config.clickFunction,null);
				me.lastUpdate = null;
				me.lastValues = [];
				me.itmDiv = [];
				me.divToIndex = {};
				me.doTest = true;
				me.selected = -1;
				me.lastKey = null;
				me.lastWasText = true;
				//internal methods
				var ss = '';
				me.getPosition = function(obj)
				{
					var topValue= 0,leftValue= 0;
					while(obj){
					leftValue+= obj.offsetLeft;
					topValue+= obj.offsetTop;
					obj= obj.offsetParent;
					}
					finalvalue = {x:leftValue,y:topValue};
					return finalvalue;
				}
				me.hidePopup = function()
				{
					me.selected=-1;
					me.popup.style.visibility = 'hidden';
					me.doTest = false;
				}

				me.updateValues = function(values,update)
				{
					var go = false;
					if(me.lastUpdate == null) go = true;
					else if(update>lastUpdate) go = true;
					if((values.length != null) && go)
					{
						me.lastValues = values;
						me.selected = -1;
						var p = me.getPosition(me.tb);
						me.popup.style.left = p.x.toString() + 'px';
						me.popup.style.top = (p.y + me.tb.offsetHeight).toString() + 'px';
						me.popup.style.width = me.tb.offsetWidth + 'px';
						me.itmDiv = [];
						me.divToIndex = {};
						while(me.popup.firstChild){
							me.popup.removeChild(me.popup.firstChild);
						}
						
						var c = '';
						for(var i=0;i<values.length;i++)
						{
							var itm = values[i];
							var div1 = document.createElement('div');
							var id = 'autoSuggestDiv' + $KB.GetNextId();
							me.divToIndex[id] = i;
							div1.id = id;
							div1.onmousedown = function(e)
							{
								if (!e) var e = window.event;
								var ele = e.srcElement;
								if($KB.isNull(ele))
								{
									var node = e.target;
									while(node.nodeType != node.ELEMENT_NODE)
										node = node.parentNode;
									ele = node;	
								}
								var ind = me.divToIndex[ele.id];
								if(ind == null) ind = me.divToIndex[ele.parentNode.id];
								if(ind != null)
								{
									var val = me.lastValues[ind].Key;
									me.setValue(val);
									setTimeout(function(){me.tb.focus();me.selectText(val.length,val.length);if(me.clickFunction != null) me.clickFunction();},100);
								}
							}
							div1.onmouseover = function(e)
							{
								if (!e) var e = window.event;
								var ele = $KB.FixNull(e.toElement,e.target);
								var ind = me.divToIndex[ele.id];
								if(ind == null) ind = me.divToIndex[ele.parentNode.id];
								if(ind != null)
								{
									me.selected = ind;
									me.highlight(ind,false);
								}
							}
							if(me.popupItemCls != null) $DOM.SetClass(div1,me.popupItemCls);
							var div2 = document.createElement('div');
							div2.onmouseover = function(e){};
							$DOM.SetClass(div2,"FL");
							div2.innerHTML = itm.Key;
							var div3 = document.createElement('div');
							div3.onmouseover = function(e){};
							$DOM.SetClass(div3,"FR");
							div3.innerHTML = (itm.Value == -1 ? '' : 
									( (itm.Value == 1) ? $KB.LZ('CPL_Search_Clues_Single_Count','searched {0} time',['<b>1</b>']) : 
										$KB.LZ('CPL_Search_Clues_Single_Count','searched {0} times', ['<b>'+itm.Value+'</b>'])) );
							div1.appendChild(div2);
							div1.appendChild(div3);
							me.popup.appendChild(div1);
							me.itmDiv[i] = div1;			
						}
						me.doTest = true;
						me.popup.style.visibility = 'visible';
						me.currentTab = Ext.getCmp('kbParentTabPanel').getActiveTab();
						if(!Ext.isIE) me.test();
					}
				}
				me.test = function()
				{
					if(me.doTest)
					{
						if(Ext.getCmp('kbParentTabPanel').getActiveTab() == me.currentTab) setTimeout(me.test,200);
						else me.hidePopup();
					}
				}
				me.highlight = function(pos,setValue)
				{
					var c = '';
					setValue = $KB.FixNull(setValue,true);
					for(var i=0;i<me.lastValues.length;i++)
					{
						var itm = me.lastValues[i];
						if(i==pos)
						{
							if(me.popupHighlightCls != null)
							{
								$DOM.SetClass(me.itmDiv[i],me.popupHighlightCls);
							}
							else
							{
								me.itmDiv[i].style.overflow='hidden';
								me.itmDiv[i].style.clear='both';
								me.itmDiv[i].style.backgroundColor='#d5e2ff';
								me.itmDiv[i].style.color='#000000';
								me.itmDiv[i].style.fontWeight='bold';
							}
							if(setValue) me.tb.value = itm.Key;
						}
						else
						{
							if(me.popupHighlightCls != null)
							{
								$DOM.SetClass(me.itmDiv[i],me.popupItemCls);
							}
							else
							{
								me.itmDiv[i].style.overflow='inherit';
								me.itmDiv[i].style.clear='inherit';
								me.itmDiv[i].style.backgroundColor='inherit';
								me.itmDiv[i].style.color='inherit';
								me.itmDiv[i].style.fontWeight='inherit';
							}
						}
					}
				}
				//create popup div
				var pu = document.createElement('div');
				pu.style.position = 'absolute';
				pu.style.left = '0px';
				pu.style.top = '0px';
				pu.style.visibility = 'hidden';
				if(me.popupCls != null) pu.className = me.popupCls;
				else
				{
					pu.style.backgroundColor = '#ffffff';
					pu.style.border = '1px solid #598ee3';
					pu.style.color = '#000000';
					pu.style.fontWeight = 'bold';
				}
				pu.style.zIndex = '99999';
				document.body.appendChild(pu);
				me.popup = pu;
				
				Ext.apply(this,
				{
					xtype:'kbautosuggesttextbox'
				});
				
				Ext.ux.AutoSuggestTextBox.superclass.constructor.apply(this,arguments);
				this.on({
					keydown:function(tf,e)
					{
						me.lastWasText = true;
						switch(e.keyCode)
						{
							case 13: case 27:
								me.hidePopup();
								me.lastWasText = false;
								break;
							case 40:
								me.selected++;
								if(me.selected >= me.lastValues.length) me.selected = 0;
								me.highlight(me.selected);
								me.lastWasText = false;
								break;
							case 38:
								me.selected--;
								if(me.selected < 0) me.selected = me.lastValues.length-1;
								me.highlight(me.selected);
								me.lastWasText = false;
								break;
						}
						me.lastKey = e.keyCode;
					},
					keyup:function(tf,e)
					{
						me.lastKey = e.keyCode;
						switch(e.keyCode)
						{
							case 40:
								break;
							case 38:
								break;
							case 13:
								break;
							default:
								me.lastTime = new Date();
								if(tf.getValue() == '')
								{
									me.hidePopup();
									return;
								}
								setTimeout
								(
									function() 
									{
										var curDate = new Date(); 
										if( (curDate-me.lastTime) >= me.waitBuffer)
										{
											if(!me.lastWasText) return;
											var val = tf.getValue();
											me.outFunction(val,function(res,resp)
											{
												var arr = [];
												var addVal = true;
												for(var x=0;x<res.length;x++)
												{
													arr.push(res[x]);
													if(res[x].Key.toLowerCase() == val.toLowerCase()) addVal = false;
												}
												if(addVal) arr.push({Key:val,Value:-1});
												me.updateValues(arr,curDate);
											});
										}
									},
									me.waitBuffer + 50
								);
								break;
						}
					},
					afterrender:function(cmp)
					{
						me.tb = cmp.el.dom;
					},
					blur:function()
					{
						me.hidePopup();
					}
				});
			}
		});
		Ext.reg('kbautosuggesttextbox', Ext.ux.AutoSuggestTextBox);
	}
}
$KB.LZ = function(key, defaultString, variables)
{
	var str = $KB.FixNullorEmpty($KB.GlobalData.Localization[key], defaultString);
	if(typeof(variables) != 'undefined')
	{
		for(var i = 0; i<variables.length; i++)
		{
			str = str.replace('{' + i.toString() + '}',variables[i]);
		}
	}
	return str;
}
$KB.IsPositiveInt32 = function(v)
{
	for(var i=0;i<v.length;i++)
	{
		var c = v.charCodeAt(i);
		if(c<48 || c>57) return false;
	}
	var num = parseInt(v);
	if( (num>=0) && (num<2147483648) ) return true;
	return false;
}
$KB.Init = function(BlankImgUrl)
{
	Ext.BLANK_IMAGE_URL = BlankImgUrl;
	Ext.UpdateManager.defaults.loadScripts = true;
	Ext.Direct.addProvider($KB.Request);
	
	$KB.Cookie = new $KB.CookieData();
	Ext.overrideIf = function(origclass, overrides)
	{
		if(overrides)
		{
			var p = origclass.prototype;
			for(var method in overrides)
			{
				if(!p[method])
				{
					p[method] = overrides[method];
				}
			}
		}
	};
	Ext.overrideIf
	(
		Array,
		{
			copy:function()
			{
				var a = [];
				for (var i = 0, l = this.length; i < l; i++)
				{
					a.push(this[i]);
				}
				return a;
			},
			indexOf:function(v, b)
			{
				for (var i = +b || 0, l = this.length; i < l; i++)
				{
					if(this[i] === v)
					{
						return i;
					}
				}
				return -1;
			},
			intersect:function()
			{
				if(!arguments.length)
				{
					return [];
				}
				var a1 = this, a2, a;
				for (var k = 0, ac = arguments.length; k < ac; k++)
				{
					a = [];
					a2 = arguments[k] || [];
					for (var i = 0, l = a1.length; i < l; i++)
					{
						if (-1 < a2.indexOf(a1[i]))
						{
							a.push(a1[i]);
						}
					}
					a1 = a;
				}
				return a.unique();
			},
			lastIndexOf:function(v, b)
			{
				b = +b || 0;
				var i = this.length;
				while (i-- > b)
				{
					if(this[i] === v)
					{
						return i;
					}
				}
				return -1;
			},
			union:function()
			{
				var a = this.copy(), a1;
				for (var k = 0, ac = arguments.length; k < ac; k++)
				{
					a1 = arguments[k] || [];
					for(var i = 0, l = a1.length; i < l; i++)
					{
						a.push(a1[i]);
					}
				}
				return a.unique();
			},
			unique:function()
			{
				var a = [], i, l = this.length;
				for (i = 0; i < l; i++)
				{
					if (a.indexOf(this[i]) < 0)
					{
						a.push(this[i]);
					}
				}
				return a;
			}
		}
	);
}
$KB.WriteViewPort = function(BodyElement, WriteUserLogout)
{
	var columns = 1;
	$KB.Settings.PortalStyle = $KB.FixNullorEmpty($KB.Settings.PortalStyle, []);
	var topBottomFill = $KB.FixNull($KB.Settings.PortalStyle.topBottomFill,'tabs');
	var AppWidth = $KB.FixNullorEmpty($KB.Settings.PortalStyle.width, 0);
	var HasSidePanels = (AppWidth > 0);
	
	var HasPanel = {};
	HasPanel.west = false;
	HasPanel.east = false;
	
	function calcWidth(wBody)
	{
		var width = Math.max(wBody - AppWidth, 0)
		if (HasPanel.west && HasPanel.east) width = Math.floor(width/2);
		return width
	}
	var AppBody = [ BodyElement ];
	var ViewPortItems = [];
	Ext.each
	(
		['north','south'], 
		function (region)
		{
			var ac = $KB.Settings.PortalStyle.appConfig[region];
			var panel = new Ext.Panel(item);
			
			var v = ac.height;
			HasPanel[region] = (v != "none");
			if (HasPanel[region])
			{
				var item = 
				{
					border: false,
					region: region,
					preventBodyReset: true,
					id: 'Content_' + region
				};
				if (v == "auto")
				{
					item.xtype = 'panel';
					item.autoHeight = true;
				}
				else
				{
					item.xtype = 'container',
					item.height = v;
				}
				item.bodyStyle = ac.bodyStyle;
				if(topBottomFill == 'tabs') AppBody.push(item);
				else if (topBottomFill == 'page') ViewPortItems.push(item);
			}
		}
	);
	
	if (HasSidePanels)
	{
		switch ($KB.FixNullorEmpty($KB.Settings.PortalStyle.mode, 'center'))
		{
			case 'center':
				HasPanel.west = true;
				HasPanel.east = true;
				break;
			case 'left':
				HasPanel.east = true;
				break;
			case 'right':
				HasPanel.west = true;
				break;
		}
		var SideWidth = calcWidth(Ext.getBody().getWidth());
		var sc = $KB.FixNullorEmpty($KB.Settings.PortalStyle.sideConfig, []);
		
		Ext.each
		(
			['west','east'],
			function (region)
			{
				if (HasPanel[region])
				{
					var item = { region: region, width: SideWidth, id: 'Content_' + region, preventBodyReset: true};
					$KB.copyProps(sc[region], item);
					ViewPortItems.push(item);
				}
			}
		);
		ViewPortItems.push
		(
			new Ext.Panel
			(
				{
					width: AppWidth,
					bodyStyle: 'background-color:transparent',
					layout: 'border',
					region: 'center',
					defaults: { frame: false, border: false },
					items: AppBody
				}
			)
		);
	}
	else
	{
		vpLayout = 'border';
		ViewPortItems = AppBody;
	}
	$KB.PageViewPort = new Ext.Viewport
	(
		{
			layout: 'border',
			cls: 'SD_Body',
			defaults: { frame: false, border: false },
			items: ViewPortItems
		}
	);
//	$KB.PageViewPort = new Ext.Viewport
//	(
//		{
//			cls: 'SD_Body',
//			layout:'anchor',
//			items:
//			{
//				xtype:'panel',
//				anchor:'0 0',
//				autoScroll:true,
//				bodyStyle: 'background-color:transparent;',
//				border:false,
//				hideBorders:true,
//				items:
//				{
//					layout:'border',
//					height:2000,
//					bodyStyle: 'background-color:transparent;',
//					defaults: { frame: false, border: false },
//					items: ViewPortItems
//				}
//			} 
//		}
//	);
	if (HasSidePanels)
	{
		$KB.PageViewPort.on
		(
			"resize", 
			function (o, aW, aH, rw, rH)
			{
				var width = calcWidth(aW);
				if (HasPanel.west) Ext.get("Content_west").setWidth(width);
				if (HasPanel.east) Ext.get("Content_east").setWidth(width);
			}
		) 
	}
	
	Ext.each
	(
		['east','west', 'south','north'],
		function (region)
		{
			if (HasPanel[region])
			{
				var c = new Ext.Container({cls:'SD_page_' + region, border: false, applyTo: 'Content' + region});
				var p = Ext.getCmp("Content_" + region);			
				p.add(c);
				$g('Content' + region).style.display = "";
				p.doLayout();
			}
		}
	);
	$KB.Settings.ShowLoginStatus = WriteUserLogout && ($KB.Settings.PortalType == "Secure" || $KB.Settings.PortalType == "Personalize" || $KB.Settings.HasOptionalLogin );
	$KB.ScriptContainer = new Ext.Window({ x:-100, y: -100, hidden: true, autoDestroy: false, hideMode: 'offsets' });
	$KB.ScriptContainer.show();	$KB.ScriptContainer.hide();
};

$KB.getRelativePos = function(relTo, width, height)
{
	var pos = [];
	if (Ext.isObject(relTo))
	{
		var p = relTo.getPosition();
		pos.x = p[0];
		pos.y = p[1] + relTo.getHeight();
	}
	else
	{
		pos = $KB.getVisualCenter(width, height);
	}
	return pos
}
$KB.Extract = function(x, Start, End)
{
	if (x == null) return null;
	var n1 = 0;
	var _x = x.toLowerCase();
	if (!$KB.isNullOrEmpty(Start))
	{
		var z = new String();
		n1 = _x.indexOf(Start.toLowerCase());
		if (n1 < 0) return null;
		n1 = n1 + Start.length;
	}
	var n2;
	if ($KB.isNullOrEmpty(End))
	{
		n2 = x.length;
	}
	else
	{
		n2 = _x.indexOf(End.toLowerCase(), n1 + 1);
		if (n2 < 0) return null;
	}
	return x.substr(n1, n2 - n1);
}
$KB.OverrideExtJSObjects = function()
{
	Ext.override(Ext.grid.GridView, {
		resizeIndex: -1,
		initUI : function(grid){
			grid.on("headerclick", this.onHeaderClick, this);
			grid.on("headerdblclick", this.onHeaderDblClick, this);
			if(grid.trackMouseOver){
				grid.on("mouseover", this.onRowOver, this);
				grid.on("mouseout", this.onRowOut, this);
			}
		},
		onHeaderClick : function(g, index, e){
			if(this.headersDisabled){
				return;
			}
			this.resizeIndex = -1;
			var resizeCursor = (!$KB.isNull(this.activeHdRef)) ? this.activeHdRef.style.cursor : 'ddd';
			resizeCursor = (Ext.isAir && resizeCursor == 'move') || (Ext.isSafari && (resizeCursor == 'e-resize' || resizeCursor == 'w-resize')) || resizeCursor == 'col-resize';
			if (resizeCursor) {
				g.stopEditing(true);
				this.resizeIndex = index;
				var cell = Ext.fly(g.getView().getHeaderCell(index));
				if ((this.cm.getColumnWidth(index) / 2) + cell.getLeft() > e.getPageX()) this.resizeIndex--;
				while (this.cm.isHidden(this.resizeIndex)) {
					this.resizeIndex--;
					if (this.resizeIndex < 0) break;
				}
			} else if (this.cm.isSortable(index)) {
				g.stopEditing(true);
				g.store.sort(this.cm.getDataIndex(index));
			}
			return;
		},
		onHeaderDblClick: function(g, index, e) {
			e.stopEvent();
			if (this.resizeIndex >= 0 && g.getStore().getTotalCount() > 0) {
				var sz = 0;
				var el, w;
				for (i = 0; i < g.getStore().getTotalCount(); i++) {
					el = Ext.fly(this.getCell(i, this.resizeIndex));
					w = el.getWidth();
					el = el.first('div.x-grid3-cell-inner');
					w -= el.getWidth(true);
					w += el.getTextWidth(Ext.util.Format.stripTags(el.innerHTML));
					if (w > sz) sz = w;
				}
				g.getColumnModel().setColumnWidth(this.resizeIndex, sz);
				g.fireEvent('columnresize', this.resizeIndex, sz);
			}
		}
	});
	Ext.override(Ext.form.Checkbox, {
		onRender: function(ct, position){
			Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
			this.baseCls = 'x-form-check';
			if(this.inputValue !== undefined){
				this.el.dom.value = this.inputValue;
			}
			this.innerWrap = this.el.wrap({
				cls: this.baseCls+'-wrap-inner'
			});
			this.wrap = this.innerWrap.wrap({cls: this.baseCls+'-wrap'});
			this.imageEl = this.innerWrap.createChild({
				tag: 'img',
				src: Ext.BLANK_IMAGE_URL,
				cls: this.baseCls
			});
			if(this.boxLabel){
				this.labelEl = this.innerWrap.createChild({
					tag: 'label',
					htmlFor: this.el.id,
					cls: 'x-form-cb-label',
					html: this.boxLabel
				});
			}
			if(this.checked){
				this.setValue(true);
			}else{
				this.checked = this.el.dom.checked;
			}
			this.originalValue = this.checked;
			this.resizeEl = this.positionEl = this.wrap;
		},
		afterRender: function(){
			Ext.form.Checkbox.superclass.afterRender.call(this);
			this.imageEl[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
		},
		initCheckEvents: function(){
			this.innerWrap.addClassOnOver(this.overCls);
			this.innerWrap.addClassOnClick(this.mouseDownCls);
			this.innerWrap.on('click', this.onClick, this);
		},
		onFocus: function(e) {
			Ext.form.Checkbox.superclass.onFocus.call(this, e);
			this.innerWrap.addClass(this.focusCls);
		},
		onBlur: function(e) {
			Ext.form.Checkbox.superclass.onBlur.call(this, e);
			this.innerWrap.removeClass(this.focusCls);
		},
		onClick: function(e){
			if (e.getTarget().htmlFor != this.el.dom.id) {
				if (e.getTarget() !== this.el.dom) {
					this.el.focus();
				}
				if (!this.disabled && !this.readOnly && e.browserEvent.type == 'click') {
					this.toggleValue();
				}
			}
		},
		onEnable: Ext.form.Checkbox.superclass.onEnable,
		onDisable: Ext.form.Checkbox.superclass.onDisable,
		onKeyUp: undefined,
		setValue: function(v) {
			var checked = this.checked;
			this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
			if(this.rendered){
				this.el.dom.checked = this.checked;
				this.el.dom.defaultChecked = this.checked;
				this.imageEl[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
			}
			if(checked != this.checked){
				this.fireEvent("check", this, this.checked);
				if(this.handler){
					this.handler.call(this.scope || this, this, this.checked);
				}
			}
		},
		toggleValue: function() {
			var checked = this.checked;
			this.setValue(!checked);
		},
		getResizeEl: function() {
			return this.wrap;
		}
	});
	Ext.override(Ext.form.Radio, {
		checkedCls: 'x-form-radio-checked'
	});
}
$KB.PostResult = function(params)
{
	this.id = params.Id;
	this.onLoad = $KB.FixNull(params.OnLoad,null);
	this.postId = $KB.FixNull(params.PostId, null);
	this.isSnapIn = $KB.FixNull(params.IsSnapIn, false);
	this.searchId = $KB.FixNull(params.SearchId, 0);
	this.Control = new Ext.Container(
	{
		id:this.id,
		layout:'vbox', width:700,height:500,
		padding:'5',
		layoutConfig:
		{
			align:'stretch'
		},
		defaults:
		{
			style:
			{
				padding:'10px;'
			}
		}
	});
	
	this.init = function()
	{
		var thisObject = this;
		DirectRequest.GetPost(this.postId, this.searchId, function(res,resp)
		{
			if($KB.CheckValueResponse(resp))
			{
				thisObject.Data = res.Value;
				thisObject.Control.add(thisObject.getThreadData());
				thisObject.Control.add(thisObject.getPostData());
				if(thisObject.onLoad != null)
				{
					thisObject.onLoad({Control:thisObject.Control});
				}
			}
		});
	}
	this.getThreadData = function()
	{
		var forumClickEvent = '';
		var threadClickEvent = '';
		if(this.isSnapIn)
		{
			var furl = location.protocol + '//' + location.host + '?ForumId=' + this.Data.ForumId;
			var turl = location.protocol + '//' + location.host + '?ThreadId=' + this.Data.ThreadId;
			forumClickEvent = $KB.BuildClick("window.open('" + furl + "');");
			threadClickEvent = $KB.BuildClick("window.open('" + turl + "');");
		}
		else
		{
			forumClickEvent = String.format($KB.BuildClick("$KB.open(\{ForumId:{0}\})"),this.Data.ForumId);
			threadClickEvent = String.format($KB.BuildClick("$KB.open(\{ThreadId:{0}\})"),this.Data.ThreadId);
		}
		
		var c = new Ext.Container(
		{
			items:
			[
				new Ext.form.FieldSet(
				{
					title:$KB.LZ('Thread_Info', 'Thread Information'),
					width:260,
					autoHeight:true,
					items:
					[
						this.getInfoDef($KB.LZ('Forum', 'Forum'),
							'<span style="float:left;" class="SD_SearchResultViewLink" ' + 
							forumClickEvent + 
							'>' + $KB.escTag(this.Data.ForumName) + 
							'</span>'),
						this.getInfoDef($KB.LZ('Thread', 'Thread'),
							'<span style="float:left;" class="SD_SearchResultViewLink" ' + 
							threadClickEvent + 
							'>' + $KB.escTag(this.Data.ThreadName) + 
							'</span>'),
						this.getInfoDef($KB.LZ('Num_Posts', 'Number of Posts'),this.Data.ThreadPostCount),
						this.getInfoDef($KB.LZ('Proposed_Answers', 'Proposed Answers'),this.Data.ProposedAnswers.length),
						this.getInfoDef($KB.LZ('Accepted_Answers', 'Accepted Answers'),this.Data.AcceptedAnswers.length)
					]
				})
			]
		});
		
		return c;
	}
	this.getPostData = function()
	{
		var thisObject = this;
		var tcDef = 
		{
			id:this.id + 'tab',
			flex:1,
			plain:true,
			listeners:
			{
				tabchange: function(tabPanel,Tab)
				{
					$KB.RefreshCustomTab(thisObject.id + 'tab','Children', Tab);
				}
			}
		};
		$KB.AddCustomTabOptions(this.tabPanelId,'Children',tcDef);
		var tabControl = new Ext.TabPanel(tcDef);
	
		var releventPost = this.getPost(this.Data.Post,false,'',true,true);
		
		tabControl.add(
		{
			title:$KB.LZ('Relevant_Post', 'Relevant Post'),
			autoScroll:true,
			anchor:'0 0',
			items: releventPost
		});
		if(this.Data.ProposedAnswers.length>0)
		{
			var itms = [];
			for(var i=0;i<this.Data.ProposedAnswers.length;i++)
			{
				var pn = i+1;
				itms[i] = this.getPost(this.Data.ProposedAnswers[i],true,'Proposed Answer #' +  pn.toString(),false,true);
			}
			tabControl.add(
			{
				title:$KB.LZ('Proposed_Answers', 'Proposed Answers'),
				autoScroll:true,
				anchor:'0 0',
				items: itms
			});
		}
		if(this.Data.AcceptedAnswers.length>0)
		{
			var itms = [];
			for(var i=0;i<this.Data.AcceptedAnswers.length;i++)
			{
				var pn = i+1;
				itms[i] = this.getPost(this.Data.AcceptedAnswers[i],true,'Accepted Answer #' +  pn.toString(),false,true);
			}
			tabControl.add(
			{
				title:$KB.LZ('Accepted_Answers', 'Accepted Answers'),
				autoScroll:true,
				anchor:'0 0',
				items: itms
			});
		}
		
		tabControl.setActiveTab(0);
		return tabControl;
	}
	this.getPost = function(post, showBorder, title, showMeta1, showMeta2)
	{
		var c = new Ext.form.FieldSet(
		{
			title: showBorder ? title : '',
			border: showBorder
		});
		var cont = new Ext.Container(
		{
			style:'padding:8px;',
			items:c
		});
		if(showMeta1)
		{
			c.add(this.getInfoDef($KB.LZ('Is_Proposed', 'Is Proposed Answer'),post.IsProposed ? 'Yes' : 'No'));
			c.add(this.getInfoDef($KB.LZ('Is_Accepted', 'Is Accepted Answer'),post.IsAccepted ? 'Yes' : 'No'));
		}
		if(showMeta2)
		{
			if(post.Attachments.length>0)
			{
				var att = '';
				var a = '';
				for(var j=0;j<post.Attachments.length;j++)
				{
					att = att + a + post.Attachments[j].FileName + post.Attachments[j].FileExtn;
					a = ';';
				}
				c.add(this.getInfoDef($KB.LZ('Post_Att', 'Attachments'),att));
			}
			c.add(this.getInfoDef($KB.LZ('CreatedBy', 'Created By'),post.CreatedBy + ' (' + post.CreatedDate + ')'));
		}
		c.add(
		{
			xtype:'box',
			autoEl:
			{
				tag:'div',
				style:'padding-top:20px;',
				children:
				[
					{tag:'div',html:post.Content,style:'overflow:auto;clear:both;border:3px inset;padding:5px;'}
				]
			}
		});
		return cont;
	}
	this.getInfoDef = function(label, text)
	{
		var d =
		{
					xtype:'box',
					autoEl:
					{
						tag:'div',
						children:
						[
							{tag:'div',cls:'SD_SearchResultViewLabel FL',html:label,style:'clear:both;'},
							{tag:'div',cls:'SD_SearchResultViewMetadata',html:text.toString(),style:'padding:1px;'}
						]
					}
		};
		return d;
	}
	this.init();
}
$KB.histPrevTab = null;
$KB.histPrevCrumb = null;
$KB.allowHistoryAdd = true;
$KB.HandleHistoryChange = function(token,fromBack)
{
	if(token){
		var parts = token.split(':');
		var tab = null;
		var crumb = null;
		var artId = null;
		for(var i=0;i<parts.length;i=i+2)
		{
			var key = parts[i].toLowerCase();
			var value = null;
			if( (i+1) < parts.length )
			{
				value = parts[i+1];
			}
			if(value != null)
			{
				switch(key)
				{
					case 'tab':
						tab = value;
						break;
					case 'crumb':
						crumb = value;
						break;
					case 'artid':
						artId = value;
						break;
				}
			}
		}
		$KB.allowHistoryAdd = false;
		var tabChanged = false;
		if( (tab != null) && (tab != $KB.histPrevTab) )
		{
			tabChanged = true;
			$KB.histPrevTab = tab;
			$KB.PageTabs.setActiveTab(tab);
		}
		if( (crumb != null) && (crumb != $KB.histPrevCrumb) )
		{
			$KB.histPrevCrumb = crumb;
			var namespc = $KB.TabManager.getNS($KB.getCurrentTabName());
			if(namespc != null) 
			{
				if(fromBack && (artId != null))
				{
					namespc.BreadCrumb.articleBackFn(artId);
				}
				else namespc.BreadCrumb.clickByIndex($KB.FixNull(crumb,0),$KB.ProcessCrumbClick);
				$KB.ProcessCrumbClick = true;
			}
		}
		else if ( (crumb != null) && (artId != null) )
		{
			var namespc = $KB.TabManager.getNS($KB.getCurrentTabName());
			if(namespc != null)
			{
				if($KB.ProcessCrumbClick)
				{
					namespc.BreadCrumb.articleBackFn(artId);
				}
				$KB.ProcessCrumbClick = true;
			}
		}
		$KB.allowHistoryAdd = true;
	}else{
		// This is the initial default state.  Necessary if you navigate starting from the
		// page without any existing history token params and go back to the start state.
		$KB.PageTabs.setActiveTab(0);
		$KB.histPrevTab = null;
		var namespc = $KB.TabManager.getNS($KB.getCurrentTabName());
		if(namespc != null) 
		{
			namespc.BreadCrumb.clickByIndex(0,$KB.ProcessCrumbClick);
			$KB.ProcessCrumbClick = true;
		}
	}
}
$KB.RefreshCustomTab = function(tabPanelId, tabType, currentTab)
{
	if($KB.CustomTabs[tabType])
	{
		var tabPanel = Ext.getCmp(tabPanelId);
		var typeString = 'Parent';
		if(tabType == 'Children') typeString = 'Child';
		for(var i=0;i<tabPanel.items.items.length;i++)
		{
			var itm = tabPanel.items.items[i];
			var stripId = itm.id + 'StripItem';
			var element = document.getElementById(stripId);
			if(itm.id == currentTab.id)
			{
				element.setAttribute("class","CS_" + typeString + "Tab_Active"); //For Most Browsers
				element.setAttribute("className", 'CS_' + typeString + 'Tab_Active'); //For IE; harmless to other browsers.									
				element.onmouseover = function() 
				{
					this.setAttribute("class","CS_" + typeString + "Tab_Active CS_" + typeString + "Tab_Active_mo");
					this.setAttribute("className", 'CS_' + typeString + 'Tab_Active CS_' + typeString + 'Tab_Active_mo');
				}
				element.onmouseout = function() 
				{
					this.setAttribute("class","CS_" + typeString + "Tab_Active");
					this.setAttribute("className", 'CS_' + typeString + 'Tab_Active');
				}
			}
			else
			{
				element.setAttribute("class", "CS_" + typeString + "Tab_Inactive"); //For Most Browsers
				element.setAttribute("className", "CS_" + typeString + "Tab_Inactive"); //For IE; harmless to other browsers.									
				element.onmouseover = function() 
				{
					this.setAttribute("class","CS_" + typeString + "Tab_Inactive CS_" + typeString + "Tab_Inactive_mo");
					this.setAttribute("className","CS_" + typeString + "Tab_Inactive CS_" + typeString + "Tab_Inactive_mo");
				}
				element.onmouseout = function() 
				{
					this.setAttribute("class","CS_" + typeString + "Tab_Inactive");
					this.setAttribute("className","CS_" + typeString + "Tab_Inactive");
				}
			}
		}
	}
}
$KB.AddCustomTabOptions = function(tabPanelId, tabType, tabPanelDef)
{
	if($KB.CustomTabs[tabType])
	{
		var typeString = 'Parent';
		if(tabType == 'Children') typeString = 'Child';
		tabPanelDef.itemTpl = new Ext.XTemplate
		(
			'<li id="{id}" style="overflow:hidden">',
				'<tpl if="this.isActive(tabId)">',
					'<div id="{tabId}StripItem" class="CS_' + typeString + 'Tab_Active">{text}</div>',
				'</tpl>',
				'<tpl if="this.isActive(tabId) == false">',
					'<div id="{tabId}StripItem" class="CS_' + typeString + 'Tab_Inactive">{text}</div>',
				'</tpl>',
				'<a class="x-tab-right" href="#" style="padding-left:6px;visibility:hidden !important; height:0px;width:0px;">',
					'<em class="x-tab-left">',
						'<span class="x-tab-strip-inner">',
							'<span style="margin-left:20px" class="x-tab-strip-text {iconCls}">{text} {extra}</span>',
						'</span>',
					'</em>',
				'</a>',
			'</li>',
			{
				compiled:true,
				isActive: function(tabId)
				{
					var at = Ext.getCmp(tabPanelId).getActiveTab();
					return (at == null) ? false : (at.id == tabId);
				}
			}
		);
		tabPanelDef.getTemplateArgs = function(item) {
			var result = Ext.TabPanel.prototype.getTemplateArgs.call(this, item);
			return Ext.apply(result, {
				tabId: item.id
			});
		}
	}
}
$KB.IsMasterSite = function()
{
	return $KB.FixNull($KB.fromMasterSite, false);
}
$KB.AllowHistory = function()
{
	return $KB.FixNull($KB.doHistory, false);
}
$KB.ShowTabStrip = function()
{
	return $KB.FixNull($KB.showTabStrip,true);
}
$KB.Renderers =
{
	Date : function (value, p, r)
	{
		return $KB.DateFormat(value, "&nbsp;&nbsp;");
	},
	DateDay : function (value, p, r)
	{
		if ($KB.isNullOrEmpty(value)) return "null date";
		return value.dateFormat('M j, Y');
	},
	DateBreak : function (value, p, r)
	{
		return $KB.DateFormat(value, "<br/>");
	}
};
$KB.DateFormat = function (value, sep)
{
	if (value.dateFormat('m/d/Y') == "01/01/1") return "";
	if ($KB.isNullOrEmpty(value)) return "null date";
	var dt = new Date();
	var dayMatch = value.dateFormat('M j Y') == Ext.util.Format.date(dt, 'M j Y');
	return String.format ("<b>{0}</b>{1}{2}", dayMatch ?  "Today" : value.dateFormat('M j, Y'), $KB.FixNull(sep,"&nbsp;&nbsp;"), value.dateFormat('g:i a'))
}
$KB.GetHelp = function(params)
{
	if($KB.isNull($KB.HelpDoc))
	{
		$KB.HelpDoc = [];
	}

	var src = '/kb/article?islink=true&Help=' + params.Id;
	var articleIFrame = new Ext.Container(
	{
		region:'center',
		style:'padding:2px;',
		autoEl:
		{
			tag: 'iframe',
			src: src,
			align: 'left',
			scrolling: 'auto',
			marginwidth:'8px',
			marginheight:'8px',
			hspace:'10px',
			frameborder: '0'
		}
	});
	return articleIFrame;
};
$KB.ShowWindowItem = function(params)
{
	var window = new Ext.Window
	(
		{
			renderTo: Ext.getBody(),
			width: $KB.FixNull(params.Width,400),
			height: $KB.FixNull(params.Height,400),
			resizable: true,
			title: $KB.FixNull(params.Title,""),
			anchor: '0 0',
			modal: true,
			layout:'fit',
			items: params.Item,
			buttons:
			{
				text:$KB.LZ('Close', 'Close'),
				handler: function(){window.close();}
			}
		}
	);
	window.show();
}
$KB.ShowHelp = function(helpid,title)
{
	var hlp = $KB.GetHelp({Id:helpid});
	$KB.ShowWindowItem({Item:hlp,Width:800,Height:600,Title:title});
}
$KB.LoadingIndicator = function(params)
{
	var me = this;
	me.renderTo = $KB.FixNull(params.renderTo,Ext.getBody());
	me.centered = $KB.FixNull(params.centered,true);
	me.left = $KB.FixNull(params.left,'0px');
	me.top = $KB.FixNull(params.top,'0px');
	if(me.centered)
	{
		me.left = '50%';
		me.top = '50%';
	}
	me.el = new Ext.BoxComponent
	(
		{
			renderTo: me.renderTo,
			width:35,
			height:45,
			autoEl:
			{
				tag:'div',
				style:'left:' + me.left + ';top:' + me.top + ';position:absolute;z-index:9999;background-color:transparent;background-image:url(/Content/images/ajax-loader.gif) !important;background-repeat:no-repeat !important;'
			}
		}
	);
	me.el.show();
	me.Destroy = function()
	{
		if((!$KB.isNull(me)) && (!$KB.isNull(me.el)))
		{
			me.el.hide();
			me.el.destroy();
			me.el = null;
			me = null;
		}
	}
}
$KB.elementFromEvent = function(e)
{
	if(window.event) e = window.event;
	return $KB.FixNull(e.srcElement,e.target);
}
Ext.IEDocumentMode = function() {
    if (!Ext.isIE) {
        return undefined;
    }
    if (document.documentMode) { // >= IE8
        return document.documentMode;
    }
    if (document.compatMode && document.compatMode == "CSS1Compat") {
        return 7; // standards mode IE7
    }
    return 5; // quirks mode
}();
Ext.History = (function () {
    var iframe, hiddenField;
    var ready = false;
    var currentToken;
    var onhashchangeSupported = "onhashchange" in window && (!Ext.isIE || Ext.IEDocumentMode >= 8);
	var fromBack = true;

    function getHash() {
        var href = top.location.href, i = href.indexOf("#");
        return i >= 0 ? href.substr(i + 1) : null;
    }

    function doSave() {
        hiddenField.value = currentToken;
    }

    function handleStateChange(token) {
        currentToken = token;
        Ext.History.fireEvent('change', token, fromBack);
		fromBack = true;
    }

    function updateIFrame (token) {
        var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
        try {
            var doc = iframe.contentWindow.document;
            doc.open();
            doc.write(html);
            doc.close();
            return true;
        } catch (e) {
            return false;
        }
    }

    function checkIFrame() {
        if (!iframe.contentWindow || !iframe.contentWindow.document) {
            setTimeout(checkIFrame, 10);
            return;
        }

        var doc = iframe.contentWindow.document;
        var elem = doc.getElementById("state");
        var token = elem ? elem.innerText : null;

        var hash = getHash();

        setInterval(function () {

            doc = iframe.contentWindow.document;
            elem = doc.getElementById("state");

            var newtoken = elem ? elem.innerText : null;

            var newHash = getHash();

            if (newtoken !== token) {
                token = newtoken;
                handleStateChange(token);
                top.location.hash = token;
                hash = token;
                doSave();
            } else if (newHash !== hash) {
                hash = newHash;
                updateIFrame(newHash);
            }

        }, 50);

        ready = true;

        Ext.History.fireEvent('ready', Ext.History);
    }

    function startUp() {
        currentToken = hiddenField.value ? hiddenField.value : getHash();

        if (Ext.isIE && !onhashchangeSupported) {
            checkIFrame();
        } else {
            if (onhashchangeSupported) {
                window.onhashchange = function() {
                    var hash = getHash();
                    handleStateChange(hash);
                };
            } else {
                var hash = getHash();
                setInterval(function () {
                    var newHash = getHash();
                    if (newHash !== hash) {
                        hash = newHash;
                        handleStateChange(hash);
                        doSave();
                    }
                }, 50);
            }
            ready = true;
            Ext.History.fireEvent('ready', Ext.History);
        }
    }

    return {
        fieldId: 'x-history-field',
        iframeId: 'x-history-frame',
        events:{},
        init: function (onReady, scope) {
            if(ready) {
                Ext.callback(onReady, scope, [this]);
                return;
            }
            if(!Ext.isReady){
                Ext.onReady(function(){
                    Ext.History.init(onReady, scope);
                });
                return;
            }
            hiddenField = Ext.getDom(Ext.History.fieldId);
            if (Ext.isIE && !onhashchangeSupported) {
                iframe = Ext.getDom(Ext.History.iframeId);
            }
            this.addEvents(
                'ready',
                'change'
            );
            if(onReady){
                this.on('ready', onReady, scope, {single:true});
            }
            startUp();
        },
        add: function (token, preventDup) {
			fromBack = false;
            if(preventDup !== false){
                if(this.getToken() == token){
                    return true;
                }
            }
            if (iframe) {
                return updateIFrame(token);
            } else {
                top.location.hash = token;
                return true;
            }
        },
        back: function(){
            history.go(-1);
        },
        forward: function(){
            history.go(1);
        },
        getToken: function() {
            return ready ? currentToken : getHash();
        }
    };
})();
Ext.apply(Ext.History, new Ext.util.Observable());
$DOM.SetInnerText = function(dom,v)
{
	if(!$KB.isNull(dom.innerText)) dom.innerText = v;
	else dom.textContent = v;
}
$DOM.SetClass = function(dom,v)
{
	dom.setAttribute('class',v);
	dom.setAttribute('className',v);
}
$KB.GoToLink = function(params)
{
	var TabName = $KB.getCurrentTabName();
	if($KB.isNullOrEmpty(TabName)) return;
	var ns = $KB.TabManager.getNS(TabName);
	if($KB.isNullOrEmpty(ns)) return;
	ns.articleBar.articleClicked({ArticleId:params.ArticleId,Title:params.Title,ShowToolbar:true,Source:'Article',ItemType:'Article'},function(){});
}
$KB.GetOfficeDocOpenInfo = function(prms)
{
	var woId = $KB.FixNull($KB.officeWindowId,0) + 1;
	var pp = $KB.GlobalData.PortalProperties;
	var url = "/kb/article?cid=" + pp.PortalId + "&c=" + pp.ClientId +"&articleid=" + prms.ArticleId + ($KB.isNull(prms.DocId)? "" : "&docid=" + prms.DocId) + "&source=" + $KB.FixNull(prms.Source,'article') + ($KB.isNull(prms.SearchString) ? "" : "&searchstring=" + prms.SearchString) + ($KB.isNull(prms.SearchId) ? "" : "&searchid=" + prms.SearchId) + "&islink=true&FromPopup=1&LogVisit=0";
	var prm1 = "articlePopup" + woId;
	var prm2 = "toolbar=0,resizable=1,scrollbars=1,status=0,location=0,width=640,height=480";
	return {URL:url,WindowId:prm1,Parameters:prm2};
}
$KB.GetOfficDocOpenStr = function(prms)
{
	var dinfo = $KB.GetOfficeDocOpenInfo(prms);
	return "window.open(\'" + dinfo.URL + "\',\'" + dinfo.WindowId + "\',\'" + dinfo.Parameters + "\');";
}
$KB.GetURLParameter = function(name,nocase)
{
	nocase = $KB.FixNull(nocase,false);
	if(nocase) name = name.toLowerCase();
	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]"+name+"=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec(nocase ? window.location.href.toLowerCase() : window.location.href );
	if( results == null )
	return "";
	else
	return results[1];
}
