// Namespace
var FM = {
    auth: {
        status: null,
        returnUrl: ''
    },

    ajaxErrorHandler: function (XHR, textStatus, errorThrown) {
        console.log(XHR, textStatus, errorThrown);
        var data = $.parseJSON(XHR.responseText);
        if (data) errorMessage = data.error;
        else errorMessage = errorThrown;
        alert('Sorry, something went wrong.' + '\n\n' + textStatus + ': ' + errorMessage + '\n\n' + 'Please try again.');
    }
};

// Forms
FM.forms = {
    init: function () {
        // bind input events for overprint placeholders and tips
        $('.form-field input, .form-field select, .form-field textarea').bind({
            'focusout.FM': FM.forms.focusout,
            'focusin.FM': FM.forms.focusin,
            'keypress.FM': FM.forms.focusin,
            'paste.FM': FM.forms.focusin,
            'change.FM': FM.forms.focusin,
            'click.FM': FM.forms.focusin
        }).trigger('focusout.FM');

        // for catching changes caused by e.g. autofill
        window.setInterval(function () {
            $('.form-field').each(function () {
                if ($(this).find('input:focus, select:focus, textarea:focus').length > 0) {
                    // skip if any child inputs have focus
                }
                else {
                    $(this).find('input, select, textarea').trigger('focusout');
                }
            });
        }, 200);

        $('.form-field label.overprint').each(function () {
            var label = this;
            $(label).bind({
                mouseover: function (e) {
                    $(label).stop().hide();
                }
            });
            $('#'+$(label).attr('for')).bind({
                mouseout: function (e) {
                    $(label).stop().fadeTo(300, 1.0);
                }
            });
        });

        // click handler for all buttons - applies loading throbber and prevents double clicks
        $('.button-small, .button-medium, .button-large, .button-xl').not('.no-throb').bind('click.FM', function (e) {
            var button = $(this);

            if (button.hasClass('loading')) {
                e.preventDefault();
                return;
            }

            if (button.find('var').length < 1) {
                button.find('strong').wrapInner('<var/>');
            }
            button.find('var').width(button.find('var').width());
            button.find('var').wrapInner('<del/>');
            button.addClass('loading');
            button.fadeTo(500, 0.5);

            window.setTimeout(function () {
                button.find('del').replaceWith(button.find('del').contents());
                button.removeClass('loading');
                button.fadeTo(250, 1);
            }, 5000)
        });

        // pre-load throbber images else they don't show in some browsers on click as the download gets cancelled
        var throbber = new Image; throbber.src='/images/common/throbber.gif';
        var throbberBlue = new Image; throbber.src='/images/common/throbber-blue.gif';
        var throbberTeal = new Image; throbber.src='/images/common/throbber-teal.gif';
    },
    focusin: function (e) {
        var id = $(this).attr('id');
        var overprint = $(this).parent().find('label#'+id+'_overprint .overprint');
        var tip = $(this).closest('.form-field').find('.field-tip');

        if ($(this).val() === '' && !e.charCode && e.type != 'paste') {
            overprint.stop().fadeTo(100, 0.5);
        }
        else {
            overprint.stop().hide();
        }

        tip.stop().show().fadeTo(0, 1);
    },
    focusout: function (e) {
        var overprint = $(this).parent().find('label#'+$(this).attr('id')+'_overprint .overprint');
        var tip = $(this).closest('.form-field').find('.field-tip');

        if ($(this).val() === '' || $(this).val() === null) {
            overprint.stop().fadeTo(300, 1.0);
        }
        else {
            overprint.stop().hide();
        }
        tip.fadeOut(300);
    },
    showError: function (field, errorMessage) {
        if (!$(field).hasClass('.form-field')) field = $(field).closest('.form-field');

        var errorHtml = '<ul><li>'+errorMessage+'</li></ul>';
        if ($(field).find('div.field-errors').length > 0)
        {
            $(field).find('div.field-errors').html(errorHtml);
        }
        else
        {
            $(document.createElement('div')).addClass('field-errors').hide().html(errorHtml).appendTo($(field).find('.form-field-main')).show('fast');
        }
    },
    hideErrors: function (field) {
        if (!$(field).hasClass('.form-field')) field = $(field).closest('.form-field');

        $(field).find('.field-errors').hide('fast').remove();
    }
};

