/*
 * copy('日本語'.quote());
 */

if (typeof Folkat == 'undefined') {
    Folkat = {}
};

(function () {
    var F = Folkat; // shortcut

    F.debug = function (msg) {
	if (typeof window.console == 'object') {
	    window.console.log(msg);
	}
    };

    F.isSmartPhone = navigator.userAgent.indexOf('Android ') != -1 || navigator.userAgent.indexOf('iPod;') != -1 || navigator.userAgent.indexOf('iPhone;') != -1 || navigator.userAgent.indexOf('iPad;') != -1;

    // sprintf
    // XXX bug wrong parse "%d %02d"
    var sprintf = function (str) {
	var args = Array.prototype.slice.call(arguments, 1);
	return str.replace(/%0(\d+)d/g, function(m, num) {
            var r = String(args.shift());
            var c = '';
            num = parseInt(num) - r.length;
            while (--num >= 0) c += '0';
            return c + r;
	}).replace(/%[sdf]/g, function(m) { return sprintf._SPRINTF_HASH[m](args.shift()) });
    };
    sprintf._SPRINTF_HASH = {
	'%s': String,
	'%d': parseInt,
	'%f': parseFloat
    };

    // Storageh
    if (window.localStorage) {
	F.Storage = window.localStorage;
    } else {
	// XXX for gears
//	alert("nostore");
	var S = {};
	F.Storage = {
	    setItem: function(key, value) {
		return S[key] = value;
	    },
	    getItem: function(key) {
		return S[key];
	    },
	    removeItem: function(key) {
		return S[key] = null;
	    }
	};
    }

    // Date
    Date.from_epoch = function(epoch) {
	return new Date(epoch * 1000);
    };
    Date.prototype.ago = function () {
	var now = new Date * 1;
	var mins = (now - this) / 60000;
	if (mins < 1) {
	    return "\u305F\u3063\u305F\u4ECA";
	}
	else if (mins < 60) {
	    return Math.floor(mins) + "\u5206\u524D";
	}
	else if (mins < 60 * 12) {
	    var h = Math.round((mins - 30) / 60);
	    return "\u7D04" + h + "\u6642\u9593\u524D";
	}
	return sprintf("%d.%d.%d", this.getFullYear(), this.getMonth() + 1, this.getDate()) + sprintf(
	    " %02d:%02d", this.getHours(), this.getMinutes());
    };
    Date.prototype.eqDate = function (x) {
	return this.getFullYear() == x.getFullYear()
	    && this.getMonth() == x.getMonth() && this.getDate() == x.getDate();
    };

    // geolocation
    if (! navigator.geolocation) { // loading geolocation API from google Gears
	if (google && google.gears) {
	    navigator.geolocation = google.gears.factory.create("beta.geolocation");
	}
    }
    F.Location = {
	_lat: F.Storage.getItem('curLat') || 35.690311,
	_lng: F.Storage.getItem('curLng') || 139.703549,
	hooks: [],
	lat: function(lat) {
	    if (lat) _lat = lat;
	    return _lat;
	},
	lng: function(lng) {
	    if (lng) _lng = lng;
	    return _lng;
	},
	currentPosition: function (cb, fcb) {
    	    if (navigator.geolocation) {
		navigator.geolocation.getCurrentPosition(
    	            function(curPos) {
                        F.debug(curPos.coords.accuracy);
			var lat = curPos.coords.latitude;
			var lng = curPos.coords.longitude;
                        var accuracy = curPos.coords.accuracy;
			F.debug("curPos:" +  lat + ',' + lng + " : " + accuracy);
			F.Location.lat(lat);
			F.Location.lng(lng);
                        if (cb) {
			    cb(lat, lng, accuracy);
                        }
	            },
	            function(error) {
			if (fcb) {
			    fcb(error);
			} else {
			    alert("\u4F4D\u7F6E\u60C5\u5831\u304C\u53D6\u308C\u307E\u305B\u3093\u3067\u3057\u305F:" + error);
			}
 	            },
	            {
			enableHighAccuracy: true,
			maximumAge: 3 * 60 * 1000
		    }
    		);
	    } else {
		alert("\u3053\u306E\u30D6\u30E9\u30A6\u30B6\u3067\u306F\u4F4D\u7F6E\u60C5\u5831\u304C\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093");
		if (fcb) fcb();
	    }
	},
	currentGLatLng: function () {
	    new google.maps.LatLng(F.Location.lat, F.Location.lng);
	},
	update: function (cb) { // XXXX obsolute
	    F.Location.currentPosition(cb);
	},
	onUpdated: function (callback) { // XXXX obsolute
	    F.Location.hooks.push(callback);
	},
	callHook: function() { // XXXX obsolute
	    $.each(F.Location.hooks, function(i, cb) {
		cb(F.Location.lat, F.Location.lng);
	    });
	}
    };

    F.picture_image_thumb_size = function (picture) {
        var picWidth,
            picHeight,
            max = 110;
        if (picture.width <= max && picture.height <= max) {
            picWidth = picture.width;
            picHeight = picture.height;
        } else {
            if (picture.width < picture.height) {
                picHeight = max;
                picWidth = Math.floor(picture.width * max / picture.height);
            } else {
                picWidth = max;
                picHeight = Math.floor(picture.height * max / picture.width);
            }
        }
        return [picWidth, picHeight];
    };

    F.getHashQuery = function () {
        var query = new Array();
        if (location.hash.length > 1) {
                var src = location.hash.replace(/^#(!\/)?/, '').split('&');
                for (var i=0, l=src.length; i<l; i++) {
                    var parts = src[i].split('=');
                    var key = parts[0];
                    var value = decodeURIComponent(parts[1]);
                    query[key] = value;
                }
        }
        return query;
    };
    F.renderHashQuery = function (ary) {
        var ret = new Array();
        for (var k in ary) {
            v = ary[k];
            if (typeof v == 'object') {
                for (i=0, l=v.length; i<l; i++) {
                    ret.push(k + '=' + encodeURIComponent(v[i]));
                }
            } else {
                ret.push(k + '=' + encodeURIComponent(v));
            }
        }
        return ret.join('&');
    };
    F.setHashQuery = function (ary) {
        location.hash = '!/' + Folkat.renderHashQuery(ary);
    };

    // Map
    F.Map = function (elm, options) {
	this.initialize(elm, options);
    };

    F.Map.prototype = {
	initialize: function(elm, options){
	    var mapdiv;
	    if (! elm) {
		return this;
	    }

	    this.markers = [];
	    if (! options) {
		options = {};
	    }

	    if (typeof elm == "string") {
		mapdiv = document.getElementById(elm);
	    } else {
		mapdiv = elm;
	    }

	    this.map_ = new google.maps.Map(mapdiv,
					    {
						zoom: (options.zoom || 16),
						mapTypeId: google.maps.MapTypeId.ROADMAP,
						navigationControl: true,
						mapTypeControl: false,
						streetViewControl: false,
						disableDefaultUI: true,
						scaleControl: false // 地図下部の目盛り
					    }
					   );
	    if (options.simple && options.style != 'none') {
		var style = [
		    { featureType: "all", elementType: "labels", stylers: [ { visibility: "off" }] },
		    { featureType:"administrative", elementType:"all", stylers:[ {visibility:"off"}] },
		    { featureType:"transit", elementType:"all", stylers:[ {visibility:"simplified"}]},
		    { featureType:"transit.station", elementType:"all", stylers:[{ visibility:"on"}]},
		    { featureType:"road", elementType:"all", stylers:[ { visibility:"simplified"}]},
		    { featureType:"poi", elementType:"all", stylers:[{visibility:"off"}]},
		    { featureType:"poi.park",elementType:"all", stylers:[{ visibility:"on" }]},
		    { featureType:"landscape", elementType:"all", stylers:[{visibility:"on"}] }
		];

		var color_style = {
		    'evening': [
 			{ featureType:"poi.park", elementType:"all", stylers: [
			    { visibility:"on" }, { saturation: -10 }, { lightness: -20 }, { gamma: 0 }
			] },
			{ featureType: "landscape", elementType: "all", stylers: [
			    { saturation: 80 }, { lightness: -25 }, { gamma: 0 }, { visibility: "on" }, { hue: "#ff6600" }
			] },
			{ featureType: "road", elementType: "all", stylers: [
			    { saturation: -30 }, { visibility: "simplified" }, { lightness: -25 }, { gamma: 0 }
			] },
			{ featureType: "water", elementType: "all", stylers: [
			    { visibility: "on" }, { saturation: 95 }, { lightness: -45 },{ hue: "#ff6600" }
			] },
			{ featureType: "transit.station.airport", elementType: "all", stylers: [
			    { saturation: -10 }, { lightness: -20 }
			] }
		    ],
		    "night": [
			{ featureType:"poi.park", elementType:"all", stylers: [
			    { visibility:"on" }, { saturation: -10 }, { lightness: -40 }, { gamma: 0 }
			] },
			{ featureType: "landscape", elementType: "all", stylers: [
			    { saturation: -90 }, { lightness: -50 }, { gamma: 0 }, { visibility: "on" }
			] },
			{ featureType: "road", elementType: "all", stylers: [
			    { saturation: -100 }, { visibility: "simplified" }, { lightness: -30 }, { gamma: 0 }
			] },
			{ featureType: "water", elementType: "all", stylers: [
			    { visibility: "on" }, { saturation: -10 }, { lightness: -70 },{ hue: "#00a2ff" }
			] },
			{ featureType: "transit.station.airport", elementType: "all", stylers: [
			    { saturation: -10 }, { lightness: -40 }
			] }
		    ]
		};

		if (options.style && color_style[options.style]) {
		    style = style.concat(color_style[options.style]);
		} else if (options.style == 'daytime') {
		} else {
		    var now = new Date();
		    if (now.getHours() == 16) {
//			style = style.concat(color_style['evening']);
		    } else if (now.getHours() >= 17 || now.getHours() < 5) {
//			style = style.concat(color_style['night']);
		    }
		}

		var folkat_style = new google.maps.StyledMapType(style, { map: this.map_, name: "folkat" });
		this.map_.mapTypes.set('folkat', folkat_style);
		this.map_.setMapTypeId('folkat');
	    }
	    var position;
	    if (options.lat && options.lng) {
		this.map_.setCenter(new google.maps.LatLng(options.lat, options.lng));
	    } else {
		this.map_.setCenter(F.Location.currentGLatLng());
	    }
	    return this;
	},
	setCenter: function (lat, lng) {
	    var pos = new google.maps.LatLng(lat, lng);
	    this.map_.setCenter(pos);
	},
	setZoom: function (z) {
	    this.map_.setZoom(z);
	},
	getCenter: function () {
	    return this.map_.getCenter();
	},
	getBounds: function () {
	    return this.map_.getBounds();
	},
	addIcon: function(marker_data, onclick) {
	    var pos = new google.maps.LatLng(marker_data['lat'], marker_data['lng']);

	    var marker_attrs = {
		clickable: true,
		position: pos,
		map: this.map_,
		draggable: false
	    };
	    marker_attrs.title = marker_data.title || marker_data.name;
	    if (marker_data.icon) {
		marker_attrs.icon = new google.maps.MarkerImage(marker_data.icon);
	    }

	    var marker = new google.maps.Marker(marker_attrs);
	    this.markers.push(marker);
	    if (onclick) {
		google.maps.event.addListener(marker, 'click', onclick);
	    }
	    return marker;
	},
	removeIcons: function() {
	    $.each(this.markers, function (i, m) {
		m.setMap(null);
	    });
	    this.markers = [];
	},
	bind: function(type, fn) {
	    google.maps.event.addListener(this.map_, type, fn);
	},
	one: function(type, fn) {
	    google.maps.event.addListenerOnce(this.map_, type, fn);
	}
    };

    $(function () {
	$(window).bind('orientationchange', function() {
	    if (window.orientation && Math.abs(window.orientation) === 90) {
		$('body').removeClass('vertical').addClass('horizontal');
	    } else {
		$('body').removeClass('horizontal').addClass('vertical');
	    }
	});

	$(window).trigger('orientationchange');
    });

    F.LikesTmpl = {};
    F.LikesTmpl.like_message_link = function(member) {
        var result;

        var displayName = String(member.memberDisplayName).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); //");
        result = '<a href="' + member.memberLink + '">' +
                 '<img src="' + member.memberIcon + '" alt="' + displayName + '" title="' + displayName + '" class="icon member-icon tip" style="width: 20px; height: 20px;">' +
                 '</a>';
        return result;
    };

    F.LikesTmpl.like_message = function(likes) {
        if (!likes.length) return ''
        var len_threshold = 3;
        var len = likes.length;
        var loop_max = len > len_threshold ? len_threshold : len;

        var message = '';
        for (var count = 0; count < loop_max; count++) {
            message += F.LikesTmpl.like_message_link(likes[len - 1 - count]);
        }
        if (len > len_threshold) {
            message += 'たち';
            message += len;
            message += '人';
        }
        message += 'が「いいね」したよ！';
        return message;
    };

    // スマホでアドレスバーを隠す用の機能
    Folkat.scrollToTop = true;
    Folkat.PageOffset = 0;

    $(document).ready(function() {
        if (Folkat.scrollToTop) {
            window.setTimeout(function() { 
		if (window.pageYOffset === 0) {
		    window.scrollTo(0, Folkat.PageOffset);
		};
	    }, 1);
        }

	// follow
	$('.follow-control').each(function (i, c) {
	    var follow_form = $(this).children("form.follow-form");
	    var unfollow_form = $(this).children("form.unfollow-form");
	    var cntl = $(this);
	    var loading = $("<span></span>");

	    follow_form.children('.follow-button').click(function() {
		$.ajax({
	     	    type: 'POST',
	     	    url: "/api/member/follow",
	     	    data: follow_form.serialize(),
	     	    success: function(data) {
			loading.remove();
			unfollow_form.show();
	     	    },
                    error: function (data) {
                        F.debug(data);
                        if (data.status==403) {
                            var x = $.parseJSON(data.responseText);
                            if (x.error == 'FollowLimitError') {
                                alert("これ以上はフォローできないよ。");
                                return false;
                            }
                        }
                        alert("あれれ？何かがおかしいみたい。\n少し時間をおいてから、もう一度ためしみてくれるかな？");
                        return false;
                    },
		    dataType: 'json'
		});
		follow_form.hide();
		cntl.append(loading);
		return false;
	    });

	    unfollow_form.children('.unfollow-button').click(function() {
		//	    alert(unfollow_form.serialize());
		var loading = $("<span>loading</span>");
		$.ajax({
	     	    type: 'POST',
	     	    url: "/api/member/unfollow",
	     	    data: unfollow_form.serialize(),
	     	    success: function(data) {
			loading.remove();
			follow_form.show();
	     	    },
		    dataType: 'json'
		});
		unfollow_form.hide();
		cntl.append(loading);
		return false;
	    });

	});

	// barrier
	$('form.barrier-form').submit(function(event) {
            event.preventDefault();
            event.stopPropagation();
	    var form = $(this);
	    form.hide();
	    var loading = $("<span>loading</span>");
	    form.after(loading);
	    var id = form.children('input[name=link_from] :first').val();
	    $.ajax({
		type: 'POST',
		url: form.attr('action'),
		data: form.serialize(),
		success: function (data) {
		    loading.remove();
		    $('#unbarrier-' + id).show();
		},
		dataType: 'json'
	    });
	});


	$('form.unbarrier-form').submit(function(event) {
            event.preventDefault();
            event.stopPropagation();
	    var form = $(this);
	    form.hide();
	    var loading = $("<span>loading</span>");
	    form.after(loading);
	    $.ajax({
		type: 'POST',
		url: form.attr('action'),
		data: form.serialize(),
		success: function (data) {
		    loading.remove();
		    form.after($("<span>バリアー解除しました</span>"));
		},
		dataType: 'json'
	    });
	});

    // notification
    $('#globalHeader #notifyCnt').click(function (e) {
        var self = $(this);
            e.preventDefault();
            e.stopPropagation();
            var container = $('#notifyContainer');

            var body = $('body');
            if (!body.data('notifyHook')) {
                body.click(function (e) {
                    if ($(e.target).closest('#notifyContainer').size()==0 && container.css('display') == 'block') {
                        container.hide();
                        return false;
                    }
                    return true;
                }).data('notifyHook', true);
            }

            if (container.css('display') == 'none') {
                $.ajax({
                    type:'GET',
                    url: '/home/notification/parts',
                    cache: false,
                    success: function (data) {
//                        var left = ($('#globalHeader').width() - ($('#globalHeader').width() - $('#globalHeader .inner').width())/2) - 1000;
                        var right = 0;
                        var parts = $(data);
                        container.css('right', parseInt(right, 10) + 'px');
                        container.html(parts);
                        container.show();

                    }
                });
            } else {
                container.hide();
            }
    });

	// like
	var like = function(btn) {
            if (!Folkat.memberId && location.pathname.match(/\/spot\/\d+\//)) {
                location.href = '/auth/?.back=/spot/' + Folkat.spot_id + '/';
                return;
            }
            var url;
            var params;
	    var type = btn.data('type');
            switch (type) {
            case "touch":
		url = '/api/touch/like'
		params = { touch_id: btn.data('id') };
                break;
            case "note":
		url = '/api/note/like'
		params = { note_id: btn.data('id') };
                break;
            case "hightouch":
		url = '/api/hightouch/like'
		params = { hightouch_id: btn.data('id') };
                break;
            case "guide":
                url = '/api/guide/like'
                params = { guide_id: btn.data('id') };
                break;
            case "deals":
                url = '/api/deals_spot_status/like'
                params = { deals_spot_status_id: btn.data('id') };
                break;
            case "news":
                url = '/api/newspaper/like'
                params = { news_id: btn.data('id') };
                break;
	    default:
		return;
            }
	    if (Folkat.post_token) params.token = Folkat.post_token;

	    Folkat.debug(url);
	    Folkat.debug(type);
	    Folkat.debug(params);

	    $.ajax({
		type: 'POST',
		url: url,
		data: params,
		success: function (data) {
		    btn.removeClass('loading').addClass('liking');
                    var msgs = $('.likeMessage[data-id=' + btn.data('id') + ']');
		    if (msgs.length > 0) {
		        msgs.html(F.LikesTmpl.like_message(data[type].likes));
                    }
                    else {
		        $('.likeCount[data-id=' + btn.data('id') + ']').text(data[type].likes.length);
                    }
                },
		error: function (xhr, message, exeption) {
		    btn.removeClass('loading');
		},
		dataType: 'json'
	    });
	    btn.addClass('loading');
	};
	var unlike = function(btn) {
            var url;
            var params;
	    var type = btn.data('type');
            switch (type) {
            case "touch":
		url = '/api/touch/unlike'
		params = { touch_id: btn.data('id') };
                break;
            case "note":
		url = '/api/note/unlike'
		params = { note_id: btn.data('id') };
                break;
            case "hightouch":
		url = '/api/hightouch/unlike'
		params = { hightouch_id: btn.data('id') };
                break;
            case "deals":
                url = '/api/deals_spot_status/unlike'
                params = { deals_spot_status_id: btn.data('id') };
                break;
            case "guide":
                url = '/api/guide/unlike'
                params = { guide_id: btn.data('id') };
                break;
            case "news":
                url = '/api/newspaper/unlike'
                params = { news_id: btn.data('id') };
                break;
	    default:
		return;
            }
	    if (Folkat.post_token) params.token = Folkat.post_token;
	    $.ajax({
		type: 'POST',
		url: url,
		data: params,
		success: function (data) {
		    btn.removeClass('loading').removeClass('liking');
                    var msgs = $('.likeMessage[data-id=' + btn.data('id') + ']');
		    if (msgs.length > 0) {
		        msgs.html(F.LikesTmpl.like_message(data[type].likes));
                    }
                    else {
		        $('.likeCount[data-id=' + btn.data('id') + ']').text(data[type].likes.length);
                    }
                },
		error: function (xhr, message, exeption) {
		    btn.removeClass('loading');
		},
		dataType: 'json'
	    });
	    btn.addClass('loading');
	};

	// present
	$('.present-control').each(function (i, c) {
	    var present_form = $(this).children("form.present-form");
            var present_control = $('#present-control');
            var present_done = $('#present-done');
            var before_preset = $('#beforePresent');
            var after_preset = $('#afterPresent');
	    var cntl = $(this);

	    present_form.children('.present-button').click(function() {
		$.ajax({
	     	    type: 'POST',
	     	    url: "/api/coupon2/send",
	     	    data: present_form.serialize(),
	     	    success: function(data) {
			present_done.show();
                        before_preset.hide();
                        after_preset.show();
	     	    },
		    dataType: 'json'
		});
		present_control.hide();
		return false;
	    });
	});

	Folkat.handle_like_bottom = function (b) {
 	    b.find('.likeBtn[data-type]').live('click', function(e) {
                e.stopPropagation();
                e.preventDefault();

		var btn = $(this);
		btn.hasClass('loading');
		if (btn.hasClass('liking')) {
		Folkat.debug("unlike!");

		    unlike(btn);
		} else {
		Folkat.debug("like");
		    like(btn);
		}
                return false;
	    });
	    b.find('.likeBtn[data-type][data-liking=1]').addClass('liking');
	}
	Folkat.handle_like_bottom($('body'));
    });

// MyMap
    F.MyMap = function (div, options) {
	var self = this;
//        var map = this.map = new Folkat.Map(div, options);
	F.Map.prototype.initialize.call(this, div, options);

	this.one('bounds_changed', function(){
            if (self.onBoundsChangedHandler) {
                self.onBoundsChangedHandler();
            }
            self.load();
	});
        this.onSpotClickHandler = null;
    };
    F.MyMap.prototype = new F.Map();
    F.MyMap.prototype.load = function (selfMap) {
	var self = this;
	var bounds = this.map_.getBounds();
	var params = {};
	params.bounds = bounds.toUrlValue();
        if (arguments.length==0) {
                if (F.getHashQuery()['target'] == 'self') {
                        selfMap = true;
                }
        }
        (function () {
            var match = location.search.match('parent_category_id=([0-9]+)') || location.hash.match('parent_category_id=([0-9]+)');
            if (match) {
                params.parent_category_id = match[1];
                return match[1];
            } else {
                return null;
            }
        })();
        (function () {
            var match = location.hash.match('[^_]category_id=([0-9]+)');
            if (match) {
                params.category_id = match[1];
                return match[1];
            } else {
                return null;
            }
        })();
	if (selfMap) {
	    params.self_map = 1;
	}
	$('#loading_text').text("\u30B9\u30DD\u30C3\u30C8\u60C5\u5831\u3092\u53D6\u5F97\u4E2D");
	$('#map_loading').show();
        if (Folkat.memberId && F.getHashQuery()['target'] != 'all') {
            $.getJSON('/api/mymap', params, function (data) {
                $('#map_loading').hide();
                self.removeIcons();
                if (self.onLoadSpotsHandler) {
                    self.onLoadSpotsHandler(data.spots);
                }
                $.each(data.spots, function(i, spot) {
                    var onclick = function (ev) {
                        if (self.onSpotClickHandler) {
                            self.onSpotClickHandler(ev, spot);
                        };
                    };
                    self.addIcon(spot, onclick);
                });
            });
        } else {
            delete params.bounds;
            params.lat = bounds.getCenter().lat();
            params.lng = bounds.getCenter().lng();
            $.getJSON('/api/spot/search', params, function (data) {
                $('#map_loading').hide();
                self.removeIcons();
                if (self.onLoadSpotsHandler) {
                    self.onLoadSpotsHandler(data.spots);
                }
                $.each(data.spots, function(i, spot) {
                    var onclick = function (ev) {
                        if (self.onSpotClickHandler) {
                            self.onSpotClickHandler(ev, spot);
                        };
                    };
                    self.addIcon(spot, onclick);
                });
            });
        }
    };
    F.MyMap.prototype.onSpotClick = function (fn) {
	this.onSpotClickHandler = fn;
    };
    F.MyMap.prototype.onLoadSpots = function (fn) {
        this.onLoadSpotsHandler = fn;
    };
    F.MyMap.prototype.onBoundsChanged = function (fn) {
        this.onBoundsChangedHandler = fn;
    };

// StickerNote
    F.StickerNote = {};
    F.StickerNote.load = function() {
	var owner = Folkat.page_owner;
        $.getJSON('/api/member/sticker_notes', { member_id: owner.id }, function(data) {
            if (!data.stickerNotes || !data.stickerNotes.length) {
                $('#sticker-note-list').append(Folkat.Template.get('sticker-nonedata-template').compile()());
                return;
            }
            var ul = $('#sticker-note-list');
            var tt = Folkat.Template.get('sticker-item-template').compile();
            var s_hash = {};
            var stickers = [];

            $.each(data.stickerNotes.reverse(), function(i, sn) {
                if (sn.sticker){
                    if (s_hash[sn.sticker.link]) {
                        s_hash[sn.sticker.link].count++;
                    } else {
                        s_hash[sn.sticker.link] = sn;
                        stickers.push(sn);
                        sn.count = 1;
                    }
                }
            });

            $.each(stickers.reverse(), function(i, st) {
                st.countLabel = st.count == 1 ? '' : 'x' + st.count;
                ul.append(tt(st));
            });
        });
    };

    // execute this function after setup facebook JS SDK
    var fb_ready = function () {
        $('.fb-invite').each(function () {
            var self = $(this);
            var link = self.find('.fb-invite-link');
            link.click(function (event) {
                event.preventDefault();
                event.stopPropagation();
                FB.ui({
                    method: 'send',
                    picture: self.data('picture'),
                    name: self.data('name'),
                    description: self.data('description'),
                    link: self.data('link'),
                    to: self.data('fbid')
                });
            });
        });

        $('.fb-invite-more').click(function (event) {
            var self = $(this);
            event.preventDefault();
            event.stopPropagation();

            FB.ui({
                method: self.data('method') || 'send',
                picture: self.data('picture'),
                name: self.data('name'),
                description: self.data('description'),
                link: self.data('link')
            });
        });
    };


    $(function () {
        if ('FB' in window) { // already initialized.
            fb_ready();
            return;
        }

        var root = $('#fb-root');
        if (!root) {
            return; // this page does not require fb API
        }

        var facebook_id = root.data('facebook_id');
        if (!facebook_id) {
            return; // there is no fb id
        }

        window.fbAsyncInit = function() {
            FB.init({
                appId  : facebook_id,
                status : true, // check login status
                cookie : true, // enable cookies to allow the server to access the session
                xfbml  : true, // parse XFBML
                oauth  : true // enable OAuth 2.0
            });
            fb_ready(); // call back function.
        };
        (function(d){
        var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
        js = d.createElement('script'); js.id = id; js.async = true;
        js.src = "//connect.facebook.net/en_US/all.js";
        d.getElementsByTagName('head')[0].appendChild(js);
        }(document));
    });
})();


// page top scroll
$(function(){
  $("#goToTop a,.goToTop a").click(function(){
    $('html, body').animate({scrollTop: 0}, 'fast');
    return false;
  });
});


