/**
 * Created by James Zhang
 * User: atmail
 * Date: 14/05/12
 * Time: 10:21 PM
 */

String.prototype.splice = function(idx, rem, s){
  return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
}

$.fn.serializeObject = function()
{
	var o = {};
	var a = this.serializeArray();
	$.each(a, function() {
		if (o[this.name] !== undefined) {
			if (!o[this.name].push) {
				o[this.name] = [o[this.name]];
			}
			o[this.name].push(this.value || '');
		} else {
			o[this.name] = this.value || '';
		}
	});
	return o;
};

/**
 * Convert number of bytes into human readable format
 *
 * @param integer bytes     Number of bytes to convert
 * @param integer precision Number of digits after the decimal separator
 * @return string
 */
function bytesToSize(bytes, precision)
{
	var kilobyte = 1024;
	var megabyte = kilobyte * 1024;
	var gigabyte = megabyte * 1024;
	var terabyte = gigabyte * 1024;

	if ((bytes >= 0) && (bytes < kilobyte)) {
		return bytes + ' B';

	} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
		return (bytes / kilobyte).toFixed(precision) + ' KB';

	} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
		return (bytes / megabyte).toFixed(precision) + ' MB';

	} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
		return (bytes / gigabyte).toFixed(precision) + ' GB';

	} else if (bytes >= terabyte) {
		return (bytes / terabyte).toFixed(precision) + ' TB';

	} else {
		return bytes + ' B';
	}
}

