/// <reference path="~/TopletsResources/js/jquery-vsdoc.js" />

if (typeof (TD) == 'undefined') {
	var TD = {};
	TD.Toplets = {};
}

TD.Framework = {
	PageOnLoad: function () {
		TD.Framework.IsPageLoaded = true;

		if (!TD.Framework.IsInFrame()) {
			//param shouls starts from "popup"
			var QueryParams = TD.Framework.ParseQueryString(document.location);

			if (QueryParams['popuplogin'] != null && QueryParams['popuplogin'] == "true")
				TD.Framework.PopupLogin();

			if (QueryParams['PopupResetPassword2'] != null && QueryParams['PopupResetPassword2'] == "true" && QueryParams['rCode'] != null && QueryParams['uCode'] != null)
				TD.Framework.PopupResetPassword2(QueryParams['rCode'], QueryParams['uCode']);

			if (QueryParams['PopupAccountActivation'] != null && QueryParams['PopupAccountActivation'] == "true") {

				var messageStr = '';
				if (QueryParams['message'] != null)
					messageStr = QueryParams['message'];

				var acodeStr = '';
				if (QueryParams['ACode'] != null)
					acodeStr = QueryParams['ACode'];

				TD.Framework.PopupActivation({
					message: messageStr,
					acode: acodeStr
				});
			}
		}
	},

	IsPageLoaded: false,

	Browser: {
		IE: !!(window.attachEvent && navigator.userAgent.indexOf('Opera') === -1),
		Opera: navigator.userAgent.indexOf('Opera') > -1,
		WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
		Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') === -1,
		MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
	},

	IncDecFontSize: function (_obj, _vector) {
		var curFontSize;
		if (typeof jQuery != "undefined")
			curFontSize = parseInt(jQuery(_obj).css("fontSize"));
		else if (typeof Prototype != "undefined")
			curFontSize = parseInt(_obj.getStyle('fontSize'));

		if (!_obj.DefaultFontSize)
			_obj.DefaultFontSize = curFontSize;

		if (_vector == 0)
			_obj.style.fontSize = _obj.DefaultFontSize + 'px';
		else {
			var newVal = curFontSize + _vector;
			_obj.style.fontSize = newVal + 'px';
		}
		return false;
	},

	IsInFrame: function () {
		return !(window.top == window);
	},

	EvalScript: function (scripts) {
		try {
			if (scripts != '') {
				var script = "";
				scripts = scripts.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function () {
					if (scripts !== null) script += arguments[1] + '\n';
					return '';
				});
				if (script) (window.execScript) ? window.execScript(script) : window.setTimeout(script, 0);
			}
			return false;
		}
		catch (e) {
			alert(e)
		}
	},

	ReadCookie: function (name) {
		if (document.cookie.length == 0)
			return null;
		var search = name + "=";
		offset = document.cookie.indexOf(search);
		if (offset == -1)
			return null;
		offset += search.length;
		end = document.cookie.indexOf(";", offset);
		if (end == -1) end = document.cookie.length;
		var cookieValue = unescape(document.cookie.substring(offset, end))
		return cookieValue;
	},

	// writeCookie("myCookie", "my name", 24); // Stores the string "my name" in the cookie "myCookie" which expires after 24 hours.
	WriteCookie: function (name, value, hours, host) {
		var expire = "";
		if (hours != null) {
			expire = new Date((new Date()).getTime() + hours * 3600000);
			expire = "; expires=" + expire.toGMTString();
		}
		var path = (host) ? "; path=" + host : "; path=/";
		document.cookie = name + "=" + escape(value) + expire + path;
	},

	PopupWasClicked: false,
	Popup: function (url, title, width, height) {
		var link = {
			title: '', //title, iframe will show title
			href: url,
			className: "iframe",
			rel: ""
		};
		var options = {
			overlayShow: true,
			width: width,
			height: height,
			showCloseButton: true,
			hideOnContentClick: false,
			padding: 0
		};

		if (typeof (jQuery.fancybox) == 'undefined' || $.fancybox.isInit == false) {
			if (TD.Framework.PopupWasClicked == true)
				return;
			TD.Framework.PopupWasClicked = true;
			setTimeout("TD.Framework.Popup('" + url + "','" + title + "'," + width + "," + height + ")", 1000);
			return false;
		}

		jQuery(link).fancybox(options).trigger('click');
		TD.Framework.PopupWasClicked = false;
		return false;
	},

	ClosePopup: function (reload) {
		if (TD.Framework.IsInFrame()) {
			window.top.TD.Framework.ClosePopup();
			return false;
		}
		if (reload === true) {
			var QueryParams = TD.Framework.ParseQueryString(document.location);
			var url;
			if (QueryParams['ReturnUrl'] != null)
				url = QueryParams['ReturnUrl'];
			else {
				url = new String(document.location.href);
				url = url.replace(/popup[\w\d]+=[^&]+/i, "");
				url = url.replace(/&{2,}/, "&");
			}
			url = url.replace(/#.*/, "");
			document.location.href = url;
		}
		else {
			if (jQuery.fancybox)
				jQuery.fancybox.close();
		}
	},
	ClosePopupViaProxy: function (iframeid, reload) {
		try {
			top.TD.Framework.ClosePopup(reload);
		}
		catch (err) {
			TD.Framework.xDomainSender(iframeid, 'TD.Framework.ClosePopup(' + reload + ');');
		}
	},


	PopupLogin: function (width, height) {
		if (!width)
			width = TD.Config.AppDafults.PopupLoginWidth;
		if (!height)
			height = TD.Config.AppDafults.PopupLoginHeight;
		var host = (TD.Config.AppDafults.UseSSL === true) ? "https://" + window.location.hostname : "";
		TD.Framework.Popup(host + TD.Config.AppDafults.PopupLoginPath, '', width, height);
		return false;
	},
	PopupLoginViaProxy: function (iframeid) {
		try {
			top.TD.Framework.PopupLogin();
		}
		catch (err) {
			TD.Framework.xDomainSender(iframeid, 'TD.Framework.PopupLogin();');
		}
	},

	PopupRegistration: function (width, height) {
		if (!width)
			width = TD.Config.AppDafults.PopupRegistrationWidth;
		if (!height)
			height = TD.Config.AppDafults.PopupRegistrationHeight;
		var host = (TD.Config.AppDafults.UseSSL === true) ? "https://" + window.location.hostname : "";
		TD.Framework.Popup(host + TD.Config.AppDafults.PopupRegistrationPath, '', width, height);
	},
	PopupRegistrationViaProxy: function (iframeid) {
		try {
			top.TD.Framework.PopupRegistration();
		}
		catch (err) {
			TD.Framework.xDomainSender(iframeid, 'TD.Framework.PopupRegistration();');
		}
	},

	PopupActivation: function (options, width, height) {
		if (!width)
			width = TD.Config.AppDafults.PopupActivationWidth;
		if (!height)
			height = TD.Config.AppDafults.PopupActivationHeight;

		var message = '';
		var aCode = '';
		if (!!options) {
			if (typeof options === "string") {
				aCode = options;
			}
			else { //object
				if (options.message !== undefined)
					message = options.message;
				if (options.acode !== undefined)
					aCode = options.acode;
			}
		}

		var host = (TD.Config.AppDafults.UseSSL === true) ? "https://" + window.location.hostname : "";
		var params = '&ACode=' + aCode + '&message=' + message;

		TD.Framework.Popup(host + TD.Config.AppDafults.PopupActivationPath + params, '', width, height);
	},
	PopupActivationViaProxy: function (iframeid) {
		try {
			top.TD.Framework.PopupActivation();
		}
		catch (err) {
			TD.Framework.xDomainSender(iframeid, 'TD.Framework.PopupActivation();');
		}
	},


	PopupResetPassword: function (width, height) {
		if (!width)
			width = TD.Config.AppDafults.PopupResetPasswordWidth;
		if (!height)
			height = TD.Config.AppDafults.PopupResetPasswordHeight;
		var host = (TD.Config.AppDafults.UseSSL === true) ? "https://" + window.location.hostname : "";
		TD.Framework.Popup(host + TD.Config.AppDafults.PopupResetPasswordPath, '', width, height);
	},
	PopupResetPasswordViaProxy: function (iframeid) {
		try {
			top.TD.Framework.PopupResetPassword();
		}
		catch (err) {
			TD.Framework.xDomainSender(iframeid, 'TD.Framework.PopupResetPassword();');
		}
	},

	PopupResetPassword2: function (rCode, uCode, width, height) {
		if (!width)
			width = TD.Config.AppDafults.PopupResetPasswordWidth;
		if (!height)
			height = TD.Config.AppDafults.PopupResetPasswordHeight;
		var host = (TD.Config.AppDafults.UseSSL === true) ? "https://" + window.location.hostname : "";
		TD.Framework.Popup(host + TD.Config.AppDafults.PopupResetPassword2Path + 'rCode=' + rCode + '&uCode=' + uCode, '', width, height);
	},


	CallFbLoginViaProxy: function (iframeid) {
		try {
			top.TD.Facebook.ProcessLogin();
		}
		catch (err) {
			TD.Framework.xDomainSender(iframeid, 'TD.Facebook.ProcessLogin();');
		}
	},
	CallFbLogoutViaProxy: function (iframeid) {
		try {
			top.TD.Facebook.ProcessLogout('/');
		}
		catch (err) {
			TD.Framework.xDomainSender(iframeid, "TD.Facebook.ProcessLogout('/');");
		}
	},

	Logout: function () {
		var host = (TD.Config.AppDafults.UseSSL === true) ? "https://" + window.location.hostname : "";
		document.location = host + TD.Config.AppDafults.LogoutPath + escape(document.location.href);
		return false;
	},

	//update to jquery func
	ContentInject: function (_URL, _ID, _Params) {
		var ID;
		if (!_ID) {
			ID = 'ContentInject' + Math.random() * 5000;
			document.write('<div id="' + ID + '"></div>')
		}
		else
			ID = _ID;

		jQuery.get(_URL, _Params,
			function (data) {
				elem = document.getElementById(ID);
				if (elem == null)
					return;
				elem.innerHTML = data;
				//jQuery("#" + ID).html(data);
				TD.Framework.EvalScript(data);
			});
	},

	JSInsert: function (url) {
		document.write('<scr' + 'ipt type="text/javascript" src="' + url + '"></scr' + 'ipt>')
	},

	JSLoad: function (url) {
		scriptEl = document.createElement("script")
		scriptEl.setAttribute("type", "text/javascript")
		scriptEl.setAttribute("charset", "utf-8")
		scriptEl.setAttribute("src", url)
		document.getElementsByTagName('head')[0].appendChild(scriptEl)
	},

	//update to jquery func
	AddLoadEvent: function (func) { //TD.AddLoadEvent(function() { TD.JSLoad('/TopletsResources/Maps/js/topsmap.js') })
		if (typeof func == "string") {
			var funcstr = func
			func = function () { return eval(funcstr) }
		}
		var oldonload = window.onload
		if (typeof window.onload != 'function') {
			window.onload = func
		} else {
			window.onload = function () {
				oldonload()
				func()
			}
		}
	},

	WaitUntilExists: function (obj, func) {
		if (typeof obj == "undefined") {
			window.setTimeout(1000, function () { TD.Framework.WaitUntilExists(obj, func) })
		} else {
			func()
		}
	},

	//Deprecated
	viewmore: function (divid, expandid, collapseid) {
		thisdiv = document.getElementById(divid);
		expand = document.getElementById(expandid);
		collaps = document.getElementById(collapseid);
		if (thisdiv.style.display == "none") {
			thisdiv.style.display = "block";
			expand.style.display = "none";
			collaps.style.display = "block";
		} else {
			thisdiv.style.display = "none";
			expand.style.display = "block";
			collaps.style.display = "none";
		}
	},

	ParseQueryString: function (QueryString) {
		//var query = window.location.search.substring(1);
		var query = new String(QueryString);

		var qsParm = {}; // new Array();
		var pos = query.indexOf('?');
		if (pos > 0)
			query = query.substring(pos + 1);

		var parms = query.split('&');
		for (var i = 0; i < parms.length; i++) {
			pos = parms[i].indexOf('=');
			if (pos > 0)
				qsParm[parms[i].substring(0, pos)] = unescape(parms[i].substring(pos + 1)); ;
		}
		return qsParm;
	},


	GetReturnUrl: function (url) {
		if (url == undefined || url == null || url == '')
			return '/';
		var QueryParams = TD.Framework.ParseQueryString(url);
		if (QueryParams['ReturnUrl'] != null)
			return QueryParams['ReturnUrl'];
		return url;
	},

	//TABS
	/*
	var TabsInfo = {
	TabsId: new Array('HomeT1', 'HomeT2', 'HomeT3', 'HomeT4'),
	DefaultTabId: 'HomeT1',
	BoxesId: new Array('HomeTEl1', 'HomeTEl2', 'HomeTEl3', 'HomeTEl4'),
	TabActiveClass: 'HomeTActive',
	TabOverClass: 'HomeTActive',
	TabClass: 'HomeTActive',
	TabHash: '#tab123?'
	}
	*/
	Tabs: function (TabsInfo) {
		if (TabsInfo.TabsId.length != TabsInfo.BoxesId.length) {
			alert('TabsInfo.TabsId.length != TabsInfo.BoxesId.length');
			return;
		}

		var defaultTab = document.location.hash.indexOf(TabsInfo.TabHash);
		if (defaultTab > -1)
			TabsInfo.DefaultTabId = document.location.hash.substr(TabsInfo.TabHash.length, document.location.hash.length - TabsInfo.TabHash.length);

		var OnTabClick = function () {
			this.TabsInfo.ActiveTabId = this.Id;
			for (i = 0; i < this.TabsInfo.TabsId.length; i++) {
				var tab = jQuery('#' + this.TabsInfo.TabsId[i]);
				if (tab[0].Active) {
					tab[0].Active = false;
					tab.addClass(this.TabsInfo.TabClass);
					tab.removeClass(this.TabsInfo.TabActiveClass);
					tab.removeClass(this.TabsInfo.TabOverClass);

					jQuery('#' + TabsInfo.BoxesId[i]).hide();
				}
			}
			this.Active = true;
			jQuery(this).removeClass(this.TabsInfo.TabClass);
			jQuery(this).removeClass(this.TabsInfo.TabOverClass);
			jQuery(this).addClass(this.TabsInfo.TabActiveClass);

			jQuery('#' + TabsInfo.BoxesId[jQuery.inArray(this.Id, this.TabsInfo.TabsId)]).show();

			document.location.hash = TabsInfo.TabHash + this.Id;
			return false;
		}
		var OnTabMouseOver = function () {
			if (!this.Active) {
				jQuery(this).addClass(this.TabsInfo.TabOverClass);
				jQuery(this).removeClass(this.TabsInfo.TabClass);
			}
		}
		var OnTabMouseOut = function () {
			if (!this.Active) {
				jQuery(this).addClass(this.TabsInfo.TabClass);
				jQuery(this).removeClass(this.TabsInfo.TabOverClass);
			}
		}
		for (i = 0; i < TabsInfo.TabsId.length; i++) {
			var tab = jQuery('#' + TabsInfo.TabsId[i]);
			tab[0].Id = TabsInfo.TabsId[i];
			tab[0].TabsInfo = TabsInfo;
			tab[0].Active = false;
			tab.bind("click", OnTabClick);
			tab.bind("mouseover", OnTabMouseOver);
			tab.bind("mouseout", OnTabMouseOut);
			jQuery('#' + TabsInfo.BoxesId[i]).hide();
		}

		//var fxx = OnTabClick.bind(jQuery(TabsInfo.DefaultTabId));
		//fxx();
		jQuery('#' + TabsInfo.DefaultTabId).trigger('click');
	},

	xDomainSender: function (iframeid, message) {
		var elem = document.getElementById(iframeid);
		var txt = new String(elem.src);
		var pos = txt.indexOf("#");
		if (pos > 0)
			txt = txt.substr(0, pos);
		elem.contentWindow.location = txt + '#' + message;
		elem.width = elem.width > 50 ? 50 : 100;
	},

	xDomainReceiver: function (message) {
		var message = document.location.hash;
		if (message.length > 0) {
			message = message.substr(1);
			if (target == "top")
				top.TD.Framework.xDomainEvaluator(message);
			else
				parent.frames["hostFrame"].TD.Framework.xDomainEvaluator(message);
		}
	},

	xDomainEvaluator: function (message) {
		//alert(message);
		eval(message);
		//jQuery('#xdomaindiv').html(message);
	}
}