FM.shortlist = {
    init: function () {
        $('.listings div.controls a.shortlist').live('click', function(e) {
            e.preventDefault();
            if ($(this).hasClass('active')) {
                $(this).removeClass('active').addClass('loading');
                FM.shortlist.removeItem($(this).attr('href'), function (response, data) {
                    $(data.button).removeClass('loading');
                    if (response && response.status == 200) {
                        $(data.button).removeClass('active');
                        $(data.button).attr('href', response.addUrl);
                        $(data.button).attr('title', 'Add to your Shortlist');
                        $(data.button).html('shortlist');
                        // Trigger event handler for other hooks to use
                        $(data.button).closest('.listing').trigger('removedFromShortlist');
                    }
                    else {
                        $(data.button).addClass('active');
                        if (response && response.notice) alert(response.notice);
                    }
                }, { button: this });
            }
            else {
                $(this).addClass('loading');
                FM.shortlist.addItem($(this).attr('href'), function (response, data) {
                    $(data.button).removeClass('loading');
                    if (response && response.status == 200) {
                        $(data.button).addClass('active');
                        $(data.button).attr('href', response.removeUrl);
                        $(data.button).attr('title', 'Remove from your Shortlist');
                        $(data.button).html('shortlisted');
                        // Trigger event handler for other hooks to use
                        $(data.button).closest('.listing').trigger('addedToShortlist');
                    }
                    else {
                        if (response && response.notice) alert(response.notice);
                    }
                }, { button: this });
            }
        });
    },

    addItem: function (url, callback, data) {
        $.ajax({
            url: url + '.json',
            type: 'POST',
            cache: false,
            timeout: 30 * 1000,
            dataType: 'json',
            success: function(response) {
                if (callback) callback(response, data);
            },
            error: function (XHR, textStatus, errorThrown) {
                //FM.ajaxErrorHandler(XHR, textStatus, errorThrown);
                if (callback) callback(null, data);
                location.href = url;
            }
        });
    },

    removeItem: function (url, callback, data) {
        $.ajax({
            url: url + '.json',
            type: 'POST',
            cache: false,
            timeout: 30 * 1000,
            dataType: 'json',
            success: function(response) {
                if (callback) callback(response, data);
            },
            error: function (XHR, textStatus, errorThrown) {
                //FM.ajaxErrorHandler(XHR, textStatus, errorThrown);
                if (callback) callback(null, data);
                location.href = url;
            }
        });
    },

    loadSidebar: function (callback, data) {
        if (!FM.shortlist.sidebarUrl) return false;
        FM.startThrobber($('#sidebar #shortlist'));
        $.ajax({
            url: FM.shortlist.sidebarUrl,
            type: 'GET',
            cache: false,
            timeout: 30 * 1000,
            dataType: 'html',
            success: function(response) {
                FM.stopThrobber($('#sidebar #shortlist'));
                $('#sidebar #shortlist .listings').replaceWith(response);
                if (callback) callback(response, data);
            },
            error: function (XHR, textStatus, errorThrown) {
                FM.stopThrobber($('#sidebar #shortlist'));
                if (callback) callback(null, data);
            }
        });
    }
};

FM.startThrobber = function (container) {
    $(container).addClass('loading');
    if ($(container).find('.throbber').length < 1) $(container).append('<div class="throbber">Loading...</div>');
};
FM.stopThrobber = function (container) {
    $(container).removeClass('loading');
    $(container).find('.throbber').remove();
};

FM.photoBrowser = {
    photosUrl: '',
    cache: [],
    position: [],

    init: function () {
        $('.listings div.controls span.prev').live('click', function(e) {
            e.preventDefault();
            FM.photoBrowser.previous($(this).data('listing'));
        });

        $('.listings div.controls span.next').live('click', function(e) {
            e.preventDefault();
            FM.photoBrowser.next($(this).data('listing'));
        });
    },

    loadPhotos: function (listingId, prevNext)
    {
        if (FM.photoBrowser.cache[listingId] == null) {
            FM.startThrobber($('#listing'+listingId+' .viewer'));
            $('#listingPhoto' + listingId).find('img.listing-photo').fadeTo(500, 0.5);

            $.getJSON(FM.photoBrowser.photosUrl, { listingId: listingId }, function(data) {
                FM.photoBrowser.cache[listingId] = data.photos;

                if (prevNext == 'next') {
                    FM.photoBrowser.next(listingId);
                }
                else {
                    FM.photoBrowser.previous(listingId);
                }

                FM.stopThrobber($('#listing'+listingId+' .viewer'));
                $('#listingPhoto' + listingId).find('img.listing-photo').fadeTo(0, 1);
            });

            return false;
        }

        return true;
    },

    previous: function (listingId) {
        if (!FM.photoBrowser.loadPhotos(listingId, 'prev')) {
            return;
        }

        var position = FM.photoBrowser.getPreviousPhotoIndex(listingId);
        FM.photoBrowser.updatePhoto(listingId, position);
    },

    next: function (listingId) {
        if (!FM.photoBrowser.loadPhotos(listingId, 'next')) {
            return;
        }

        var position = FM.photoBrowser.getNextPhotoIndex(listingId);
        FM.photoBrowser.updatePhoto(listingId, position);
    },

    updatePhoto: function (listingId, position)
    {
        var index = position - 1;
        var photo = FM.photoBrowser.cache[listingId][index];

        var img = $('#listingPhoto' + listingId).find('img.listing-photo');
        img.attr({ src: '/' + photo.src, width: photo.width, height: photo.height });

        $('#listing' + listingId + ' div.controls span.count').html(position + '/' + FM.photoBrowser.cache[listingId].length);

        if (position == 1) {
            $('#listing' + listingId + ' .photo .flatmates').show();
        }
        else {
            $('#listing' + listingId + ' .photo .flatmates').hide();
        }

        FM.photoBrowser.position[listingId] = position;
    },

    getPreviousPhotoIndex: function (listingId)
    {
        var position = FM.photoBrowser.position[listingId] ? FM.photoBrowser.position[listingId] : 1;
        position--;

        if (position < 1) {
            position = FM.photoBrowser.cache[listingId].length;
        }

        return position;
    },

    getNextPhotoIndex: function (listingId)
    {
        var position = FM.photoBrowser.position[listingId] ? FM.photoBrowser.position[listingId] : 1;
        position++;

        if (position > FM.photoBrowser.cache[listingId].length) {
            position = 1;
        }

        return position;
    }
};

