/*
 * HeresJonnie.com Actions v1.0
 * Soli Deo Gloria
 * Copyright (c) 2010 Jonathan Niesen
*/
(function($) {
    var winWidth = $(window).width(),
        winHeight = $(window).height(),
        plane = $('<div id="plane" />'),
        keys = {
            37: 'left',
            38: 'up',
            39: 'right',
            40: 'down'
        },
        reserves = {
            'up': 0,
            'right': 0,
            'down': 0,
            'left': 0
        },
        properties = {
            'up': 'top',
            'right': 'left',
            'down': 'top',
            'left': 'left'
        },
        opposites = {
            'up': 'down',
            'right': 'left',
            'down': 'up',
            'left': 'right',
            'x': 'y',
            'y': 'x'
        };
        
    // We don't want the arrow keys to perform their default action
    $(document).keydown(function(event) {
        if (event.keyCode == 37 || event.keyCode == 39 || event.keyCode == 38 || event.keyCode == 40) {
            event.preventDefault();
        }
    });
    
    $.fn.findCoordLimits = function() {
        var upperLimit  = null,
            upperXLimit = 0,
            upperYLimit = 0;
        
        this.each(function() {
            upperXLimit = ( $(this).data('x') > upperXLimit) ? $(this).data('x') : upperXLimit;
            upperYLimit = ( $(this).data('y') > upperYLimit) ? $(this).data('y') : upperYLimit;
        });
        
        upperLimit = {'x': upperXLimit, 'y': upperYLimit };
        
        return upperLimit;
    };
    
    $.fn.arrangeCells = function() {
        var cells = this,
            columns = settings.columns,
            x = 0,
            y = 0,
            limit = null;
            
        // Style the plane that will contain all the cells
        plane.css({
            'left': 0,
            'position': 'absolute',
            'top': 0
        });
        
        // Initialize each cell by saving their coordinates and positioning them within the plane
        cells.wrapAll(plane).each(function(index) {
            // if the index is equal to 0, this is the first cell
            if (index === 0) {
                // x and y coords of the first cell are 0,0
                x = 0;
                y = 0;
                $(this).addClass('current');
            } else {
                if(x === columns) {
                    // if x is equal to columns, we add a new row and reset x
                    x = 0;
                    y++;
                } else {
                    // if the cell is not first and doesn't start a new row carry on
                    y = y;
                    x = x;
                }
            }
            
            // give the cell it's coordinates
            $(this).data({ 'x':x, 'y':y });
            
            // position the cell using the coordinates
            $(this).css({
                'height': winHeight - parseFloat( $(this).css('paddingTop').replace('px', '') ),
                'left': $(this).data('x') * winWidth,
                'position': 'absolute',
                'top': $(this).data('y') * winHeight,
                'width': winWidth
            });
            
            // count the views of this cell
            if ($(this).hasClass('project') === true) {
                var project = $(this);
                $(this).find('.view-count .total').text(project.find('.media .slide').length)
            }
            
            //move to the next cell
            x++;
        });
            
        // Update the cell reserves
        limit = cells.findCoordLimits();
        reserves.right = limit.x;
        reserves.down = limit.y;
            
        // Style the plane that will contain all the cells
        $('#plane').css({
            'height': (limit.y + 1) * winHeight,
            'width': (limit.x + 1) * winWidth
        });
        
        return this;
            
    };
    
    $.fn.doSomeAnimating = function(animation) {
        var plane = $('#plane');
        
        animation.current.removeClass('current');
        animation.next.addClass('current');
        plane.animate(animation.args, animation.speed, animation.easing);
    };
    
    $.fn.prepareToAnimate = function(direction) {
        /*
        Test whether or not a project is available in each direction.
        
        If a project is available the arrow notifier should be lit.
        
        If no project is available it should not be lit.
        */
        var plane = $('#plane'),
            axis = null,
            distance = 0,
            increment = 0,
            currentCell = plane.find('.current'),
            currentCoords = {
                'x': currentCell.data('x'),
                'y': currentCell.data('y')
            },
            nextCell = null,
            nextCoords = {},
            property = properties[direction],
            destination = 0,
            args = {},
            animation = null;
            
        if (direction === 'up' || direction === 'down') {
            axis = 'y';
            distance = winHeight;
        } else if (direction === 'right' || direction === 'left') {
            axis = 'x';
            distance = winWidth;
        }
        if (direction ===  'up' || direction === 'left') {
            increment = -1;
        } else if (direction === 'right' || direction === 'down') {
            increment = +1;
        }
        
        nextCoords[axis] = currentCoords[axis] + increment;
        nextCoords[opposites[axis]] = currentCoords[opposites[axis]];
        nextCell = $('#plane').find('.cell').filter(function() { return $(this).data(axis) == nextCoords[axis] && $(this).data(opposites[axis]) == nextCoords[opposites[axis]]; });
        
        destination = nextCoords[axis] * distance * -1;
        args[property] = destination;
        
        animation = {
            'current': currentCell,
            'next': nextCell,
            'args': args,
            'speed': settings.speed,
            'easing': settings.easing
        };
        
        if (nextCell.length !== 0) {
            reserves[direction]--;
            reserves[opposites[direction]]++;
            
            var testcases = {
                'up': $('#plane').find('.cell').filter(function() { return $(this).data('x') == nextCoords.x && $(this).data('y') == nextCoords.y - 1; }),
                'right': $('#plane').find('.cell').filter(function() { return $(this).data('x') == nextCoords.x + 1 && $(this).data('y') == nextCoords.y; }),
                'down': $('#plane').find('.cell').filter(function() { return $(this).data('x') == nextCoords.x && $(this).data('y') == nextCoords.y + 1; }),
                'left': $('#plane').find('.cell').filter(function() { return $(this).data('x') == nextCoords.x - 1 && $(this).data('y') == nextCoords.y; }),
            }
            
            $.each(testcases, function(key, value) {
                var arrowkey = $('body').find('#' + key + '-key');
                if (value.length === 0) {
                    if (arrowkey.hasClass('ready') === true) {
                        arrowkey.removeClass('ready');
                    }
                } else {
                    if (arrowkey.hasClass('ready') === false) {
                        arrowkey.addClass('ready');
                    }
                }
                
                
            });
            
            plane.doSomeAnimating(animation);
        } else {
            console.log(nextCell.length);
        }
    };
    
    $.fn.makeCartesian = function(options) {
        var cells = this;
        
        settings = jQuery.extend({
            "columns": 4,
            "bounds": "finite",
            "speed": 500,
            "easing": "easeInOutQuart"
        }, options);
        
        cells.arrangeCells();
        
        $('body').find('.cellkey').live('click', function(event) {
            event.preventDefault();
            
            var target = $(this).attr('href'),
                animation = {
                    'current': $('body').find('.current'),
                    'next': $(target),
                    'args': {
                        'top': $(target).data('y') * winHeight * -1,
                        'left': $(target).data('x') * winWidth * -1
                    },
                    'speed': settings.speed,
                    'easing': settings.easing
                },
                currentX = $('body').find('.current').data('x'),
                currentY = $('body').find('.current').data('y'),
                nextX = $(target).data('x'),
                nextY = $(target).data('y');
            
            if (nextX > currentX) {
                //slide to the left, the result must be negative (-)
                reserves.left = Math.abs(reserves.left - nextX - currentX);
                reserves.right = Math.abs(reserves.right - nextX - currentX);
            } else if (nextX < currentX) {
                //slide to the right, the result must be positive (+)
                reserves.left += currentX - nextX;
                reserves.right += currentX - nextX;
            }
            
            if (nextY > currentY) {
                //slide up, the result must be negative (-)
                reserves.up = Math.abs(reserves.up - nextY - currentY);
                reserves.down = Math.abs(reserves.down - nextY - currentY);
            } else if (nextY < currentY) {
                //slide down, the result must be positive (+)
                reserves.up += currentY - nextY;
                reserves.down += currentY -nextY;
            }
                
            $('#plane').doSomeAnimating(animation);
        });
        
        $(document).keydown(function(event) {
            var keyCode = event.keyCode,
                direction = keys[keyCode];
                
            if (reserves[direction] > 0) {
                
                $('#plane').prepareToAnimate(direction);
                return true;
                
            } else {
                return false;
            }
        });
    };
})(jQuery);

