(function(){

var handivi = window.handivi = {};
handivi.anonymous_user = true;

handivi.messaging = (function(){

	var _proto = {};	

	_proto.friend_updates = function(page,ifModified,cb){
		var url = "/api/messaging/friend_updates";
		if (page != "")
			url += "?p="+page;

		$.ajax({
			type:"GET",
			url:url,
			success:cb,
			cache:ifModified,
			ifModified:ifModified
		});
	};

	_proto.inbox = function(page,cb,read){
		var url = "/api/messaging/inbox";

		if (read)
			url += "?read=true";
		else
			url += "?read=false";

		if (page != "")
			url += "&p="+page;

		$.getJSON(url,cb);
	};

	_proto.archive = function(page,cb,id){
		var url = "/api/messaging/archive";
		if (id) url += "/" + id;
		else url += "/photo";

		if (page != "")
			url += "?p="+page

		$.getJSON(url,cb);
	};

	_proto.public_timeline = function(page,ifModified,cb){
		var url = "/api/messaging/timeline";
		if (page != "")
			url += "?p="+page;
		$.ajax({
			type:"GET",
			url:url,
			success:cb,
			cache:ifModified,
			ifModified:ifModified
		});
	};

	_proto.view_message = function(id,cb) {
		$.getJSON("/api/messaging/message/"+id,cb);
	};

	_proto.view_update = function(id,cb,noPermissionCb) {
		$.ajax({
			type:"GET",
			url:"/api/messaging/update/"+id,
			success: cb,
			error:	function(xhr,status,e){
						if (xhr.status == 403) {
							this.global = false;
							$.getJSON("/api/private/sender_info/"+id,noPermissionCb);
						}
					}
		});
	};

	_proto.send_gift = function(gift,recipient,text,success,failure){
		$.ajax({
			type:'POST',
			url:'/api/messaging/send/gift',
			success:success,
			error:failure,
			data: {
				gift_id:gift,
				recipients:recipient,
				text:text
			}
		});
	};
	return _proto;

})();

handivi.user = (function() {

	var _proto = {};

	_proto.profile = function(cb,id){
		var url = "/api/profile";
		if (id) url += "/" + id;
		$.getJSON(url,cb);
	};

	_proto.full_profile = function(cb){
		$.getJSON("/api/profile",cb);
	};

	_proto.change_password = function(oldpass,newpass,onSuccess,onError){
		$.ajax({
			type:"POST",
			url:"/api/password",
			data: { password:oldpass,
					newpassword:newpass
					},
			error: onError,
			success: onSuccess
		});
	};

	_proto.reset_password = function(phonenr,onSuccess,onError){
		$.ajax({
			type:"POST",
			url:"/api/req_reset_password",
			data: {phonenr:phonenr},
			error:onError,
			success:onSuccess
		});
	};

	_proto.change_phonenr = function(phonenr,onSuccess,onError){
		$.ajax({
			type:"POST",
			url:"/api/req_change_phonenr",
			data: {newphonenr:phonenr},
			error:onError,
			success:onSuccess
		});
	};

	_proto.save_profile = function(name,privacy,gender,birthdate,bio,onSuccess,onError){
		var data = {name:name,
					is_private:privacy,
					gender:gender,
					bio:bio};

		if (birthdate)
			data.birthdate = birthdate.getFullYear()+"-"+(birthdate.getMonth()+1)+"-"+birthdate.getDate();

		$.ajax({
			type:"POST",
			url:"/api/profile",
			data:data,
			error:onError,
			success:onSuccess
		});
	};

	_proto.alpha_signup = function(e,onSuccess,onError) {
		$.ajax({
			type:"POST",
			url:"/api/signup",
			data: { email:e },
			error: onError,
			success: onSuccess
		});
	};

	_proto.register = function(country,n,p,c,onSuccess,onError) {
		$.ajax({
			type:"POST",
			url:"/api/register",
			data: { phonenr_0:country,
					phonenr_1:n,
					password:p,
					invite_code:c },
			error: onError,
			success: onSuccess
		});
	};

	_proto.login = function(n,p,onSuccess,onError){
		$.ajax({
			type:"POST",
			url: "/api/login",
			data: { phonenr:n, password:p },
			error: onError,
			success: onSuccess
		});
	};

	_proto.logout = function(onSuccess){
		$.get("/api/logout",onSuccess);
	};

	_proto.preferences = function(onSuccess){
		$.get("/api/private/settings",onSuccess);
	};

	_proto.set_notifications = function(dd,onSuccess,onError){
		if (dd == null)
			dd = "0";

		$.ajax({
			type:"POST",
			url: "/api/private/settings",
			data: { daily_digest:dd },
			error: onError,
			success: onSuccess
		});
	};

	return _proto;

})();

handivi.friends = (function(){

	var _proto = {};

	_proto.list_friends = function(cb,id){
		var url = "/api/friends/";
		if (id) url += id;
		$.getJSON(url,cb);
	};

	_proto.count_friend_requests = function(cb)
	{
		$.getJSON("/api/friends/pending",function(list){
			cb(list.length);
		});
	}

	_proto.list_pending = function(cb){
		$.getJSON("/api/friends/pending",cb);
	};

	_proto.block = function(cb,id) {
		$.ajax({
			type:"POST",
			url:"/api/friends/delete",
			data:{id:id},
			error:function(xhr,s,e){
				if (xhr.status == 200)
					cb("","success");
				else
					cb(e,"error");
			},
			success:function(s,e){
				cb("","success");
			}
		});
	};

	_proto.follow = function(cb,id){
		$.ajax({
			type:"POST",
			url:"/api/friends/add",
			data:{id:id},
			error:function(xhr,s,e){
				if (xhr.status == 202)
					cb("","success");
				else
					cb(e,"error");
			},
			success:function(s,e){
				cb("","success");
			}
		});
	};

	_proto.invite = function(cb,phonenr){
		$.ajax({
			type:"POST",
			url:"/api/friends/add",
			data:{phonenr:phonenr},
			error:function(xhr,s,e){
				if (xhr.status == 202)
					cb("","success");
				else
					cb(e,"error");
			},
			success:function(s,e){
				cb("","success");
			}
		});
	};

	_proto.dismiss = function(id,onSuccess,onError){
		$.ajax({
			type:"POST",
			url:"/api/friends/decline",
			data: {id:id},
			error: onError,
			success: onSuccess
		});
	};

	_proto.accept = function(id,onSuccess,onError){
		$.ajax({
			type:"POST",
			url:"/api/friends/accept",
			data: {id:id},
			error: onError,
			success: onSuccess
		});
	};

	_proto.refuse = _proto.dismiss;

	return _proto;

})();

handivi.util = (function(){

	var _proto = {};
		
	_proto.list_countries = function(cb){
		$.getJSON("/api/private/listcountries",cb);
	};

	_proto.request_download = function(onSuccess,onError){
		$.ajax({
			type:"POST",
			url:"/api/private/download",
			error:onError,
			success:onSuccess
		});
	};

	_proto.show_result = function(el,text,css) {
		el.fadeOut("slow",function(){
			el.removeClass("error").
				removeClass("success").
				addClass(css).
				html(text).
				fadeIn(1000);
		});
	};


	return _proto;

})();

/*
    JSON parser taken from YUI because it's like a million times
    better than jQuery's simple eval()
*/

handivi.util.JSON = {
    /**
     * First step in the validation.  Regex used to replace all escape
     * sequences (i.e. "\\", etc) with '@' characters (a non-JSON character).
     * @property _ESCAPES
     * @type {RegExp}
     * @static
     * @private
     */
    _ESCAPES : /\\["\\\/bfnrtu]/g,
    /**
     * Second step in the validation.  Regex used to replace all simple
     * values with ']' characters.
     * @property _VALUES
     * @type {RegExp}
     * @static
     * @private
     */
    _VALUES  : /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
    /**
     * Third step in the validation.  Regex used to remove all open square
     * brackets following a colon, comma, or at the beginning of the string.
     * @property _BRACKETS
     * @type {RegExp}
     * @static
     * @private
     */
    _BRACKETS : /(?:^|:|,)(?:\s*\[)+/g,
    /**
     * Final step in the validation.  Regex used to test the string left after
     * all previous replacements for invalid characters.
     * @property _INVALID
     * @type {RegExp}
     * @static
     * @private
     */
    _INVALID  : /^[\],:{}\s]*$/,

    /**
     * Regex used to replace special characters in strings for JSON
     * stringification.
     * @property _SPECIAL_CHARS
     * @type {RegExp}
     * @static
     * @private
     */
    _SPECIAL_CHARS : /["\\\x00-\x1f\x7f-\x9f]/g,

    /**
     * Regex used to reconstitute serialized Dates.
     * @property _PARSE_DATE
     * @type {RegExp}
     * @static
     * @private
     */
    _PARSE_DATE : /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/,

    /**
     * Character substitution map for common escapes and special characters.
     * @property _CHARS
     * @type {Object}
     * @static
     * @private
     */
    _CHARS : {
        '\b': '\\b',
        '\t': '\\t',
        '\n': '\\n',
        '\f': '\\f',
        '\r': '\\r',
        '"' : '\\"',
        '\\': '\\\\'
    },

    stringToDate : function (str) {
        if (this._PARSE_DATE.test(str)) {
            var d = new Date();
            d.setUTCFullYear(RegExp.$1, (RegExp.$2|0)-1, RegExp.$3);
            d.setUTCHours(RegExp.$4, RegExp.$5, RegExp.$6);
            return d;
        }
    },

	jsonDataFilter: function(data,type) {
		if (type != 'json')
			return data;

		var isValid = function (str) {
			if (!(typeof str === "string")) return false;

			return handivi.util.JSON._INVALID.test(str.
                replace(handivi.util.JSON._ESCAPES,'@').
                replace(handivi.util.JSON._VALUES,']').
                replace(handivi.util.JSON._BRACKETS,''));
		};

		if (data == '')
			return '[]';
		if (!isValid(data))
			throw new SyntaxError("invalid JSON");
		return data;
	}

};

handivi.ui = (function(){
	var _proto = {};
	_proto.gift = (function(){

		_gift_proto = {};
		_gift_proto.currentTimer = null;

		_gift_proto.animateGift = function (el,frameCount,fps,loopDelay,currentFrame)
			{
				if (frameCount < 2) return; /* no animation if we don't have at least 2 frames */
				fps = fps || frameCount;
				loopDelay = loopDelay || 0;
				var currentFrame = currentFrame || 0;
				var frameWidth = parseInt($(el).get(0).style.width);

				if (currentFrame == frameCount)
				{
					currentFrame = 0;
					if (loopDelay > 0)
					{
						/* have the last frame show a bit longer */
						$(el).get(0).style.backgroundPosition=(-1*(frameCount-1)*frameWidth) + "px 0px";
						handivi.ui.gift.currentTimer = setTimeout(function(){handivi.ui.gift.animateGift(el,frameCount,fps,loopDelay,currentFrame);},loopDelay);
					}
					else
						$(el).get(0).style.backgroundPosition="0px 0px";

					return;

				}

				$(el).get(0).style.backgroundPosition=(-1*currentFrame*frameWidth) + "px 0px";
				currentFrame++;
				handivi.ui.gift.currentTimer = setTimeout(function(){handivi.ui.gift.animateGift(el,frameCount,fps,loopDelay,currentFrame);},1000/fps)

			};

		_gift_proto.stopAnimation = function(el) {
				if (handivi.ui.gift.currentTimer)
					clearTimeout(handivi.ui.gift.currentTimer);
				handivi.ui.gift.currentTimer = null;
				$(el).get(0).style.backgroundPosition="0px 0px";
			};

		return _gift_proto;

	})();

	return _proto;

})();

$.ajaxSetup({
	dataFilter: handivi.util.JSON.jsonDataFilter,
	dataType: "json",
	cache: false
});

})();