TD.Framework.DelegateType = function(_type) {
	this.type = _type;
};
TD.Framework.DelegateType.prototype.listeners = {};
TD.Framework.DelegateType.prototype.Add = function(f) {
	if (typeof (this.listeners[this.type]) == 'undefined')
		this.listeners[this.type] = [];
	this.listeners[this.type].push(f);
};
TD.Framework.DelegateType.prototype.Invoke = function() {
	if (typeof (this.listeners[this.type]) == 'undefined')
		return;
	var c = this.listeners[this.type].length;
	var v = this.listeners[this.type];
	for (di = 0; di < c; di++)
		v[di]();
};


///////////////////////////////////////////////////////
//   TD.Identity
///////////////////////////////////////////////////////


TD.Identity = {
	IsAuthenticated: false
};
if (TD.Framework.ReadCookie(TD.Config.AppDafults.TopsCmsCookieName) != null) {
	jQuery.extend(TD.Identity, TD.Framework.ParseQueryString(TD.Framework.ReadCookie(TD.Config.AppDafults.TopsCmsCookieName)));
	TD.Identity.IsAuthenticated = TD.Identity.UserName != undefined;
}


///////////////////////////////////////////////////////
//   TD.Facebook
///////////////////////////////////////////////////////


TD.Facebook = {
	FbAPIKey: "",
	IsRequireParseDomTree: false,
	IsInitialized: false,
	IsSecureConnection: false,

	PageOnLoad: function() {
		if (this.IsRequireParseDomTree) {
			this.ParseDomTree();
		}
	},

	OnInit: new TD.Framework.DelegateType('TD_Facebook_OnInit'),

	Init: function(id) {
		if (!!window.FB) {
			/*
			FB.Bootstrap.init(this.FbAPIKey, "/xd_receiver.htm", { reloadIfSessionStateChanged: false });
			FB.Bootstrap.ensureInit(function()
			{
			FB.FBDebug.isEnabled=false;
			FB.FBDebug.logLevel=0;
				
			TD.Facebook.IsInitialized = true;
			TD.Facebook.OnInit.Invoke();
				
			});		
			return;
			*/
			//var receiver = (this.IsSecureConnection === true) ? "/xd_receiver_ssl.htm" : "/xd_receiver.htm";
			//FB.init(this.FbAPIKey, receiver, {}); /*"reloadIfSessionStateChanged": false*/

			FB.init({
				appId: this.FbAPIKey,
				cookie: true,
				logging: true,
				status: true,
				xfbml: true
			});

			TD.Facebook.IsInitialized = true;
			TD.Facebook.OnInit.Invoke();

			if (this.IsRequireParseDomTree) {
				this.ParseDomTree();
			}
		}
	},

	EnsureLoad: function(_f) {
		if (TD.Facebook.IsInitialized === true)
			_f();
		else
			this.OnInit.Add(_f);
	},

	ProcessLogin: function() {
		TD.Facebook.EnsureLoad(function() {
			var curentDocument = document;
			/*
			if (TD.Framework.IsInFrame()){
			FB = window.top.FB;
			//window.top.TD.Facebook.ProcessLogin();
			//return false;
			}
			*/
			//---FB.ensureInit(function() {

			/*
			FB.Connect.requireSession();
			if(!FB.Facebook.get_sessionWaitable().result)
			FB.Facebook.get_sessionWaitable().add_changed(function()
			var sessionWaitable=FB.Facebook.get_sessionWaitable();
			if(sessionWaitable.get_isReady()&&sessionWaitable.result)
			FB.Facebook.get_sessionWaitable().waitUntilReady( function( session ) {
			*/

			//---FB.Connect.requireSession(function() {
			FB.login(function(response) {
				if (response.session) {
					$.get(TD.Config.AppDafults.PopupFbIsOurUserPath + response.session.uid, function(data) {
						var host = (TD.Config.AppDafults.UseSSL === true) ? "https://" + window.location.hostname : "";
						if (data == "true") {
							document.location.href = host + TD.Config.AppDafults.PopupFbHandlerPath + escape(TD.Framework.GetReturnUrl(document.location));
						}
						else {
							var width = TD.Config.AppDafults.PopupFbWidth;
							var height = TD.Config.AppDafults.PopupFbHeight;
							var url = host + TD.Config.AppDafults.PopupFbHandlerPath + escape(TD.Config.AppDafults.PopupClosePath);
							TD.Framework.Popup(url, '', width, height);
						}
					});
				};
			});
			//---}, null, true);
			return false;
			//---});
		});

		return false;
	},

	ProcessLogout: function(ReturnUrl) {
		TD.Facebook.EnsureLoad(function() {
			if (TD.Framework.IsInFrame()) {
				window.top.TD.Facebook.ProcessLogout(ReturnUrl);
				return false;
			}
			TD.Framework.ClosePopup();
			if (typeof (ReturnUrl) == 'function')
				FB.logout(ReturnUrl);
			else {
				if (ReturnUrl == undefined)
					ReturnUrl = escape(TD.Framework.GetReturnUrl(document.location));
				FB.logout(function() { document.location = TD.Config.AppDafults.AppLogout + ReturnUrl; });
			}
		});
	},

	ParseDomTree: function(Timeout) {
		if (TD.Framework.IsPageLoaded === true && this.IsInitialized === true) {
			FB.XFBML.parse();
			return;
		}
		else
			this.IsRequireParseDomTree = true;
	},

	PostFeed: function(FeedData, callback) {
		TD.Facebook.EnsureLoad(function() {
			var attachment = {
				name: FeedData.AssetTitle,
				caption: FeedData.FeedCaption + FeedData.AssetType,
				//description: 'A small JavaScript library that allows you to harness ',
				href: FeedData.AssetUrl,
				/*
				'properties': [
				{text:'text prop 1',href:'http://google.com'},
				{text:'text prop 2',href:'http://google.com'},
				{text:'text prop 3',href:'http://google.com'},
				{text:'text prop 4',href:'http://google.com'}

									],
				*/
				'media': []
			};

			for (var i = 0; i < FeedData.AssetImages.length; i++)
				attachment.media[i] = {
					href: FeedData.AssetUrl,
					type: 'image',
					src: FeedData.AssetImages[i].src
				};

			var action_link = [{ 'text': 'Read ' + FeedData.AssetType, 'href': FeedData.AssetUrl}];
			var msg = FeedData.CommentTitle + "\n\r" + FeedData.Comment;

			callback = (callback != null && typeof callback == 'function') ? callback : function(response) { if (response && response.post_id) { alert('Post was published.'); } else { alert('Post was not published.'); } };

			FB.ui(
				{
					method: 'stream.publish',
					message: msg,
					attachment: attachment,
					action_links: action_link,
					user_message_prompt: 'Share your thoughts about Connect'
				},
				callback
			);
		});

		return false;

		/*
		var TemplateBundleId = FeedData.TemplateBundleId;
		var user_message_prompt = "What do you think of this " + FeedData.AssetType.toLowerCase() + "?";
		var user_message = { value: FeedData.Comment };

				for (var i = 0; i < FeedData.AssetImages.length; i++)
		FeedData.AssetImages[i].href = FeedData.AssetUrl;

				var template_data = {
		"WebSiteUrl": FeedData.WebSiteUrl,
		"WebSiteName": FeedData.WebSiteName,
		"AssetType": FeedData.AssetType,
		"AssetUrl": FeedData.AssetUrl,
		"AssetTitle": FeedData.AssetTitle,
		"images": FeedData.AssetImages
		}
		var body_general = '';

				callback = (callback != null && typeof callback == 'function') ? callback : function() { };

				FB.ensureInit(function() {
		FB.Connect.showFeedDialog(TemplateBundleId, template_data, [], body_general, null, FB.RequireConnect.require, callback, user_message_prompt, user_message);
		});
		*/
	},

	GlobalFeedData: null,

	FeedDataObj: function(PropertiesObject) {
		//TemplateBundleId, WebSiteName, AssetType
		//AssetTitle, AssetImages, AssetVideo
		//FeedCaption, FeedUserMessagePrompt
		for (x in PropertiesObject)
			this[x] = PropertiesObject[x];

		this.AssetUrl = document.location.href;
		this.WebSiteUrl = document.location.href;
		// will setted later
		this.CommentTitle = "";
		this.Comment = "";
	},

	calbacFunc: function(data) {
		var fff = 5;
	},


	runFQL: function(FQL, callback) {
		callback = (callback != null && typeof callback == 'function') ? callback : TD.Facebook.calbacFunc;
		var query = FB.Data.query(FQL);
		query.wait(callback);
	},


	AppFriends: function(callback) {
		TD.Facebook.EnsureLoad(function() {

			TD.Facebook.runFQL("SELECT uid, is_app_user FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me()) ORDER BY name", function(rows) {
				var appFriends = new Array();
				for (i = 0; i < rows.length; i++) {
					if (rows[i].is_app_user == true)
						appFriends.push(rows[i].uid);
				}
				callback(appFriends);
			})
			return;

			callback = (callback != null && typeof callback == 'function') ? callback : TD.Facebook.calbacFunc;
			FB.ensureInit(function() {
				FB.Facebook.apiClient.friends_getAppUsers(callback);
				//FB.Facebook.apiClient.friends_getLists(TD.Facebook.calbacFunc);
			});
			return;

		});
	},

	InviteFriends: function(excludeAppFriends) {
		TD.Facebook.EnsureLoad(function() {
			//FB.ensureInit(function() {
			var showFunc = function(exclude_ids) {
				/*
				FB.ui(
				{
				method: 'request.form'
				},
				callback
				);
				*/


				var dialog = new FB.ui.FBMLPopupDialog('Invite your friends to join', '');
				/*
				var fbml = '<fb:fbml>' +
				'<fb:request-form style="width:630px; height:540px;" action="' + document.location.href + '?" method="POST" invite="true" type="Invite Friends" ' +
				'content="You have been invited to visit website <fb:req-choice url=\'http://' + document.location.host + '/\' label=\'Ok\' />" >' +
				'<fb:multi-friend-selector showborder="false" rows="4" cols="4" exclude_ids="' + exclude_ids + '" actiontext="Invite your friends" bypass="cancel" showborder="false" />' +
				'</fb:request-form>' +
				'</fb:fbml>';
				dialog.setFBMLContent(fbml);
				*/
				dialog.setContentWidth(630);
				dialog.setContentHeight(560);
				dialog.show();
			}
			if (excludeAppFriends)
				TD.Facebook.AppFriends(function(data) {
					showFunc(data.join(","));
				});
			else
				showFunc('');
			//});
		});
		return false;
	},

	ifUserConnected: function(YesFunction, NoFunction) {
		TD.Facebook.EnsureLoad(function() {
			/*
			FB.Connect.ifUserConnected(
			(YesFunction ? YesFunction : null),
			(NoFunction ? NoFunction : null)
			);
			*/
			FB.getLoginStatus(function(response) {
				if (response.session) {
					if (YesFunction)
						YesFunction();
				} else {
					if (NoFunction)
						NoFunction();
				}
			});
		});
		//FB.Bootstrap.requireFeatures(["ApiClient"], function() {
		//var sesrec = FB.Facebook.apiClient.get_session();
		//});
	},

	Temp: function() {
		//connect.getUnconnectedFriendsCount
	}
}