FM.facebook = {
    loginUrl: null,
    loginStatus: null,
    accessToken: null,
    authScope: 'email',

    init: function () {

    },

    setLoginStatus: function (loginStatus) {
        FM.facebook.loginStatus = loginStatus;
        if (loginStatus.authResponse && loginStatus.authResponse.accessToken) {
            if (loginStatus.authResponse.accessToken != FM.facebook.accessToken) {
                $.ajax({
                    url: FM.facebook.pingUrl,
                    data: { code: loginStatus.authResponse.accessToken },
                    type: 'POST',
                    cache: false,
                    timeout: 30 * 1000,
                    dataType: 'json',
                    success: function(data) {
                        console.log(data);
                    },
                    error: function (XHR, textStatus, errorThrown) {
                        console.log(XHR, textStatus, errorThrown);
                    }
                });
            }
            FM.facebook.accessToken = loginStatus.authResponse.accessToken;
        }
    },

    initHandler: function () {
        console.log('facebookInit triggered');
        FB.Event.subscribe('auth.login', function (response) {
            console.log('Caught auth.login', response);
            FM.facebook.setLoginStatus(response);
        });
        FB.Event.subscribe('auth.statusChange', function (response) {
            console.log('Caught auth.statusChange', response);
            FM.facebook.setLoginStatus(response);
        });
        FB.getLoginStatus(function(response) {
            console.log('Login status', response);
            FM.facebook.setLoginStatus(response);
        });
        $(document).bind('facebookAfterLogin.default', FM.facebook.defaultAfterLoginHandler);
    },

    loginHandler: function () {
        console.log('facebookLogin triggered', FM.facebook.loginStatus);

        if (!FM.facebook.loginStatus || !FM.facebook.loginStatus.authResponse || !FM.facebook.loginStatus.authResponse.accessToken ) {
            console.log('No access token provided, auth failed?');
            return;
        }

        $.ajax({
            url: FM.facebook.loginUrl,
            data: { code: FM.facebook.loginStatus.authResponse.accessToken, returnUrl: FM.auth.returnUrl },
            type: 'POST',
            cache: false,
            timeout: 30 * 1000,
            dataType: 'json',
            success: function(data) {
                console.log(data);
                if (data.status == 200) { // OK
                    $(document).trigger('facebookAfterLogin', data);
                }
                else {
                    if (data.redirectUrl) location.href = data.redirectUrl;
                    else if (data.error) alert(data.error);
                }
            },
            error: FM.ajaxErrorHandler
        });
    },

    defaultAfterLoginHandler: function (e, data) {
        console.log('facebookAfterLogin triggered');
        if (data && data.redirectUrl) location.href = data.redirectUrl;
        else location.reload();
    },

    loginButtonHandler: function (e) {
        console.log('loginButtonHandler triggered');
        if (e) e.preventDefault();
        FB.login(function () {
            $(document).trigger('facebookLogin');
        }, { scope: FM.facebook.authScope });
    }
};
$(document).bind('facebookInit', FM.facebook.initHandler);
$(document).bind('facebookLogin', FM.facebook.loginHandler);

// Init
$(document).ready(FM.forms.init);
$(document).ready(FM.shortlist.init);
$(document).ready(FM.facebook.init);

// Misc
if (typeof(console) == 'undefined') console = {};
if (typeof(console.log) == 'undefined') console.log = function () {};