function htmlEscape(str) {
	return String(str)
		.replace(/&/g, '&amp;')
		.replace(/"/g, '&quot;')
		.replace(/'/g, '&#39;')
		.replace(/</g, '&lt;')
		.replace(/>/g, '&gt;');
}

function isAndroid() {
	return (navigator.userAgent.indexOf("Android")>=0);
}

var $mobile = {
	Account       : null,
	currentFolder : null,
	folerList     : null,
	autocompleteCacheSize : 50,
	processingLogin : false,
	settings : null

};

$mobile.saveSettings = function(settings) {
	this.settings = settings;
	sessionStorage.setItem('settings', settings);
}

$mobile.loadSettings = function() {
	if(!this.settings ) {
		this.settings = sessionStorage.getItem('settings');
	}
	return this.settings;
}

/*
 * ****************************************************************
 */

$mobile.getCountPerPage = function() {
	return this.settings['MsgNum'];
}

$mobile.isCookieEnabled = function()
{
	var cookieEnabled = (navigator.cookieEnabled) ? true : false;

	if (typeof navigator.cookieEnabled == "undefined" && !cookieEnabled)
	{
		document.cookie="testcookie";
		cookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false;
	}
	return (cookieEnabled);
}


$mobile.postJSON = function(url, postData, onSuccess) {

	$.mobile.showPageLoadingMsg('a');

	setTimeout(function(){
		$.mobile.hidePageLoadingMsg();
	}, 50000);

	$.ajax({
		type:"POST",
		url:url,
		dataType:"json",
		data:postData,
		success:function(json) {

			$.mobile.hidePageLoadingMsg();

			if(json && json["failed"]) {
				alert(json["message"]);

				if(json["message"].indexOf("Session expired")>=0) {
					$.mobile.changePage("#mobile_login",{transition:"slide", reverse:true});
				}
				return;
			}

			if(onSuccess) {
				onSuccess(json, status);
			}
			else {
				//console.warn("Warning: no callback defined for $mobile.postJSON from server");
			}
		},
		error:function() {
			$.mobile.hidePageLoadingMsg();

			onSuccess && onSuccess({result:'fail'});
			//alert("Failed to get request from server.");
		}
	});
};


$mobile.getAccount = function() {
	var settings = this.loadSettings();
	return settings? settings['Account'] : '';
}

$mobile.getSignature = function() {
	var settings = this.loadSettings();
	return settings? settings['Signature'] : '';
}

$mobile.isValid = function() {
	return this.getAccount()? true : false;
}

$mobile.setCurrentFolder = function(folder) {
	this.currentFolder = folder;
};

$mobile.getCurrentFolder = function() {
	return this.currentFolder;
};

$mobile.getCurrentFolderLocalName = function() {
	return this.currentFolder? this.currentFolder.localName : null;
};

$mobile.getCurrentFolderGlobalName = function() {
	return this.currentFolder? this.currentFolder.globalName : null;
};

$mobile.login = function(loginData, onSuccess) {

	if(this.processingLogin) return;

	this.processingLogin = true;
	setTimeout(function() {
		$mobile.processingLogin = false;
	}, 5000)

    var emailArgs = loginData.email.split('@');
    var postData = $.extend({
	    emailName : emailArgs[0],
	    emailDomain : emailArgs[1],
	    expectJson : 1,
	    expectSettings : 1
    }, loginData);

	var url = getAppBaseUrl() + "/mail/auth/processlogin";

    this.postJSON(url, postData, function(json) {

	    $mobile.processingLogin = false;
	    onSuccess && onSuccess(json);

    });
};

$mobile.logout = function() {
	localStorage.setItem('Account', null);
	
	this.postJSON("mail/auth/logout", {}, function() {
		$.mobile.changePage("#mobile_login", {transition:"slide", reverse:true});
		$('.message-panel', '#mobile_login').show();
		$('.login-input','#mobile_login').val('')
	})
}

$mobile.listEmails = function(folder, pageNo, onSuccess) {

    var postData = {
	    folder : folder,
	    range  : pageNo,
      limit : $mobile.countPerPage
    };

    this.postJSON("api/mail/list", postData, onSuccess);
};

$mobile.searchEmails = function(search, onSuccess) {

	this.postJSON("api/mail/search", {searchQuery:search}, onSuccess);
}

$mobile.loadEmails = function(folder, UIDs, onSuccess) {

	if(!(UIDs instanceof Array)) {
		UIDs = [UIDs];
	}
	// load from server
	var postData = {
		folder : folder,
		"uniqueId[]" : UIDs
	};

	var url = "api/mail/view/threadsEnabled/false/";

	$mobile.postJSON(url, postData, function(json) {
		if(json instanceof Array) {
			onSuccess && onSuccess(json);
		}
	});

};

$mobile.showEmail = function(folder, uniqueId, onSuccess) {

	if(!(uniqueId instanceof Array)) {
		uniqueId = [uniqueId];
	}

	// first check from localStorage
	messageCache.load(uniqueId, folder, function(message) {
		
		$mobile.setEmailSeen(uniqueId, folder);
		if(message) {
			//console.log('get message from websql', uniqueId, folder);

			onSuccess && onSuccess(message);
		}
		else {
			// load from server
			var postData = {
				folder : folder,
				"uniqueId" : uniqueId
			};

			var url = "api/mail/view/threadsEnabled/false/";

			$mobile.postJSON(url, postData, function(json) {
				if(json instanceof Array) {

					var message = json[0];

					messageCache.save(uniqueId, folder, message);

					$mail.setMail(uniqueId, message);
					onSuccess && onSuccess($mail.getMail(uniqueId));
				}
			});
		}

	});

};

$mobile.setEmailSeen = function(uniqueId, folder) {
	var url = "api/mail/setmessageseen/";
	var postData = {
		folder: folder,
		uid: uniqueId 
	}

	this.postJSON(url, postData, function(json){
    if(!json.success){
			alert('Unable to set message as read');
		}
	});
}

$mobile.sendEmail = function(data, callback) {
	this.postJSON("api/mail/send", data, function(response) {
		if(callback) {
			callback(response);
		}
		else {
			if(response && !response.error) {
				$.mobile.changePage("#mobile_maillist", {transition: 'slide', reverse:true});
			}
			else {
				alert("Send failed");
			}
		}
	});
}

$mobile.moveEmail = function(fromFolder, toFolder, uniqueId, onSuccess) {
	if(!(uniqueId instanceof Array)) {
		uniqueId = [uniqueId];
	}

	var postData = {
		fromFolder : fromFolder,
		toFolder   : toFolder,
		"mailId[]"    : uniqueId,
		listFolder : fromFolder,
		disableThread : true,
		expectJson : true
	};
	if(fromFolder === 'Trash' && toFolder === 'Trash') {
		postData['actuallyDelete'] = 1;
	}

	var url = "mail/mail/movetofolder";

	this.postJSON(url, postData, function(json) {
		
		if(json && json['result']=='success' && $mobile.currentMailList && $mobile.currentMailList.length) {
			
			$.each(uniqueId, function(k, v) { 
				
				for(var i in $mobile.currentMailList) {
					
					if($mobile.currentMailList[i]['UID'] == v ) {
						$mobile.currentMailList.splice(i, 1);
						break;
					}
				}
				
			});

			messageCache.deleteCache(uniqueId, fromFolder);
		}
		
		onSuccess && onSuccess(json);
	});
};

$mobile.html2text = function(html, callback) {
	this.postJSON("mobile/index/html2text", {html:html}, callback);
}

$mobile.setMailData = function(data) {

	var uid = data.headers.uniqueid;
	if(!$mail.getMail(uid)) {
		//alert('Failed get mail from cache.')
		$mail.setMail(uid, data);
	}

	$mail.curID = uid;
};

$mobile.getMailData = function() {
	return $mail.curID? $mail.getMail($mail.curID) : null;
};

$mobile.listFolder = function(callback) {
	if(this.folderList) {
		callback && callback(this.folerList);
	}

	this.postJSON("api/mail/listfolder", {}, function(json){
		if(json instanceof Array) {
			this.folerList = json;
			callback && callback(json);
		}
	});
};

$mobile.updateFolderTotals = function(callback) {

	var url = "mail/mail/updatefoldertotals";

	$.ajax({
		type:"POST",
		url:url,
		dataType:"json",
		data:{},
		success:function(json) {

			callback && callback(json);

		}

	});
}

$mobile.deleteFolder = function(folder, callback) {
	if(!folder) return;
	this.postJSON("mail/mail/folderremove/folderNameGlobal/" + urlencode(folder), {}, callback);
};

$mobile.createFolder = function(folder, callback) {
	var postData = {
		folderNameNew  : urlencode(folder),
		makeRootFolder : 1
	};
	this.postJSON("mail/mail/foldercreate", postData, callback);
};

$mobile.updateCache = function(UIDs, folder) {

	//console.log("checking...", UIDs);
	messageCache.getUncachedIDs(UIDs, folder, function(res) {

		if(res.length>0) {
			//console.log("loading...",res);

			$mobile.loadEmails(folder, res, function(json){

				$.each(json, function(k,v){

					messageCache.save(v['UID'], folder, v);

				});

			});
		}

	});
}


/// ****************************************************************
///  Operation on contacts
/// ****************************************************************
$mobile.listContacts = function(groupId, callback) {

	var postData = {
		GroupID : groupId,
		format  : "json"
	};

	var url = "api/contact/list";

	this.postJSON(url, postData, callback);
};

$mobile.loadGroups = function(callback) {
	this.postJSON("api/group/list", {}, callback);
};

$mobile.deleteGroup = function(groupId, callback) {
	if(!(groupId instanceof Array)) {
		groupId = [groupId];
	}

	var postData = {
		"GroupID[]" : groupId
	};

	this.postJSON("api/group/delete", postData, callback);
};

$mobile.createGroup = function(name, callback) {
	this.postJSON("api/group/create", {newGroupName : name}, callback);
};

$mobile.updateContact = function(data, callback) {
	this.postJSON("api/contact/update", data, callback);
}

$mobile.getProfileId = function() {
	return this.settings && this.settings['profile'] ? this.settings.profile : -1;
}

$mobile.disableHeaderTabToggle = function(pageId) {
	$("[data-role=header]", pageId).fixedtoolbar({ tapToggle: false });
}

$mobile.reload = function(noChangePage) {
	if(!this.getAccount()) {
		$mobile.postJSON("mobile/index/checkauth", {}, function(json) {
			if(json && json["auth"] === "success") {
				$mobile.saveSettings( json['settings'] );
				if(!noChangePage) $.mobile.changePage("#mobile_maillist");
			}
		});
	}
}

$mobile.listCalendars = function(callback) {
    $mobile.caldavglue({'func': 'calname'}, callback );
}

$mobile.listCalendar = function(param, callback) {

	if(param == undefined) {
		param = {};
	}
	
	if(! param['start'] ) {
		param['start'] = Math.round( Date.now()/1000 ) - 24 * 3600;
	}

    if(! param['end'] ) {
        param['end'] = param['start'] + 180 * 24 * 3600;
    }
	
	param.func = 'ajaxcal';
				
	$mobile.caldavglue(param, callback);
}

$mobile.caldavglue = function(param, callback) {
    if(!param) {
        console.error('param is null');
    }
    param['ajax'] = 1;
    param['json'] = 1;
    param['appmode'] = 'Private';

    $mobile.postJSON("mail/calendar/caldavglue", param, callback);
}

function jqmSimpleMessage(message) {
	$("<div class='popup-message ui-loader ui-overlay-shadow ui-body-b ui-corner-all'><span>" + message + "</span></div>")
		.css({
			display: "block",
			opacity: 0.96
		})
		.appendTo("body").delay(800)
		.fadeOut(2000, function(){
			$(this).remove();
		});
};