///////////////////////////////////////////////////////
//   TD.md5
///////////////////////////////////////////////////////


TD.md5 = {
	/*
	* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
	* Digest Algorithm, as defined in RFC 1321.
	* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
	* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
	* Distributed under the BSD License
	* See http://pajhome.org.uk/crypt/md5 for more info.
	*/

	/*
	* Configurable variables. You may need to tweak these to be compatible with
	* the server-side, but the defaults work in most cases.
	*/
	hexcase: 0,  /* hex output format. 0 - lowercase; 1 - uppercase        */
	b64pad: "", /* base-64 pad character. "=" for strict RFC compliance   */
	chrsz: 8,  /* bits per input character. 8 - ASCII; 16 - Unicode      */

	/*
	* These are the functions you'll usually want to call
	* They take string arguments and return either hex or base-64 encoded strings
	*/
	hex_md5: function(s) { return this.binl2hex(this.core_md5(this.str2binl(s), s.length * this.chrsz)); },
	b64_md5: function(s) { return this.binl2b64(this.core_md5(this.str2binl(s), s.length * this.chrsz)); },
	str_md5: function(s) { return this.binl2str(this.core_md5(this.str2binl(s), s.length * this.chrsz)); },
	hex_hmac_md5: function(key, data) { return this.binl2hex(this.core_hmac_md5(key, data)); },
	b64_hmac_md5: function(key, data) { return this.binl2b64(this.core_hmac_md5(key, data)); },
	str_hmac_md5: function(key, data) { return this.binl2str(this.core_hmac_md5(key, data)); },

	/*
	* Perform a simple self-test to see if the VM is working
	*/
	md5_vm_test: function() {
		return this.hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
	},

	/*
	* Calculate the MD5 of an array of little-endian words, and a bit length
	*/
	core_md5: function(x, len) {
		/* append padding */
		x[len >> 5] |= 0x80 << ((len) % 32);
		x[(((len + 64) >>> 9) << 4) + 14] = len;

		var a = 1732584193;
		var b = -271733879;
		var c = -1732584194;
		var d = 271733878;

		for (var i = 0; i < x.length; i += 16) {
			var olda = a;
			var oldb = b;
			var oldc = c;
			var oldd = d;

			a = this.md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
			d = this.md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
			c = this.md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
			b = this.md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
			a = this.md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
			d = this.md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
			c = this.md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
			b = this.md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
			a = this.md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
			d = this.md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
			c = this.md5_ff(c, d, a, b, x[i + 10], 17, -42063);
			b = this.md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
			a = this.md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
			d = this.md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
			c = this.md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
			b = this.md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);

			a = this.md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
			d = this.md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
			c = this.md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
			b = this.md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
			a = this.md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
			d = this.md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
			c = this.md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
			b = this.md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
			a = this.md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
			d = this.md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
			c = this.md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
			b = this.md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
			a = this.md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
			d = this.md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
			c = this.md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
			b = this.md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);

			a = this.md5_hh(a, b, c, d, x[i + 5], 4, -378558);
			d = this.md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
			c = this.md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
			b = this.md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
			a = this.md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
			d = this.md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
			c = this.md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
			b = this.md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
			a = this.md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
			d = this.md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
			c = this.md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
			b = this.md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
			a = this.md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
			d = this.md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
			c = this.md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
			b = this.md5_hh(b, c, d, a, x[i + 2], 23, -995338651);

			a = this.md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
			d = this.md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
			c = this.md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
			b = this.md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
			a = this.md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
			d = this.md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
			c = this.md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
			b = this.md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
			a = this.md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
			d = this.md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
			c = this.md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
			b = this.md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
			a = this.md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
			d = this.md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
			c = this.md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
			b = this.md5_ii(b, c, d, a, x[i + 9], 21, -343485551);

			a = this.safe_add(a, olda);
			b = this.safe_add(b, oldb);
			c = this.safe_add(c, oldc);
			d = this.safe_add(d, oldd);
		}
		return Array(a, b, c, d);

	},

	/*
	* These functions implement the four basic operations the algorithm uses.
	*/
	md5_cmn: function(q, a, b, x, s, t) {
		return this.safe_add(this.bit_rol(this.safe_add(this.safe_add(a, q), this.safe_add(x, t)), s), b);
	},
	md5_ff: function(a, b, c, d, x, s, t) {
		return this.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
	},
	md5_gg: function(a, b, c, d, x, s, t) {
		return this.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
	},
	md5_hh: function(a, b, c, d, x, s, t) {
		return this.md5_cmn(b ^ c ^ d, a, b, x, s, t);
	},
	md5_ii: function(a, b, c, d, x, s, t) {
		return this.md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
	},

	/*
	* Calculate the HMAC-MD5, of a key and some data
	*/
	core_hmac_md5: function(key, data) {
		var bkey = this.str2binl(key);
		if (bkey.length > 16) bkey = this.core_md5(bkey, key.length * this.chrsz);

		var ipad = Array(16), opad = Array(16);
		for (var i = 0; i < 16; i++) {
			ipad[i] = bkey[i] ^ 0x36363636;
			opad[i] = bkey[i] ^ 0x5C5C5C5C;
		}

		var hash = this.core_md5(ipad.concat(this.str2binl(data)), 512 + data.length * this.chrsz);
		return this.core_md5(opad.concat(hash), 512 + 128);
	},

	/*
	* Add integers, wrapping at 2^32. This uses 16-bit operations internally
	* to work around bugs in some JS interpreters.
	*/
	safe_add: function(x, y) {
		var lsw = (x & 0xFFFF) + (y & 0xFFFF);
		var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
		return (msw << 16) | (lsw & 0xFFFF);
	},

	/*
	* Bitwise rotate a 32-bit number to the left.
	*/
	bit_rol: function(num, cnt) {
		return (num << cnt) | (num >>> (32 - cnt));
	},

	/*
	* Convert a string to an array of little-endian words
	* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
	*/
	str2binl: function(str) {
		var bin = Array();
		var mask = (1 << this.chrsz) - 1;
		for (var i = 0; i < str.length * this.chrsz; i += this.chrsz)
			bin[i >> 5] |= (str.charCodeAt(i / this.chrsz) & mask) << (i % 32);
		return bin;
	},

	/*
	* Convert an array of little-endian words to a string
	*/
	binl2str: function(bin) {
		var str = "";
		var mask = (1 << this.chrsz) - 1;
		for (var i = 0; i < bin.length * 32; i += this.chrsz)
			str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
		return str;
	},

	/*
	* Convert an array of little-endian words to a hex string.
	*/
	binl2hex: function(binarray) {
		var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
		var str = "";
		for (var i = 0; i < binarray.length * 4; i++) {
			str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
			   hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
		}
		return str;
	},

	/*
	* Convert an array of little-endian words to a base-64 string
	*/
	binl2b64: function(binarray) {
		var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
		var str = "";
		for (var i = 0; i < binarray.length * 4; i += 3) {
			var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16)
					| (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8)
					| ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
			for (var j = 0; j < 4; j++) {
				if (i * 8 + j * 6 > binarray.length * 32) str += this.b64pad;
				else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
			}
		}
		return str;
	}
}


