(function( $ ) {
/*
 * The recipe manager is initialized on a page change.  It must be passed the new page params.
 */
$.widget( "ui.recipeManager", {  

    options: {
        // The url of the content html fragment
        url: null,

        // The url parameters of the address
        params: null,

        // Selectors
        songArray: '#songs',
        recipePager: '#recipe-pager',
        recipeFilter: '#recipe-filter',
        player: '#player',                    
        nowPlaying: '#now-playing',
        songTemplate: '#song-template'
    },

    _init: function() {
        var self = this,
            loadPage,
            onLoad;

        if( !this.options.params ) {
            throw "The recipe manager must be initialized with a set of parameters.";
        }

        if( !this.options.url ) {
            throw "The recipe manager must be initialized with a url.";
        }

        loadPage = function () {
            self.element.empty().load( self.options.url, onLoad );
        };

        onLoad = function (responseText, textStatus, xhr) {
            switch (xhr.status) {
                case 401:
                    $( '#page' ).loginManager( 'login' ).then( loadPage );
                    break;

                default:
                    $( self.options.recipePager ).pager({
                        $songArray: $( self.options.songArray )
                    });

                    self.element.delegate( '#songs .haudio', 'click', function( event ) {
                        var item = $.tmplItem( this ).data;

                        $( self.options.player ).player( 'playRecipeItem', item );
                    });

                    $( self.options.recipeFilter ).recipeFilter();

                    $( self.options.songArray ).songArray({
                        template: $( self.options.songTemplate ),
                        defaultUrl: '/recipesJson',
                        deepLinkPath: '/',
                        managerName: 'recipeManager'
                    });

                    self.currentContext = self._buildContext( self.options.params );
                    self.element.trigger( 'update.recipeManager', [ self.currentContext ] );
            }
        };

        loadPage();



        function contextsAreEqual( ctx1, ctx2 ) {
            var isEqual = true;

            if( ctx1 === ctx2 ) {
                return true;
            }

            if( !$.isPlainObject( ctx1 ) || !$.isPlainObject( ctx2 ) ) {
                return false;
            }


            $.each( ctx1, function( key, value ) {
                if( ctx2[ key ] !== value ) {
                    isEqual = false;
                    return false; // just returns from $.each
                }
            });

            if( !isEqual ) {
                return false;
            }

            $.each( ctx2, function( key, value ) {
                if( ctx1[ key ] !== value ) {
                    isEqual = false;
                    return false; // just returns from $.each
                }
            });

            return isEqual;
        } 

        this.element.bind( 'pageUpdate', function( e, params ) {
            var context = self._buildContext( params );

            if( !contextsAreEqual( self.currentContext, context ) ) {
                self.currentContext = context;
                self.element.trigger( 'update.recipeManager', [ self.currentContext ] );
            }

        });
    },

    destroy: function() {
        $.Widget.prototype.destroy.apply(this, arguments);

        this.element.unbind( 'pageUpdate' )
                .unbind( 'update.recipeManager' )
                .undelegate( 'click' )
                .empty();
    },

    changeLocation: function( params ) {
        $.location()
            .current()
            .params(this._buildContext(params))
            .update();
    },

    genreChanged: function( genreId ) {
        var newContext = {};

        if( genreId ) {
            newContext[ 'genre.id' ] = genreId;
        }

        if( this.currentContext.ordering ) {
            newContext[ 'ordering' ] = this.currentContext.ordering;
        }

        $.location().current().params(newContext).update();
    },

    orderingChanged: function( ordering ) {
        var newContext = {};
        if( ordering && ordering !== 'NEWEST' ) {
            newContext[ 'ordering' ] = ordering
        }

        if( this.currentContext[ 'genre.id' ] ) {
            newContext[ 'genre.id' ] = this.currentContext[ 'genre.id' ];
        }

        $.location().current().params(newContext).update();
    },

    pageChanged: function( name, value ) {
        var newContext = {};
        if( this.currentContext[ 'genre.id' ] ) {
            newContext[ 'genre.id' ] = this.currentContext[ 'genre.id' ];
        }

        if( this.currentContext[ 'ordering' ] ) {
            newContext[ 'ordering' ] = this.currentContext[ 'ordering' ];
        }

        newContext[ name ] = value;

        $.location().current().params(newContext).update();
    },

    updateLocation: function( params ) {
        var newParams = $.extend( {}, this.params );

        if( params.ordering === 'NEWEST' || params.ordering === 'null' ) {
            delete newParams.ordering;
        }
        else {
            newParams.ordering = params.ordering;
        }

        if( !params[ 'genre.id' ] || params[ 'genre.id' ] === 'null' ) {
            delete newParams[ 'genre.id' ];
        }
        else {
            newParams[ 'genre.id' ] = params[ 'genre.id' ];
        }


        this.newLocation( newParams, null );
    },

    _loadPage: function( pageUrl, onLoad ) {
        var self = this;

        this.element.empty().load( pageUrl, function( responseText, textStatus, xhr ) {
        });
    },

    _buildContext: function( params ) {
        var context = {};
        if( params[ 'ordering' ] && params[ 'ordering' ] !== 'NEWEST' ) {
            context[ 'ordering' ] = params[ 'ordering' ];
        }

        if( params[ 'genre.id' ] && params[ 'genre.id' ] !== '' && params[ 'genre.id' ] !== 'null' ) {
            context[ 'genre.id' ] = params[ 'genre.id' ];
        }

        if( params[ 'location' ] ) {
            context[ 'location' ] = params[ 'location' ];
        }
        else if( params[ 'startAt' ] ) {
            context[ 'startAt' ] = params[ 'startAt' ];
        }
        else if( params[ 'endBefore' ] ) {
            context[ 'endBefore' ] = params[ 'endBefore' ];
        }

        return context;
    }

}); 

})( jQuery );