$(document).ready(function() {
    var backdrop = $('<div id="backdrop"></div>');
    backdrop.css('opacity', '.6');
    
    $('body').find('.cell').makeCartesian();
    
    $('body').find('.lightswitch').click(function(event) {
        event.preventDefault();
        var projectId = $(this).parents('.project').attr('id');
        var lightbox = $('#' + projectId).find('.lightbox');
        if (lightbox.hasClass('off') === true) {
            lightbox.removeClass('off').addClass('on');
            lightbox.css({
                'left': ($(window).width() - lightbox.width()) / 2,
                'top': ($(window).height() - lightbox.height()) / 2
            });
            backdrop.appendTo('body');
        } else {
            lightbox.removeClass('on').addClass('off');
            backdrop.remove();
        }
    });
    
    $('body').find('.closebutton').click(function(event) {
        event.preventDefault();
        var projectId = $(this).parents('.project').attr('id');
        var lightswitch = $('#' + projectId).find('.lightswitch');
        lightswitch.trigger('click');
    });
    
    $('body').find('.next-view').click(function(event) {
        event.preventDefault();
        var projectId = $(this).parents('.project').attr('id');
        var curSlide = $('#' + projectId).find('.slide.active');
        var curCount = parseFloat($('#' + projectId).find('.view-count .now').text());
        if (curSlide.next('.slide').length > 0) {
            curSlide.css('display', 'none').removeClass('active');
            curSlide.next('.slide').css('display', 'block').addClass('active');
            $('#' + projectId).find('.view-count .now').text(curCount + 1);
        }
    });
    
    $('body').find('.prev-view').click(function(event) {
        event.preventDefault();
        var projectId = $(this).parents('.project').attr('id');
        var curSlide = $('#' + projectId).find('.slide.active');
        var curCount = parseFloat($('#' + projectId).find('.view-count .now').text());
        if (curSlide.prev('.slide').length > 0) {
            curSlide.css('display', 'none').removeClass('active');
            curSlide.prev('.slide').css('display', 'block').addClass('active');
            $('#' + projectId).find('.view-count .now').text(curCount - 1);
        }
    });
    
    $(document).keydown(function(event) {
        event.preventDefault();
        if (event.keyCode === 32) {
            var projectId = $('body').find('.project.current').attr('id');
            var lightswitch = $('#' + projectId).find('.lightswitch');
            //if (lightswitch.length > 0) {
                lightswitch.trigger('click');
            //}
        }
    });
});