///////////////////////////////////////////////////////
//   TD.Forms
///////////////////////////////////////////////////////


TD.Forms = {

	IsPressedEnter: function(e) {
		var event = window.event || e;
		var key = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
		return (key == 13);
	},

	IsEmail: function(_email) {
		///^(\w+[\-\.])*\w+@(\w+\.)+[A-Za-z]+$/
		email_re1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)|(\.$)/;
		email_re2 = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
		if (_email == "" || email_re1.exec(_email) || !email_re2.exec(_email))
			return false;
		return true;
	},

	//C#
	//Date: DateTime.ToShortDateString();
	//Date and Time: DateTime.ToShortDateString() + " " + DateTime.ToShortTimeString();
	AddCalendar: function(input, showsTime) {
		if (input.HasCalendar === undefined) {
			input.HasCalendar = true;

			if (input.id == '')
				input.id = 'Calendar' + Math.floor(Math.random() * 1001);
			jQuery(input).attr("readonly", "readonly");
			//jQuery(input).addClass("td_input_calendar");

			showsTime = (showsTime == true) ? true : false;
			var ifFormat = (showsTime == true) ? "%m/%d/%Y %I:%M %p" : "%m/%d/%Y"; //"en-US"

			Calendar.setup({
				inputField: input.id,
				ifFormat: ifFormat,
				showsTime: showsTime,
				timeFormat: "24", //"en-US"
				eventName: 'click'
			});
		}
	},

	Select: {

		OptionAdd: function(_objSelect, _text, _value) {
			if (TD.Framework.Browser.IE) {
				var _objOption = document.createElement("OPTION");
				_objOption.text = _text;
				_objOption.value = _value;
				_objSelect.add(_objOption);
			}
			else {// if (TD.Framework.Browser.Gecko || TD.Framework.Browser.Opera) {
				var _nextOption = _objSelect.options.length;
				_objOption = new Option(_text, _value);
				_objSelect.options[_nextOption] = _objOption
			}
		},
		OptionInsert: function(_objSelect, _text, _value, _position) {
			_itemsTextsBackup = new Array()
			_itemsValuesBackup = new Array()
			for (i = _position; i < _objSelect.length; i++) {
				_itemsTextsBackup.push(_objSelect[i].text)
				_itemsValuesBackup.push(_objSelect[i].value)
			}
			TD.Forms.Select.OptionDelete(_objSelect, _position)
			TD.Forms.Select.OptionAdd(_objSelect, _text, _value)
			for (i = 0; i < _itemsValuesBackup.length; i++)
				TD.Forms.Select.OptionAdd(_objSelect, _itemsTextsBackup[i], _itemsValuesBackup[i])
		},
		OptionDelete: function(_objSelect, _start, _length) {
			if (_start == null || _start < 0)
				_start = 0;
			if (_length == null || _length < 0 || _length == 0)
				_elements = _objSelect.length;
			else
				_elements = (_length > (_objSelect.length - _start)) ? _objSelect.length - _start : _start + _length;
			for (i = _start; i < _elements; i++)
				_objSelect.options[_start] = null;
		},
		OptionSelect: function(_objSelect, _index) {
			_index = (_index == null || _index >= _objSelect.length) ? 0 : _index;
			if (TD.Framework.Browser.IE || TD.Framework.Browser.Opera)
				_objSelect.selectedIndex = _index
			if (TD.Framework.Browser.Gecko)
				_objSelect.options[_index].selected = true
		},
		OptionSelectValue: function(_objSelect, _value) {
			_elements = _objSelect.length
			for (i = 0; i < _elements; i++) {
				if (_objSelect.options[i].value == _value) {
					_objSelect.options[i].selected = true;
					return;
				}
			}
		}
	},
	Serialize: function(selector, isOutputJSON) {
		var $src = jQuery(selector).clone(true);
		var $form = jQuery("<form></form>").append($src);
		return (!isOutputJSON) ? $form.serialize() : $form.serializeArray();
	}
}

