////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DataHandler Object
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var DOWNLOADING_STATUS 	= "downloading";
var DOWNLOADED_STATUS 	= "downloaded";

var WEBWAG_WIDGET 		= "webwag_widget";
var GOOGLE_GADGET 		= "google_gadget";
var YAHOO_WIDGET 		= "yahoo_widget";
var NETVIBES_WIDGET 	= "netvibes_widget";
var PAGEFLAKES_WIDGET 	= "pageflakes_widget";

// Formats
var JSON 				= "json";
var XML 				= "xml";
var TEXT 				= "text";

// Handles the communication with database.
// In a local data handling, widgets data is only stored locally in the client.
// The default data handling level is set to SERVER_DATA_HANDLING
//
var DataHandler = Class.create();
DataHandler.prototype = {	
		
	// constructor
	initialize: function(level) {
		this.widgetClasses = {};
		this.widgetSettings = {};
		
		// default platform
		// It can be reset in the setup.js file with the client details (just as for the iphone) :
		//
		//     var client = {
		// 	       platform : "iphone"
		//     };
		//     dataHandler.platform = client.platform;
		//
		this.platform = "web";
	},
		
	// methods
	login: function(userName, password) {
		if (this.platform == "web") {
			App.loading(1);
		}
		var loadDetails = this.handleUserDetails;
		var handleLoginRequest = function(request) {
			App.loading(0);
			loadDetails(request, true);
		};
		new Ajax.Request("/user/login?platform=web&userName="+encodeURIComponent(userName)+"&password="+encodeURIComponent(password),
		{onComplete : handleLoginRequest, onException: DataHandler.handleAjaxException});
	},
	
	logout: function() {
		var from = getCookie("from");
		var params = (from)?"?from="+encodeURIComponent(from):"";
		
		deleteCookie("session_id");
		deleteCookie("from");
		
		if (!from)
			new Ajax.Request("/user/logout",	{onComplete : App.reload, onException: DataHandler.handleAjaxException});
		else
			document.location = "/user/logout"+params;
	},
	
	quit: function() {
		var handleQuitRequest = function(request) {
		};
		new Ajax.Request('/user/quit?platform=web&userId='+user.id, {asynchronous: false, onComplete : handleQuitRequest, onException: DataHandler.handleAjaxException});
	},
	
	requestPasswordRecovery: function(userName) {
		App.loading(1);
		var handlePassRecoveryRequest = function(request) {
			App.loading(0);
			if (request.responseText == "1") {
				alert(_("PASSWORD_RECOVERY_REQUEST_OK"));
				App.closePassRecoveryBox();
			}
			else if (request.responseText == "2") {
				alert(_("PASSWORD_RECOVERY_SFR_REQUEST_OK"));
				App.closePassRecoveryBox();
			}
			else {
				alert(_("PASSWORD_RECOVERY_REQUEST_FAILED"));
			}
		};
		
		if (!userName) {
			userName = "";
		}
		new Ajax.Request("/user/open_recovery_ticket?userName="+userName, {onComplete : handlePassRecoveryRequest, onException: DataHandler.handleAjaxException});
	},
	
	getRssCategoryContent: function(parentId) {
		if (!parentId) {
			parentId = "0";
		}
		var lang = "en";
		
		var handleRssCategoryContent = function(request) {
			var categoryContent = request.responseText.evalJSON();
		};
		
		new Ajax.Request("/rss/get_categories/?platform=web&parentId="+parentId+"&lang="+lang, {method: "GET", onComplete : handleRssCategoryContent, onException: DataHandler.handleAjaxException});
	},
	
	handleUserDetails : function(request, reload) {
		
		
		debugEcho("handleUserDetails: datalen="+request.responseText.length);
		var userDetails = eval("("+request.responseText+")"); //request.responseText.evalJSON();
		var userSettings,e,tabs = [];
		debugEcho("handleUserDetails: josn evaluated");
		if (!userDetails || userDetails.status=="logged_out"){
			alert(_("ERROR_EMAIL_OR_PASSWORD"));
			return false;		
		}
		userSettings = userDetails.settings;
		
		userSettings.partner = userDetails.partner;
		if (userDetails.status!="logged_in") {
			App.showLogin();
			return;
		}
			
		if(App.popupLogin) {
			App.popupLogin.state(0);
		}
		if (App.elLogin) {
			App.elLogin.innerHTML = _("SIGN_"+(user.email?"OUT":"IN"));
		}
		for (var i = 0; i < userDetails.tabs.length; ++i) {
			// get tabs widgets
			var widgets = [];
			for (var j = 0; j < userDetails.tabs[i].widgets.length; ++j) {
				//debugEcho(userDetails.tabs[i]);
				if (userDetails.tabs[i].widgets[j] && userDetails.tabs[i].widgets[j].settings) {
					widgets[j] = new Widget("", userDetails.tabs[i].widgets[j].settings, userDetails.tabs[i].widgets[j].descriptions);
				}
				
				//debugEcho("widgetloop: ",widgets[j]);
			}
			tabs[i] = new Tab(userDetails.tabs[i].settings, widgets);
		}
		
		user = new User(userSettings, tabs);
		
		// Check that user is not SFR. Otherwise, log the user out.
		//
		if(	client.platform != "sfr_monsfr" && 
			user.partner_id == 2) {
			
			dataHandler.logout();
			return false;
		}
		
		// Only write cookies for non sfr users
		//
		if (client.platform != "sfr_monsfr") {
			var cp = location.pathname.substr(0,location.pathname.lastIndexOf("/")+1);
			if(cp=="/startup/"){
				cp = "/";
			}
			setCookie("session_id", user.session_id, 365*86400, cp);
			setCookie("user_id", user.id, 365*86400, cp);
			setCookie("startup", "true", 365*86400, cp);
		}

		
		// set cookies
		
		
		// if the we are not on the home page, we relaod the application
		if (reload) {
			App.reload();
			return false;
        }
		if (window.currentTheme && currentTheme != user.theme && !user.theme.match(/easy_/)) {
			App.settings.switchCSS(user.theme);
		}
		else if (user.theme.match(/easy_/)) {
			user.theme = currentTheme;
		}
		
		// if the user has no tab, a new one is added
        if (!user.tabs || !user.tabs.length) {
            dataHandler.addTab();
            App.reload();
            return false;
        }

		if(client.platform == "sfr_monsfr" && location.pathname.indexOf("/monsfr") != 0) {
			if(!App.checkAuthUser(user.email)){
				App.showLoginForDev();
				return false;
			}
		}
		try{
			if (client.platform != "sfr_monsfr") {
				listener = new SubscriptionsListener();		
				var url=document.location+" ";
				var domaine=url.substring(0,url.indexOf("/",7));
				listener.subscribe(0,domaine+"/services/subscription/widget_sender.php?bla=bla",renderer.showMessages,"MAIN","Renderer",0);
			}
		}catch(e){
		}
		renderer.renderUser();
		//App.setCookie();
		logger.log("loaded user "+user.id);
		
		dataHandler.loadFeedsDetails();	
	},

	loadUser: function() {
		
		var sessionId 	= getCookie("session_id");
		var userId 		= getCookie("user_id");
		
		
		var params = "platform=web&from="+this.platform+"&userId="+userId+"&sessionId="+sessionId;
		// if (window.lang)
		// 	params+="&lang="+window.lang;
		new Ajax.Request('/user/load_details',{parameters : params, onComplete : this.handleUserDetails, onException: function(request,e){
			//alert("");
			debugEcho("loadUser [ajax callback execption]: status="+request.transport.status,request,$H(e).inspect(),request.transport,"resp="+request.responseText);
			if(request.transport.status==500){
				logger.log("Erreur de chargement",ERROR);
			}
			DataHandler.handleAjaxException(request,e);
		}});
	},
	
	loadWidget: function(widgetId, src, callback) {
		var handleWidgetDetails = function(request) {
			var widgetDetails = request.responseText.evalJSON();
			widget = new Widget("", widgetDetails.settings, widgetDetails.descriptions);			
			if(callback){
				callback(widget);
			}else{
				if (renderer.isContainerRendered(widget.id)) {
					Widget.run(widget.id);
				}
				else {
					widget.render();
				}
			}
		};
		
		new Ajax.Request("/widget/get_widget/?platform=web&id="+widgetId, {method: "GET", onComplete : handleWidgetDetails, onException: DataHandler.handleAjaxException});
	},
	

	
	downloadWidget: function(widgetToDownload) {
	//	var widget;
		if (widgetToDownload && widgetToDownload.id && widgetToDownload.src) {

			// the widget is added to the listener in order to be displayed
			// as soon as the download completes.
			this.addToDownloadListener(widgetToDownload.id, widgetToDownload.src);

			if (!global.downloads[widgetToDownload.src] || global.downloads[widgetToDownload.src] != DOWNLOADING_STATUS) {
				//debugEcho("dataHandler.downloadWidget: widgetToDownload.src="+widgetToDownload.src,widgetToDownload);
				var ajax_url="/proxy/widget_src?lang="+user.language+"&url=";
				
				// At the moment we will pass every widget through the proxy to be
				// able to handle the translations from the backend.
				//
				// if (widgetToDownload.src.indexOf("http://") == -1) {
				// 	ajax_url="widgets/";
				// }

				var handleDownload = function(request) {
					
					global.downloads[widgetToDownload.src] = DOWNLOADED_STATUS;
					
					var settings = {
						src: widgetToDownload.src
					};
					
					// If the widget cannot be parsed, we generate an error
					if(!request.responseXML  || (Prototype.Browser.Gecko && request.responseXML.firstChild.nodeName == "parsererror")) {
						widget = new Widget("<b>Download Error</b> (status = "+request.status+")<br/>Could not get a valid XML widget from "+widgetToDownload.src, settings);
						logger.log("Could not get a valid XML widget from <a href=\""+ajax_url+encodeURI(widgetToDownload.src)+"\">"+ajax_url+encodeURI(widgetToDownload.src)+"</a><br/><br/> XMLHTTP Status : "+request.status+" "+request.statusText, ERROR);
					}
					else {
						
						//////////////////////////////////////////////////////////////////////////////////
						// Init widget

						widget = new Widget("", settings);						
						
						
						var root 	= findChild(request.responseXML, "widget");
						var configs	= root.getElementsByTagName("config");
						var config 	= null;
						var title 	= "";
						var icon 	= "";
						
						// Check configs and compatibilities
						var compatibility = "";
						for (var i=0; i < configs.length; i++) {
							if (!configs[i].getAttribute("platform") || configs[i].getAttribute("platform") == "web") {
								config 	= configs[i];
								title 	= getData(findChild(config, "title"));
								icon 	= getData(findChild(config, "icon"));
								if (compatibility != "") {
									compatibility += ",";
								}
								compatibility += "web";
							}
							else if (configs[i].getAttribute("platform") && configs[i].getAttribute("platform") != "") {
								if (compatibility != "") {
									compatibility += ",";
								}
								compatibility += configs[i].getAttribute("platform");
							}
						};
						
						widget.web_icon 		= icon;
						widget.prefs["src"] 	= new Pref("src", widgetToDownload.src, "hidden", "");
						widget.title 			= title;
						widget.settings["_compatibility"] = compatibility;
						
						
						
						//////////////////////////////////////////////////////////////////////////////////
						// Load script
						var scriptElem = findChild(root, "script");
						var script 	= "";
						if (scriptElem) {
							script = getData(scriptElem);
						}
						
						
						//////////////////////////////////////////////////////////////////////////////////
						// Loading style
						var style 	= getData(findChild(root, "style"));
						if (style) {
							addStyle(style);         
						}


						//////////////////////////////////////////////////////////////////////////////////
						// Loading content
						var contentElem = findChild(root, "content");
						var content = "";
						
						var foundViews = false;
						
						if (contentElem) {
							
							// load views
							var position = 0;
							for (var i = 0; i < contentElem.childNodes.length; i++) { 
								var elem = contentElem.childNodes.item(i); 
								if (elem != undefined && elem != null && elem.nodeName == "view") {
									foundViews 		= true;
									var viewName 	= elem.getAttribute("name");
									var viewType 	= elem.getAttribute("type");
									var viewData 	= getData(elem);
									
									widget._views[viewName] = new View(viewName, viewData, viewType);
									
									// We load the first view as the default content.
									if (position == 0) {
										widget._defaultViewName = viewName;
										widget._currentViewName = viewName;
										content = viewData;
									}
									position ++;
								}
							}
							
							// If there is no view we load the content directly from the <content/> element.
							if (!foundViews) {
								content = getData(contentElem);
							}
						}
						
						// If there is no view we create a default one from the content variable.
						if (!foundViews) {
							widget._views[View.DEFAULT_NAME] = new View(View.DEFAULT_NAME, content, View.DEFAULT_TYPE);
							widget._defaultViewName = View.DEFAULT_NAME;
							widget._currentViewName = View.DEFAULT_NAME;
						}
						
						// Set the default content (default view content)
						widget.content = content;
						
						
						//////////////////////////////////////////////////////////////////////////////////
						// Loading prefs
						var prefs 	= findChild(root, "prefs");
						if (prefs) {
							if (prefs.getAttribute("type") && prefs.getAttribute("type") == "html") {
								widget._form = getData(prefs);
							}
							else {
								for (var i = 0; i < prefs.childNodes.length; i++) { 
									var pref = prefs.childNodes.item(i); 
									if (pref != undefined && pref != null && pref.nodeName == "pref") {
										var prefKey 	= pref.getAttribute("name");
										var prefValue 	= pref.getAttribute("value");
										var prefType 	= pref.getAttribute("type");
										var prefLabel 	= pref.getAttribute("label");
										var prefOutput 	= pref.getAttribute("output");
										var prefElems 	= {};
										if (prefType == "list" || prefType == "color") {
											for (j = 0; j < pref.childNodes.length; j++) {
												var child = pref.childNodes.item(j); 
												if (child.nodeName == "option") {
													var optionValue = child.getAttribute("value");
													var optionLabel = child.getAttribute("label");
													prefElems[optionValue] = optionLabel;
												} 
											}
										}
										widget.prefs[prefKey] = new Pref(prefKey, prefValue, prefType, prefLabel, prefElems, prefOutput);
										if(prefOutput && prefOutput == "title") {
											widget._titleSettingName = prefKey;
										}
									}
								}
							}
						}

						// Eval script
						var ow=widget;
						eval("try { \n"+script+"\n } catch(e) { logger.log(\"downloadWidget: <b>Internal Widget Error :</b> \"+e.name+\"\\n\\n\"+e.message, ERROR);\
						debugEcho(\"downloadWidget: <b>Internal Widget Error :</b> \"+e.name+\"\\n\\n\"+e.message); }");
						if(ow != widget){
							Object.extend(widget,ow);
						}
					}

					// Store widget class
					//debugEcho("widget.src="+widget.src+"  ",global.widgetClasses);
					global.widgetClasses[widget.src] = Object.clone(widget);


					// Load widgets waiting in the listener.
					var currentListener = global.downloadListener[widget.src];
					for (var i in currentListener) {
						// We can run all widgets requesting the download.
						debugEcho("dataHandler.downloadWidget: calling Widget.run for "+i+"  ");
						Widget.run(currentListener[i]);
					}
					global.downloadListener[widget.src] = {};
				};

				global.downloads[widgetToDownload.src] = DOWNLOADING_STATUS;
				new Ajax.Request(ajax_url+encodeURI(widgetToDownload.src), {method: 'GET', onComplete: handleDownload/*, onException: DataHandler.handleAjaxException*/});
			}
		}
		else {
			logger.log("Could not download Widget.\n The widget may not have been initialized correctly.", ERROR);
		}
		
	},
	
	saveUser: function() {
		var handleSaveUser = function(request) {
			user.callback("onSave");
		};
		
		var params = "";
		params += "&language=" + user.language;
		params += "&theme=" + user.theme;
		
		new Ajax.Request("/user/update", {
		  				method		: "post",
	  					postBody	: "sessionId=" + user.session_id + "&userId=" + user.id + params,
	  					onComplete	: handleSaveUser
		});
	},
	
	saveTabs: function(tabs) {
		debugEcho("savetabs: ",tabs);
		// Handle response
		var handleSaveTabs = function(request) {
			if (!request.responseText) {
				logger.log("dataHandler.saveTabs:  Server Error : Tabs could not be saved.", ERROR);
				return;
			}
		};
		var xmlTabs = "";
		for(var i in tabs) {
			if(typeof tabs[i] =="function")
				continue;
			xmlTabs += tabs[i].toXML();
			tabs[i].backup();// we backup the informations but we're not sure that they were correctly saved...
		}
		if (xmlTabs) {
			var xml = "<tabs>\n"+xmlTabs+"\n</tabs>";
			var params = "platform=web&userId="+user.id+"&sessionId="+user.session_id+"&root="+encodeURIComponent(xml);
			debugEcho("savetabs: "+xml);
			new Ajax.Request('/user/save_tabs', {method: 'POST', parameters : params, onComplete : handleSaveTabs, onException: function(){
				DataHandler.handleAjaxException();
				App.alert("Unexpected error on save tabs settings!");
				}
			});
		}
	},
	// if isDemo, return tab instance, there is no callback
	addTab: function(tabdata,isDemo,callback) {
		var position = user.tabs?user.tabs.length:0;// if called an account not loaded (if serach performed by url param query=xxx )
		App.loading(1);
		// Handle response
		var handleAddTab = function(request) {
			if (request.responseText == "0") {
				logger.log("dataHandler.addTab:  Server Error : Tab could not be saved.", ERROR);
			}
			else {
				var t,tab;
				if(request.responseText)
					tab = request.responseText.evalJSON();
				else
					tab = {settings:request};
				
				// get tabs widgets
				var widgets = [];
				if (tab.widgets) {
					for (var j = 0; j < tab.widgets.length; ++j) {
						widgets[j] = new Widget("", tab.widgets[j].settings, tab.widgets[j].descriptions);
					}
				}
				debugEcho("tab.settings,tab",tab.settings,tab);
				
				if (!tab.settings.name)
				tab.settings.name=_("NEW_TAB");
				t = new Tab(tab.settings, widgets);
				if(isDemo){
					if (!user.demoTabs)
						user.demoTabs=[];
					t.demo=1;
					t.id="$"+String.random(5)+"$";
					user.demoTabs.push(t);
				}
				else
					user.tabs[position] = t;
				t.render();
				renderer.makeTabsSortable();
				t.show();
				if(callback)
					callback(t);
				App.loading(0);
				if(isDemo)
					return t;
				dataHandler.iphoneAddTab(t);
			}
		};
		
		if(isDemo){
			tabdata.demo=1;
			return handleAddTab(tabdata);
		}
		else {
			var params = "platform=web&userId="+user.id+"&sessionId="+user.session_id+"&tabPosition="+position;
			if (tabdata && tabdata.name){
				params += "&name=" + tabdata.name;
			}
			if (tabdata && tabdata.type == "search") {
				params += "&type=" + tabdata.type + "&value=" + tabdata.value;
			}
			new Ajax.Request('/user/add_tab', {method: 'POST', parameters : params, onComplete : handleAddTab, onException: DataHandler.handleAjaxException});
		}
	},
	
	iphoneAddTab: function(objTab) {
	},
	
	removeTab: function(tabId) {
		// Handle response
		var handleRemoveTab = function(request) {
			if (request.responseText == "0") {
				logger.log("dataHandler.removeTab:  Server Error : Tab could not be removed.", ERROR);
			}
		};		
		for(var widgetId in global.widgets) {
			if(global.widgets[widgetId].settings.tab==tabId){
				global.widgets[widgetId].remove();
			}
		}
		var params = "platform=web&tabId="+tabId;
		new Ajax.Request('/user/remove_tab', {method: 'POST', parameters : params, onComplete : function(){}, onException: DataHandler.handleAjaxException});
	},
	// hash widgets, bool blockCallback, bool fullUpdate
	saveWidgets: function(widgets, blockCallback, fullUpdate) {
		// Handle response
		var handleSaveWidgets = function(request) {
			if (request.responseText == "0") {
				logger.log("dataHandler.saveWidgets:  Server Error : widget could not be saved.", ERROR);
			}
			
			var widgetId = null;
			
			for(var i in widgets) {
				widgets[i].hideStatus();
				widgetId = widgets[i].id;
				
				// If we are on the iphone, we reload the first level display.
				if (widget.clientPlatform == "iphone") {
					global.widgets[widgetId].render();
				}
				
				if (!blockCallback && widgetId != null) {
					global.widgets[widgetId].callback("onSave");
				}
			}
		};
		var xmlWidgets = "";
		for(var i in widgets) {
			var currentXml = widgets[i].toXML(fullUpdate);
			xmlWidgets += currentXml;
			if (!blockCallback && currentXml && currentXml != "") {
				widgets[i].showStatus("saving data...", "progress");
			}
		}
		
		if (xmlWidgets) {
			var xml = "<widgets>\n"+xmlWidgets+"\n</widgets>";
			debugEcho("saving widgets:   "+xml);
			var params = "platform=web&userId="+user.id+"&sessionId="+user.session_id+"&root="+encodeURIComponent(xml);
			new Ajax.Request('/user/save_settings', {method: 'POST', parameters : params, onComplete : handleSaveWidgets, onException: DataHandler.handleAjaxException});
		}
	},
	
	// Instanciates a new widget for the current user.
	// This will add the widget at the top of the current tab.
	//
	addWidget: function(src, prefs, isDemo, makeMobileAvailable) {
		if(makeMobileAvailable){
			var globalMakeMobileAvailable =true;
		}else{
			var globalMakeMobileAvailable =false;
		}
		var handleAddWidget = function(request) {
			if (request.responseText == "0") {
				logger.log("Server Error : widget could not be added.", ERROR);
			}
			else {
				var jsonWidgets 	= request.responseText.evalJSON();
				var settings 		= jsonWidgets[0].settings;
				var descriptions 	= jsonWidgets[0].descriptions;

				// We can load the new widget.
				debugEcho("new widget:   settings,description",settings,descriptions);
				var p,addedWidget = new Widget("", settings, descriptions);
				if(prefs){
					for(p in prefs) {
						addedWidget.setValue(p,prefs[p]);
					}
				}
				addedWidget.callback("onAdd");  //callback  onAdd to define in client
				debugEcho("new widget:   addedWidget before render:",addedWidget);
				addedWidget.render();
				
				if(globalMakeMobileAvailable){
					global.screens['mobile'].addWidget(addedWidget.id);
				}
				
				for (type in global.screens) {
					if (addedWidget._isScreenCompatible(type)) {
/* 						var a = addedWidget.getValue("availability");
						if (a.indexOf(type)!=-1){
							App.notice(_("ALREADY_ON_"+type.toUpperCase()));
							return;
						} */
						global.screens[type].renderWidget(addedWidget);
					}
				}
				debugEcho("new widget:   addedWidget",addedWidget);
			}
		};
		// load xml		
		
		var p,t="",sharingId=0;
		if(prefs){
			for(p in prefs) {
				t += p+"=\""+String(prefs[p]).encodeXML()+"\" ";
				if( p == "sharing_"){
					sharingId=prefs[p];
				}
			}
			debugEcho("addWidget:src="+src+" prefs specified: t="+t,t);
		}			
		var xml = "<widget id=\""+(isDemo?0:-1)+"\" src=\""+src+"\" tab=\""+user.getCurrentTab().id+"\" "+t+"/>";
		var params = "platform=web&userId="+user.id+"&sessionId="+user.session_id+"&root="+encodeURIComponent(xml);
		if(sharingId>0){
			params += "&sharingId="+sharingId;
		}
		// Allow to add the widget on the mobile too
		
		new Ajax.Request('/widget/save', {method: 'POST', parameters : params, onComplete : handleAddWidget/* ,onException: DataHandler.handleAjaxException*/});
	},
	
	removeWidget: function(widgetId) {
		var param='id='+widgetId+"&platform=web&userId="+user.id+"&sessionId="+user.session_id;
		var widgetToRemove = global.widgets[widgetId];
		if (widgetToRemove && widgetToRemove.id) {
			// Handle response
			if(widgetToRemove.settings.sharing_){
				param+="&sharingId="+widgetToRemove.settings.sharing_;
			}
			var handleRemoveWidget = function(request) {
				if (request.responseText == "1") {
					delete global.widgets[widgetId];
				}
				else {
					logger.log("dataHandler.removeWidget:  Server Error : widget failed to be removed.", ERROR);
				}
			};
			
			new Ajax.Request('/widget/remove?'+param, {method: 'GET', onComplete: handleRemoveWidget, onException: DataHandler.handleAjaxException});
		}
		else {
			logger.log("dataHandler.removeWidget:  Could not remove Widget "+widgetId+".\nThe widget may not have been initialized correctly.", ERROR);
		}
	},
	
	// Adds a widget load request to the listener.
	// This widget will be loaded as soon as the download is done.
	//
	addToDownloadListener: function(widgetId, src) {
		var listener = global.downloadListener[src];
		if (!listener) {
			listener = {};
		}
		listener[widgetId] 				= widgetId;
		global.downloadListener[src] 	= listener;
	},
	
	requestFeed: function(widgetId, url, callback, lines, contentType, lastSeenId) {
		
		var currentId =  widgetId;

		var ajaxCallback = function(req) {
			// init callback
			if (typeof(callback) == "function") {
				widget = global.widgets[currentId];
				var json = req.responseText.evalJSON();
				callback.call(widget, json);
			}
			else {
				logger.log("Callback is not a function.", ERROR);
			}
		};
		
		var requestUrl = encodeURIComponent(url);
		if (lines) {
			requestUrl += "&lines="+lines;
		}
		if (contentType) {
			requestUrl += "&contentType="+contentType;
		}
		if (lastSeenId) {
			requestUrl += "&lastSeenId="+lastSeenId;
		}
		new Ajax.Request("/proxy/rss.php?userId="+user.id+"&format=json&url="+requestUrl, {
			method: 'GET', 
			onComplete: ajaxCallback
			//,onException: DataHandler.handleAjaxException
		});
	},

	//setRead(channelUrl, itemUrl,[callback,[cbparm]])
	setRead: function(channelUrl, itemUrl,callback,cbparm) {
		if(!callback)
			callback = function(){};
		new Ajax.Request("/rss/set_read?userId="+user.id+"&channelUrl="+encodeURIComponent(channelUrl)+"&itemUrl="+encodeURIComponent(itemUrl), {method: 'GET', onComplete: function(){ callback(cbparm); }, onException: DataHandler.handleAjaxException});
	},
	
	request: function(widgetId, url, callback, params, method, format, authParams) {
	//debugEcho("datahandler.request: ",widgetId, url, callback, params, method, format, authParams);
		//var widget = global.widgets[currentId];
		var currentId =  widgetId;
		if (typeof(callback) == "undefined")
			callback=function(){};

		var ajaxCallback = function(req) {
			// init callback
			if (typeof(callback) == "function") {
				//widget = Object.clone(global.widgets[currentId]);
				widget = global.widgets[currentId];
				
				widget.xmlHttpRequest = req; // V1 compatibility
				
				switch (format) {
				case TEXT:
					callback.call(widget, req.responseText);
					break;
				case XML:
					callback.call(widget, req.responseXML);
					break;
				case JSON:
					var json = req.responseText.evalJSON();
					callback.call(widget, json);
					break;
				default:
					callback.call(widget, req);
					break;
				}
			}
			else {
				logger.log("Callback is not a function.", ERROR);
			}
		};

		if(!method)
			method="GET";

		if (method != "GET") {
			method = "POST";
		}
		
		var ajax_url="/proxy/ajax/?url=";
		if (url.indexOf("http") != 0) {
			new Ajax.Request(url, {method: method, parameters: params, onComplete: ajaxCallback, onException: DataHandler.handleAjaxException});
		}
		else {
			var requestUrl = url;
			if (method!="POST"){
				if (params) {
					requestUrl += requestUrl.indexOf("?")>0?"&":"?" + params;
				}		
		}
			
			var serverParams="";
			if (authParams) {
				serverParams = "userId="+user.id;
				serverParams += "&"+authParams;
			}
			if (format) {
				serverParams += "format="+format;
			}
			
			//var params = "method="+(method?'POST':'GET')+"&url="+encodeURIComponent(url)+params;
			//new Ajax.Request("/proxy/ajax/", {method: 'POST', parameters : params, onComplete: ajaxCallback, onException: DataHandler.handleAjaxException});
			
			//var params = "method="+(method?'POST':'GET')+"&url="+encodeURIComponent(url)+params;
			//debugEcho("method="+method+"  "+params);
			new Ajax.Request("/proxy/ajax.php?method="+method+"&"+serverParams+"&url="+encodeURIComponent(requestUrl), {method: method, parameters : params, onComplete: ajaxCallback, onException: DataHandler.handleAjaxException});
		}
	},
	
	loadFeedsDetails : function() {
		var handleFeedsDetails = function(response) {
			eval("global.feedsDetails = " + response.responseText);
		};

		new Ajax.Request("/rss/feeds_details?userId="+user.id, {method: 'GET', onComplete: handleFeedsDetails, onException: DataHandler.handleAjaxException});
	},
	
	savePageName : function(){
		if(user.bak.page_name != user.page_name){
			new Ajax.Request("/user/update?noout=1&pageName="+encodeURIComponent(user.page_name), {method: 'GET', onComplete:
			function(){ user.bak.page_name = user.page_name;},			
			onException: DataHandler.handleAjaxException});
			
		}
	},
	loadDefaultProfile : function(){
		var uri = new URI(window.location.href);
		// load widgets
		var widget = new Widget("", DataHandler.getDefaultWidgetSettings(uri.getParam("src")));
		var widgets = [widget];
		// load tabs
		var tab = new Tab(DataHandler.getDefaultTabSettings(), widgets);
		var tabs = [tab];
		// load user
		var userSettings = DataHandler.getDefaultUserSettings();
		user = new User(userSettings, tabs);
		renderer.renderUser();			
		logger.log("loaded default user "+user.id);

		var settings = {
			id: "0",
			src: src
		};
	
		widget = new Widget("", settings);
		if (renderer.isContainerRendered(widget.id)) {
			Widget.run(widget.id);
		}
		else {
			renderer.renderWidgetContainer(widget);
		}
	
	}
	// End methods
};


DataHandler.handleAjaxException = function(request, e) {
	logger.log("DataHandler.handleAjaxException: Error during AJAX call to <a href=\""+request.url+"\">"+request.url+"</a>\n\n<span style=\"color:red;\">"+e.message+"</span>\n"+e.fileName+" - Line: "+e.lineNumber+"\n\n<b>Stack :</b>\n"+e.stack, ERROR);
};


DataHandler.getDefaultUserSettings = function() {
	return {
		id: "0"
	};
};

DataHandler.getDefaultTabSettings = function() {
	return {
		id: "0",
		name: "Main"
	};
};

DataHandler.getDefaultWidgetSettings = function(src) {
	return {
		id: "0",
		src: src
	};
};

