// Use module pattern to encapsulate switch from jQuery 
// compat-mode name-spacing to default $-function name.

(function(){
    var $ = jQuery;

    function ProjectsCarousel() {
        var self = this;

        this.init = function () {
            this.container = $('#carousel');
            this.projectId = this.container.attr('data-project-id');

            // We probably aren't on the showcase page, so stop here.
            if (!this.container.length) {
                return;
            }

            // Find the component elements.
            this.navL = this.container.find('#nav-lft');
            this.navR = this.container.find('#nav-rgt');
            this.list = this.container.find('ul');
            this.items = this.list.find('li');
            this.filter = 'all';
            $('#filter').change(function(){ self.filter = $('#filter option:selected').text(); self.loadProjectList();});

            // Remove the non-JS fallback pagination links.
            this.navL.find('a').replaceWith('<a href="#">&laquo</a>');
            this.navR.find('a').replaceWith('<a href="#">&raquo</a>');
            // Hide the non-JS fallback go button
            $('.showcase-filter input').hide();

            this.itemWidth = this.items.eq(0).width() + 10;
            this.isAnimating = false;

            // Load in the full list of projects (default set is paginated)
            this.loadProjectList();
        };
        
        this.updateProjectList = function (projects) {            
            // Empty out the existing list items.
            this.list.empty();
            
            // Add in the new set.
            for (var i=0; i<projects.length; i++) {
                var proj = projects[i];
                var elem = $('<li data-project-id="' + proj.id + '"><a href="#"><img src="' + proj.url + '/++atfield++heroImage-thumb" /></a></li>');
                this.list.append(elem);
            }

            // Refresh our list items jquery result set.
            this.items = this.list.find('li');
        };

        this.initProjectList = function () {
            // Handle left/right navigation.
            this.navL.mousedown(function(){ self.mouseIsDown = true; self.move(-1); return false; });
            this.navR.mousedown(function(){ self.mouseIsDown = true; self.move( 1); return false; });
            $(document).mouseup(function(){ self.mouseIsDown = false; });

            // Handle click events for all current & future list items.
            this.items.live('click',function(){
                var id = $(this).attr('data-project-id');
                self.selectByProjectId(id);
                self.loadProject(id);
                return false;
            });

            // Add "buffer" images off-screen at the start & end of the list.
            this.bufferL(true);
            this.bufferR();

            // Compensate for the buffer images hidden at either side.
            this.list.css({
                'left': '-' + this.itemWidth + 'px',
                'width': (this.list.width() + (this.itemWidth*2)) + 'px'
            });

            // Highlight the currently selected project.
            this.selectByProjectId(this.projectId);
        };

        this.loadProjectList = function () {
            $.getJSON('/portal/@@showcase-ajax-projects/', {'filter':this.filter}, function(data){
                var projects = data.projects;
                if (projects) self.updateProjectList(projects);
                self.initProjectList();
            });
        };

        this.loadProject = function (id) {
            $.getJSON('/portal/showcase/@@showcase-ajax-project-by-id/', { 'id':id }, function(data){
                var project = data.project;
                if (project) {
                    $('#content .banner-image img').attr('src', project.heroImg + '/++atfield++heroImage-hero');
                    $('#content-header .header-description').html(project.heroTxt);
                    $('#content .tag-line h3').html(project.title);
                    $('#content .tag-line .tag-description').html(project.description);
                    $('#project-text').html(project.projectText);
                    $('#project-contact div').html(project.address);
                    $('div.googleMapView').replaceWith(project.maptemplate);
                    mapsGoogleMaps.init();
                }
            });
        };

        this.selectByProjectId = function (id) {
            // Using the URL rather than the element because we may have multiple
            // matching items in certain circumstances due to the buffering.
            this.items.each(function(){
                var alpha = ($(this).attr('data-project-id') == id) ? '1.0':'0.3';
                $(this).find('img').animate({ 'opacity':alpha }, 500);
            });
            this.projectId = id;
        };

        this.move = function (dir) {
            if (this.isAnimating) return;
            this.isAnimating = true;

            var oldPos = parseInt(this.list.css('left'), 10);
            var newPos = oldPos - (this.itemWidth * dir);

            this.list.animate({ 'left': newPos }, 300, 'linear', function(){
                // Remove the current buffer image off one end of the list and then
                // replace it with an appropriate one at the opposite end of the list.
                if (dir>0) {
                    self.unbufferL();
                    self.bufferR();
                } else {
                    self.unbufferR();
                    self.bufferL();
                }
                
                // Undo the positioning, since it's been counteracted 
                // by the DOM manipulation we've just done above.
                self.list.css({ 'left': oldPos + 'px' });

                // Start honouring mouse clicks again.
                self.isAnimating = false;

                // Keep animating if click is held.
                if (self.mouseIsDown) self.move(dir);
            });
        };

        this.bufferL = function (firstRun) {
            var offset = firstRun ? 0:1;
            this.list.prepend(this.items.eq(this.items.length - (1 + offset)).clone());
            this.items = this.list.find('li');
        };
        this.bufferR = function (firstRun) {
            var offset = firstRun ? 0:1;
            this.list.append(this.items.eq(offset).clone());
            this.items = this.list.find('li');
        };
        
        this.unbufferL = function () {
            this.items.eq(0).remove();
            this.items = this.list.find('li');
        };
        this.unbufferR = function () {
            this.items.eq(this.items.length - 1).remove();
            this.items = this.list.find('li');
        };

        this.init();
    }

    // Run on page-load rather than document ready because we 
    // care about the dimensions of images and their ancestors.
    $(window).load(function(){ 
        new ProjectsCarousel();
    });

})();