jQuery(document).ready(function () {
	TD.Framework.PageOnLoad();
	TD.Facebook.PageOnLoad();
});

TD.ProjectCityNews = {
    latest: null,
    // TODO: set cookie domain to use the value below. 
    cookieDomain: window.location.hostname.replace(/www./, '.'),
    lastVisitCookieName: "UserLastLogin",

    TimeSincePublished2: function (tsclass, sysdate, displaytext, predicate, maxsecondsOverride) {
        var curdate, pubdate;
        var days, hours, minutes;
        var timetext;
        var timespans;
        var difference;
        var predicateString, timestampstring;
        var maxseconds = maxsecondsOverride || 5400;
        var SECONDS = {
            DAY: 24 * 60 * 60,
            HOUR: 60 * 60,
            MIN: 60
        }

        curdate = new Date((sysdate.length > 1) ? sysdate : Date());

        //find all spans with tsclass
        timespans = jQuery('span.' + tsclass);

        for (var i = 0; i < timespans.length; i++) {
            timespan = jQuery(timespans[i]);

            timetext = timespan.html().replace(/^\s*(\S*(\s+\S+)*)\s*$/, '$1');
            if (!timetext) return;

            pubdate = new Date(timetext);
            difference = curdate.getTime() - pubdate.getTime();
            difference = difference / 1000;

            if (difference <= maxseconds && difference > 0) {
                days = Math.floor(difference / SECONDS.DAY);
                hours = Math.floor((difference - (days * SECONDS.DAY)) / SECONDS.HOUR);
                minutes = Math.floor((difference - (days * SECONDS.DAY) - (hours * SECONDS.HOUR)) / SECONDS.MIN);
                if (days || hours || minutes) {
                    predicateString = (!!displaytext) ? displaytext + " " : "";
                    timestampstring = (!!days) ? days + " day" + (days > 1 ? "s" : "") + " " : "";
                    timestampstring += (!!hours) ? hours + " hour" + (hours > 1 ? "s" : "") + " " : "";
                    timestampstring += (!!minutes) ? minutes + " minute" + (minutes > 1 ? "s" : "") + " " : "";
                    timespan.html(predicateString + timestampstring + "ago");
                    timespan.addClass('td-red');
                }
            } else {
                if (difference > maxseconds) {
                    predicateString = "";
                    if (displaytext != '')
                        predicateString = displaytext + " ";
                    if (predicate != '')
                        predicateString += predicate + " ";
                    timespan.html(predicateString + pubdate.toDateString());
                }
                else {
                    timespan.html('');
                }
            }
            timespan.removeClass('td-hidden_block');
        };
    },

    /* Attach 'NEW' or 'UPDATED' to the beginning of the article's title if it
    has only published within 60 minutes. */
    AttachAlertText: function (tagClass, sysdate, titletag_prefix, alert_text) {
        var timetags;
        var timetag;
        var timetext;

        var currdate;
        var pubdate;
        var timediff;

        var titletag_id;
        var titletag_index;

        currdate = new Date((sysdate.length > 1) ? sysdate : Date());
        timetags = jQuery("." + tagClass);

        for (var i = 0; i < timetags.length; i++) {
            timetag = jQuery(timetags[i]);

            timetext = timetag.html().replace(/^\s*(\S*(\s+\S+)*)\s*$/, '$1');

            if (!timetext) return;
            pubdate = new Date(timetext);

            timediff = currdate.getTime() - pubdate.getTime();
            timediff = timediff / 60000; // From milliseconds to minutes

            if (timediff <= 60) {
                titletag_id = timetag.attr("id");
                titletag_index = (titletag_id.split('_'))[1];
                $("#" + titletag_prefix + "_" + titletag_index).html(alert_text);
            }
        }
    }
}
