$(document).ready(function(){
        
        
        $('.grid').attr('rel', '#overlay');
               
        $(".grid[rel]").overlay({
            finish: { top: 280 },
            onBeforeLoad: function() { 
                /* set default search quality and results listing type*/
                $("input[name=quality]")[2].checked = true;
                $("input[name=listing_type]").val("image");
                
                target = this.getTarget();
                if(target.tagName != "IMG") {
                    return false;
                } else {
                    /* we've clicked an image! */
                    ajax_url = sf_relative_url_root + "/itemajax/"+$(target).attr('object_id')+"?wall=1";
                    $("#overlay_content").load(ajax_url);
                }
            },
            onClose: function() {
                $("#overlay_content").html("");
            }
        });
        
        var tile_size = 197;
        var blank_tile = '<li><img class="blank" src="" alt="" /></li>'
        var wall_width = 944;
        var wall_height = 484;
        
        var num_rows = 3;
        var num_cols = 5;
        var max_cols = 6;
        var max_rows = 4;
        var max_limit = 45;
        var tile_fill_interval = 10; //(ms)
        var pop_cache_interval = 250;
        var img_fade_speed = 250;
        
        var ajax_in_progress = false;
        
        if(!wall_theme) {
            var max_offset = 850;
        } else {
            var max_offset = (wall_theme.group_count < 1000) ? wall_theme.group_count : 850;
        }

        var GRIDWIDTH = Math.floor(Math.sqrt(max_offset));
        var GRIDHEIGHT = Math.floor(Math.sqrt(max_offset));

        max_offset -= GRIDWIDTH;

        var offset_anchor = Math.floor(Math.random() * (GRIDWIDTH * GRIDHEIGHT));
        
        var offset = offset_anchor;
        
        var buffer = new Object();
        buffer.size = tile_size;
        buffer.top = tile_size * -1;
        buffer.btm = wall_height + buffer.size;
        buffer.left = $('#wall').position().left - buffer.size;
        buffer.right = buffer.left + wall_width + buffer.size;
        
        image_cache = new Object();
        cache_images();
        
        /* assign initial offsets to images */
        update_offsets();
        
        fill_loop_id = setInterval(fill_empty_tiles, tile_fill_interval);
        cache_loop_id = setInterval(cache_images, pop_cache_interval);
        
        function cache_images() {
            empties = $('.grid-inner li img.blank');
            if($(empties).size() > 0) {
                var offset = $('.grid-inner li img.blank:first').attr('offset');
                if(typeof(offset) != "undefined" && ajax_in_progress === false) {
                    if(typeof(image_cache[offset]) == "undefined") {
                        //var limit = ($(empties).size()) > 45 ? 45 : $(empties).size();
                        var limit = 45;
                        var url = sf_relative_url_root + "/" + api_url + "wall/" + offset + "/"+limit+"/";
                        if(typeof(wall_theme.group) != 'undefined') {
                            url += "?" + wall_theme.group +"="+wall_theme.id;
                        }
                        if($('.grid-inner li img.blank').size() > 0) {
                            ajax_in_progress = true;
                            $.getJSON(url, function(json){
                                if(json == "[]" || json == "null" || json == null || json.length <= 0) {
                                    max_offset = offset - 92;
                                    GRIDWIDTH = Math.floor(Math.sqrt(max_offset));
                                    GRIDHEIGHT = Math.floor(Math.sqrt(max_offset));
                                    update_offsets();
                                    ajax_in_progress = false;
                                } else {
                                    $.each(json, function(idx, museum_object){
                                        image_url = collection_images_url + museum_object.fields.primary_image_id.substr(0, 6) + "/" + museum_object.fields.primary_image_id + "_jpg_ws.jpg";
                                        offs = parseInt(offset) + idx;
                                        image_cache[offs] = {};
                                        image_cache[offs].image = image_url;
                                        image_cache[offs].object_id = museum_object.fields.object_number;
                                        ajax_in_progress = false;
                                    });
                                }
                                
                            });
                        }
                    }
                }
            }
        }
        
        function fill_empty_tiles() {
            empties = $('.grid-inner li img.blank');
            if($(empties).size() > 0) {
                $.each(empties, function(e, i) {
                    //i = $('.grid-inner li img.blank:first');
                    o = $(i).attr('offset');
                    if(typeof(image_cache[o]) != 'undefined') {
                        $(i).attr('src', image_cache[o].image);
                        $(i).attr('object_id', image_cache[o].object_id);
                        $(i).fadeIn(img_fade_speed);
                        $(i).removeClass('blank');
                    }
                });
            }
           
        }
        
        /* updates the offset attr of all images */
        function update_offsets() {
            
            if(offset_anchor <= 0) {
                offset_anchor = max_offset;
            } else if(offset_anchor >= max_offset) {
                offset_anchor = 0;
            }
            
            o = offset_anchor;
            c = 0;
            $.each($('.grid-inner li img'), function(k, li) {
                $(li).attr('offset', o);
                c++
                if(c >= num_cols) {
                    o += (GRIDWIDTH - num_cols) +1;
                    c = 0;
                } else {
                    o++;
                }
            });
        }
        
        /* scans for tiles that are not currently in the viewport and removes them */
        function remove_hidden_tiles() {
        
            $g = $('.grid');

            /* Remove tiles from right */            
            grid_right_edge = $g.position().left + $g.width();
            if(num_cols > max_cols && grid_right_edge > buffer.right) {
                while(num_cols > max_cols) {
                    $('.grid-inner li:last-child').remove();
                    num_cols--;
                }
            }

            /* Remove tiles from left */
            if(num_cols > max_cols && $g.position().left < buffer.left) {
                var cols_removed = 0;
                while(num_cols > max_cols) {
                    $('.grid-inner li:first-child').remove();
                    num_cols--;
                    cols_removed++;
                }
                new_grid_position = $g.position().left + cols_removed * tile_size;
                $g.css('left', new_grid_position);
                offset_anchor += cols_removed;
            }

            
            /* Remove tiles from bottom */
            grid_bottom_edge = $g.position().top + $g.height();
            if(num_rows > max_rows && grid_bottom_edge > buffer.btm) {
                var rows_removed = 0;
                while(num_rows > max_rows) {
                    $('.grid-inner:last').remove();
                    num_rows--;
                    rows_removed++;    
                }
            }
            
            /* Remove tiles from top */
            if(num_rows > max_rows && $g.position().top < buffer.top) {
                var rows_removed = 0;
                while(num_rows > max_rows) {
                    $('.grid-inner:first').remove();
                    num_rows--;
                    rows_removed++;  
                    offset_anchor += GRIDWIDTH;  
                }
                new_grid_position = $g.position().top + rows_removed * tile_size;
                $g.css('top', new_grid_position);
            }
            
            /* Reset grid dimensions according to what's been removed */
            $g.width(num_cols * tile_size);
            $g.height(num_rows * tile_size);
            
        }
        
        $('.grid').draggable({
            
            //axis: 'y',
            cursor: 'pointer',
            delay: 150,
            
            stop: function(event, ui) { 
            
                var $g = $('.grid');
            
                this.top = $g.position().top;
                this.bottom = this.top + $g.height();
                this.left = $g.position().left;
                this.right = this.left + $g.width();
                
                this.space = new Object();
                this.space.top = (this.space < 0) ? 0 : this.top;
                this.space.bottom = (this.bottom - wall_height > 0) ? 0 : (this.bottom - wall_height) * -1;
                this.space.left = (this.left < 0) ? 0 : this.left;
                this.space.right = (this.right - wall_width > 0) ? 0 : (this.right - wall_width) * -1;
                
                new_cols_left = Math.ceil(this.space.left / tile_size);
                if(new_cols_left < 0) new_cols_left = 0;
                new_cols_right = Math.ceil(this.space.right / tile_size);
                if(new_cols_right < 0) new_cols_right = 0;
                new_rows_top = Math.ceil(this.space.top / tile_size);
                if(new_rows_top < 0) new_rows_top = 0;
                new_rows_bottom = Math.ceil(this.space.bottom / tile_size);
                if(new_rows_bottom < 0) new_rows_bottom = 0;
                
                extra_width = new_cols_left * tile_size + new_cols_right * tile_size;
                extra_height = new_rows_top * tile_size + new_rows_bottom * tile_size;
                
                if(extra_height > 0) {
                    new_grid_height = $g.height() + extra_height;
                    $g.height(new_grid_height);
                }
                
                var row = "<ul class='grid-inner'>";
                for(var h = 0; h < num_cols; h++) {
                    row += blank_tile;
                }
                row += "</ul>";
                
                /* insert new rows on top */
                if(new_rows_top > 0) {
                    var rows_to_insert = "";
                    for(var j = 0; j < new_rows_top; j++) {
                        rows_to_insert += row;
                    }
                    $g.css('top', this.top - extra_height);
                    $g.prepend(rows_to_insert);
                    num_rows += new_rows_top;
                    /* for each row added on the top, subtract GRIDWIDTH from offset_anchor */
                    offset_anchor -= new_rows_top * GRIDWIDTH; 
                }
                
                /* insert new rows on bottom */
                if(new_rows_bottom > 0) {
                    old_width = $(".grid-inner").width();
                    var rows_to_insert = "";
                    for(var j = 0; j < new_rows_bottom; j++) {
                        rows_to_insert += row;
                    }
                    $g.append(rows_to_insert);
                    num_rows += new_rows_bottom;
                }
                /* we need to set the new width of the grid AFTER any new rows have been added */
                if(extra_width > 0) {
                    new_grid_width = $g.width() + extra_width;
                    $g.width(new_grid_width);
                }
                
                /* insert new cols on left */
                if(new_cols_left > 0) {
                    var tiles_to_insert = "";
                    for(var i = 0; i < new_cols_left; i++) {
                        tiles_to_insert += blank_tile;
                    }
                    $g.css('left', this.left - extra_width);
                    $(".grid-inner").prepend(tiles_to_insert);
                    num_cols += new_cols_left;
                    offset_anchor -= new_cols_left
                }
                
                /* insert new cols on right */
                if(new_cols_right > 0) {
                    var tiles_to_insert = "";
                    for(var i = 0; i < new_cols_right; i++) {
                        tiles_to_insert += blank_tile;
                    }
                    $(".grid-inner").append(tiles_to_insert);
                    num_cols += new_cols_right;
                }
                
                remove_hidden_tiles();
                update_offsets();
                
            }
        });

        
        
        
        
});

