var HorizontalGallery = Class.create ();

HorizontalGallery.prototype = {
    initialize: function ( leftButton, rightButton, stepSize, listContainers, defaultList, queryParams, thumbnailCreator ) {
        this.leftButton = $( leftButton );
        this.rightButton = $( rightButton );
        this.stepSize = stepSize;
        this.listContainers = listContainers;
        this.currentList = $( defaultList );
        this.queryParams = queryParams;
        this.thumbnailCreator = thumbnailCreator;

        this.retrieveActive = new Hash ();

        this.leftButton.observe ( 'click', this.moveLeft.bind ( this ) );
        this.rightButton.observe ( 'click', this.moveRight.bind ( this ) );

        this.bufferCount = 3;

        this.listContainers.each (
            function ( list ) {
                list.imageCount = list.select ( 'li' ).length;
                list.totalCount = false;

                if ( list.imageCount != 0 )
                    list.imageSize = parseInt ( list.select ( 'li' ) [ 0 ].getStyle ( 'width' ) );
                else
                    list.imageSize = this.stepSize;
            }
        );
    },

    moveLeft: function ( event ) {
        var currentLeft = parseInt ( this.currentList.getStyle ( 'left' ) );

        var minLeft = parseInt ( this.currentList.up ( 'ul' ).getStyle ( 'width' ) ) - ( this.currentList.imageCount * this.currentList.imageSize );

        if ( currentLeft > minLeft )
            new Effect.Move ( this.currentList, { x: -this.stepSize, y: 0 } );

        if ( currentLeft <= ( -( this.bufferCount - 1 ) * this.currentList.imageSize ) )
            this.getMoreItems ( this.currentList );

        var element = Event.element ( event );

        if ( element ) {
            Event.element ( event ).blur ();

            var parent = Event.element ( event ).up ( 'a' );

            if ( parent )
                parent.blur ();

            Event.stop ( event );
        }
    },

    moveRight: function ( event ) {
        var currentLeft = parseInt ( this.currentList.getStyle ( 'left' ) );

        if ( currentLeft < 0 )
            new Effect.Move ( this.currentList, { x: this.stepSize, y: 0 } );

        var element = Event.element ( event );

        if ( element ) {
            Event.element ( event ).blur ();

            var parent = Event.element ( event ).up ( 'a' );

            if ( parent )
                parent.blur ();

            Event.stop ( event );
        }
    },

    getMoreItems: function ( activeList ) {
        // If a retrieval is already in progress then don't start another
        if ( this.retrieveActive.get ( activeList ) == true )
            return;

        // If we already have the entire list of media then don't retrieve again
        if ( activeList.totalCount && ( activeList.imageCount >= activeList.totalCount ) )
            return;

        var params = this.queryParams [ this.listContainers.indexOf ( activeList ) ];

        var serviceParams = {
            'vhost': selectedVHost,
            'sort': params [ 'sort' ],
            'start': activeList.imageCount,
            'limit': 10
        };

        var fieldIndex = 0;

        params.fields.each (
            function ( currentField ) {
                serviceParams [ 'fields[' + fieldIndex++ + ']' ] = currentField;
            }
        );

        jsonRequest (
            'media.getFiles',
            serviceParams,
            function ( result ) {
                activeList.totalCount = result.totalCount;

                result.data.each (
                    function ( image ) {
                        activeList.appendChild ( this.thumbnailCreator ( image ) );

                        activeList.imageCount++;
                    }.bind ( this )
                );

                this.retrieveActive.set ( activeList, false );
            }.bind ( this ),
            function ( exception ) {
                alert ( exception );
            }
        );

        this.retrieveActive.set ( activeList, true );
    },

    setActive: function ( activeList ) {
        if ( this.listContainers.indexOf ( $( activeList ) ) == -1 )
            throw ( 'Unrecognized gallery list' );

        this.currentList = activeList;

        this.listContainers.each (
            function ( currentList ) {
                if ( currentList == activeList )
                    currentList.setStyle ( { visibility: 'visible' } );
                else
                    currentList.setStyle ( { visibility: 'hidden' } );
            }
        );
    }
};

Event.observe (
    window,
    'load',
    function () {
        if ( $$( 'div#gallery' ).length == 0 )
            return;

        var gallery = new HorizontalGallery (
            $( 'next' ),
            $( 'previous' ),
            352,
            $$( '#gallery .imageList' ),
            $( 'latest' ),
            new Array (
                { 'sort': 'upload DESC', 'fields': [ 'title', 'id', 'location' ] },
                { 'sort': 'hits DESC', 'fields': [ 'title', 'id', 'location' ] },
                { 'sort': 'upload ASC', 'fields': [ 'title', 'id', 'location' ] }
            ),
            function ( image ) {
                var li = document.createElement ( 'li' );
                var a = document.createElement ( 'a' );
                var img = document.createElement ( 'img' );

                a.href = '/mediadetail/' + image.id;

                img.title = image.title;
                img.alt = image.alt;
                img.src = image.publicUrl + '/13';

                a.appendChild ( img );
                li.appendChild ( a );

                return li;
            }
        );

        new Array ( 'latest', 'popular', 'all' ).each (
            function ( listName ) {
                $$( '.tabs .' + listName ) [ 0 ].observe (
                    'click',
                    function ( event ) {
                        $$( '.tabs a.active' ).each ( function ( currentTab ) { currentTab.removeClassName ( 'active' ); } );
                        $$( '.tabs .' + listName ) [ 0 ].addClassName ( 'active' );

                        gallery.setActive ( $( listName ) );

                        Event.element ( event ).blur ();

                        Event.stop ( event );
                    }
                );
            }
        );
    }
);

