/*******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

/**
 * Aligns a grid of objects
 * 
 * @param cols       The number of columns in the grid
 * @param cellWidth  the width of each cell
 * @param cellHeight the height of each cell
 * @param padding    the padding between the cells
 */
function alignGrid(/*int*/ cols, /*int*/ cellWidth, /*int*/ cellHeight, /*int*/ padding) {
    
    var x = 0;
    var y = 0;
    var count = 1;
    
    jQuery(".grid").each(function() {
        jQuery(this).css("position", "relative");
        
        jQuery(this).children("div").each(function() {
            jQuery(this).css({
                width: cellWidth + "em",
                height: cellHeight + "em",
                position: "absolute",
                left: x + "em",
                top: y + "em"
            });
            
            if ((count % cols) == 0) {
                x = 0;
                y += cellHeight + padding;
            } else {
                x += cellWidth + padding;
            }
            
            count++;
        });
        
        /*
         * Now we reset the variables for the next grid.
         */
        x = 0;
        y = 0;
        count = 1;
    });
}

/* 
 * Variables for handling the dynamic multigrid
 */
var gridcount = 0;
var gridwidth;
var gridheight;
var currentgrid = 0;

/* 
 * Positions the grid to a specific grid index.
 */
function positionGrid(/* int */ gridpos) {
    if (currentview != 0) {
        return;
    }
    
    jQuery("#gridnav" + currentgrid).removeClass("gridnavitemselected");
    currentgrid = gridpos;
    jQuery(".multigrid").each(function() {
        jQuery(this).animate({ 
            left: "-" + (gridwidth * currentgrid) + "em"
            }, 1500 );
    });
    
    /*
     * Set the next and previous links to be visible as needed
     */
    if (currentgrid == 0) {
        jQuery("#prevcontainer").hide(0);
    } else {
        jQuery("#prevcontainer").show(0);
    }
    
    if (currentgrid == (gridcount - 1)) {
        jQuery("#nextcontainer").hide(0);
    } else {
        jQuery("#nextcontainer").show(0);
    }
    
    jQuery("#gridnav" + currentgrid).addClass("gridnavitemselected");
}

/* 
 * Goes to the next grid position.  The is move right button
 */
function positionGridNext() {
    if (currentgrid == (gridcount - 1)) {
        return false;
    }
    
    positionGrid(currentgrid + 1);
    return false;
}

/* 
 * Goes to the previous grid position.  The is move left button
 */
function positionGridPrev() {
    if (currentgrid == 0) {
        return false;
    }
    
    positionGrid(currentgrid - 1);
    
    return false;
}

/* 
 * Adds an item to the grid navigation bar
 */
function addNavItem(index) {
    jQuery("#gridnav").append("<div id=\"gridnav" + (index  - 1) + "\" class=\"gridnavitem\"><a href=\"#\"" + 
                              "onclick=\"positionGrid(" + (index - 1) + "); return false;\">" + index + "</a></div>");

    /*
     * The navigation area needs to grow wide enough to hold all the items so we'll 
     * dynamically set the position of it based on the number of child nav items. 
     */
    jQuery("#gridnavcontainer").css("right", ((jQuery("#gridnav").children().length * 3.75) + 0.5) + "em" );
}

/**
 * Aligns a grid that spans multiple pages with dynamic links for 
 * navigation between the pages.
 * 
 * @param cols       The number of columns in the grid
 * @param cellWidth  the width of each cell
 * @param cellHeight the height of each cell
 * @param padding    the padding between the cells
 */
function alignMultiGrid(/*int*/ cols, /*int*/ cellWidth, /*int*/ cellHeight, /*int*/ padding) {
    
    init();
    
    var xoffset = padding;
    var x = xoffset;
    var y = -3;
    var cellcount = 1;
    var rowcount = 1;
    var maxrows = 3;

	if (getWindowHeight() < 800) {
		/*
		 * If the browser window is particularly short we want to show 
		 * two rows instead of three.
		 */
		maxrows = 2;
	}
    
    gridwidth = (cols * (cellWidth + padding)) + padding;
    gridheight = (maxrows * (cellHeight + padding)) + padding;
    
    currentgrid = 0;
    
    /* 
     * First we add the styles and the navigation components to the main grid container
     */
    jQuery(".maingridcontainer").each(function() {
        jQuery(this).css({
            position: "relative",
            width: (gridwidth + 5) + "em",
            height: (gridheight + 5) + "em"
        });
        
        
        /* 
         * Now we'll add the next and previous links
         */
        jQuery(this).append("<div class=\"nextprev\" id=\"nextcontainer\">" + 
                                "<a href=\"#\" id=\"next\" title=\"Next\"><div id=\"nextdiv\"> </div></a>" +
                            "</div>");
        jQuery(this).append("<div class=\"nextprev\" id=\"prevcontainer\">" + 
                                "<a href=\"#\" id=\"prev\" title=\"Previous\"><div id=\"prevdiv\"> </div></a>" + 
                            "</div>");
        
        /* 
         * And now the previous and next link styling
         */
        jQuery("#prevcontainer").css({
                width: "4em",
                height: "2em",
                position: "absolute", 
                top: ((maxrows / 2) * (cellHeight + padding) - 0.5) + "em",
                left: "-3em"
        });
        
        jQuery("#nextcontainer").css( {
            width: "4em",
            height: "2em",
            position: "absolute",
            top: ((maxrows / 2) * (cellHeight + padding) - 0.5) + "em",
            left: (gridwidth + 5) + "em"
        });
    });
    
    /* 
     * Now we style the grid container itself and add the navigation bar
     */
    jQuery(".multigridcontainer").each(function() {
        jQuery(this).css({
            overflow: "hidden",
            position: "relative",
            left: "2em",
            width: gridwidth + "em",
            height: (gridheight + 5) + "em"
        });
        
        /* 
         * Add the grid navigation bar
         */
        jQuery(this).append("<div id=\"gridnavcontainer\"><div id=\"gridnav\" class=\"grid\"></div></div>");
        jQuery("#gridnavcontainer").css({
            position: "absolute", 
            top: (gridheight) +  "em"
        });
    });
    
    /* 
     * Position the footer below the grid
     */
    jQuery("#mainfooter").css("top", 2 + "em");
    
    /* 
     * And now we are ready to align the grid.  This is where 
     * the magic happens 
     */
    jQuery(".multigrid").each(function() {
        jQuery(this).css("position", "relative");
        
        jQuery(this).children("div").each(function() {
            jQuery(this).css({
                width: cellWidth + "em", 
                height: cellHeight + "em",
                position: "absolute",
                left: x + "em",
                top: y + "em"
            });
            
            if ((cellcount % cols) == 0) {
                if ((rowcount % maxrows) == 0) {
                    /* 
                     * This means we have added the maximum number of rows to 
                     * this page in the grid and we need to push everything 
                     * over to the next grid; 
                     */
                    y = -3;
                    xoffset += gridwidth;
                    x = xoffset;
                    gridcount++;
                    addNavItem(gridcount);
                    
                } else {
                    /* 
                     * This just means we hit a new row on the current page.
                     */
                    x = xoffset;
                    y += cellHeight + padding;
                }
                
                rowcount++;
            } else {
                x += cellWidth + padding;
            }
            
            cellcount++;
        });
        
        /* 
         * This is a little hacky.  I need to see if I have to add a 
         * grid to the grid count for a partial grid at the end.  I could 
         * make this code a bit cleaner if JQuery has a do/while construct 
         * instead of just a for each 
         */
        if ((cellcount - 1) % (maxrows * cols) != 0) {
            gridcount++;
            addNavItem(gridcount);
        }
        
    });
    
    /*
     * Now we have to align a simple grid for the navigation controls
     */
    alignGrid(6, 2, 2, 1);
    
    /* 
     * Add listeners for the next and previous links
     */
    jQuery("#next").click(function() {
        positionGridNext();
        return false;
	});
    
    jQuery("#prev").click(function() {
        positionGridPrev();
        return false;
	});
    
    /*
     * The last step is to position the grid to the 0 index so the first 
     * control will be properly highlighted
     */
    positionGrid(0);
    
    /*
     * Now that we have aligned the grid we add the listener for the right arrow, 
     * left arrow, home, and end key events for grid navigation. 
     */
    addListener(document, 'keyup', KeyCheck);
    
    if (getUrlParam("showlist")) {
        showList();
    }
}


/*
 * Responds to the the right arrow, left arrow, home, and end key events for 
 * grid navigation. 
 */
var KeyCheck = function(e) {
    if(document.getElementById("tag").focused === false || 
       document.getElementById("tag").focused === undefined || 
       document.getElementById("tag").value.length === 0){
        var KeyID = (window.event) ? event.keyCode : e.keyCode;
        switch(KeyID) {
            case 35:    // the end key
                positionGrid(gridcount - 1);
                e.returnValue = false;
                return false;
            case 36:    // the home key
                positionGrid(0);
                e.returnValue = false;
                return false;
            case 37:    //the left arrow key
                positionGridPrev();
                e.returnValue = false;
                return false;
            case 39:    // the right arrow key
                positionGridNext();
                e.returnValue = false;
                return false;
        }
    }
};

/* 
 * Adds the KeyCheck listener for keyboard based grid navigation
 */
var addListener = function(element, type, expression, bubbling)
{
    bubbling = bubbling || false;
 
    if(window.addEventListener) { // Standard
        element.addEventListener(type, expression, bubbling);
        return true;
    } else if(window.attachEvent) { // IE
        element.attachEvent('on' + type, expression);
        return true;
    } else {
        return false;
    }
};

function createList(/*string*/ listContainer) {
    var count = 0;
    jQuery(".multigrid").each(function() {
        var len = jQuery(this).children("div").length;
        jQuery("#" + listContainer).append("<h2>Articles</h2>");
        
        jQuery(this).children("div").each(function() {
            var itemclass = "evenRow";
            if (count % 2 == 0) {
                itemclass="oddRow";
            }
            count++;
            
            var listitem = "<div class=\"gridlistitem " + itemclass + "\">" +
                // The number
                "<div class=\"listcol0\">" +
                    jQuery(this).children(".maincelltitle").attr("_thedate") +
                "</div>" + 
                
                // The article title
                "<div class=\"listcol1\">" +
                    "<a href=\"" +  jQuery(this).children(".maincelltitle").children("a").attr("href") + "\">" + 
                        jQuery(this).children(".maincelltitle").children("a").html() + 
                    "</a>" + 
                "</div>" + 
                
                // The article description
                "<div class=\"listcol2\">" +
                    jQuery(this).children("a").children("div").attr("title") + 
                "</div>" + 
                
                "</div>";
            jQuery("#" + listContainer).append(listitem);
        });
    });
}

function createSearchList(/*string*/ listContainer) {
    var count = 0;
    jQuery(".multigrid").each(function() {
        var len = jQuery(this).children("div").length;
        jQuery(this).children("div").each(function() {
            var itemclass = "evenRow";
            if (count % 2 == 0) {
                itemclass="oddRow";
            }
            count++;
            
            var excerpt = "";
            
            excerpt = jQuery(this).children(".cellexcerpt").children("a").children("p").html();
            
            var listitem = "<div class=\"gridlistitem " + itemclass + "\">" +
                // The number
                "<div class=\"listcol0\">" +
                    count + 
                "</div>" + 
                
                // The article title
                "<div class=\"listcol1\">" +
                    "<a href=\"" +  jQuery(this).children(".maincelltitle").children("a").attr("href") + "\">" + 
                        jQuery(this).children(".maincelltitle").children("a").html() + 
                    "</a>" + 
                "</div>" + 
                
                // The article description
                "<div class=\"listcol2\">" +
                    excerpt + 
                "</div>" + 
                
                "</div>";
            jQuery("#" + listContainer).append(listitem);
        });
    });
}

function getWindowHeight() {
  var myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myHeight = document.body.clientHeight;
  }
  return myHeight;
}

var currentview = 0;
var isSliding = false;

function doneSliding() {
    isSliding = false;
}

function showHelp() {
    if (isSliding) {
        /* 
         * This means we are already in the middle of a slide operation.
         */
        return;
    }
    
    if (currentview != 2) {
        isSliding = true;
        hideContainers();
        jQuery("#helpcontainer").slideDown("slow", doneSliding());
        currentview = 2;
    }
    
}

function showGrid() {
    if (isSliding) {
        /* 
         * This means we are already in the middle of a slide operation.
         */
        return;
    }
    
    if (currentview != 0) {
        isSliding = true;
        hideContainers();
        jQuery(".maingridcontainer").slideDown("slow", doneSliding());
        currentview = 0;
    }
    
}

function showList() {
    if (isSliding) {
        /* 
         * This means we are already in the middle of a slide operation.
         */
        return;
    }
    
    if (currentview != 1) {
        isSliding = true;
        hideContainers();
        jQuery("#listContainer").slideDown("slow", doneSliding());
        currentview = 1;
    }
    
}

function hideContainers() {
    jQuery(".maingridcontainer").hide();
    jQuery("#listContainer").hide();
    jQuery("#helpcontainer").hide();
    
}

function init() {
    jQuery("#nojswarning").hide();
    
    var searchString = "search";
    
    jQuery("#maincontainer").prepend("<div id=\"switchButtons\">" + 
                                        "<div id=\"mainbarleft\">" + 
                                            "Check out the <a href=\"#\" onclick=\"showHelp(); return false;\">best of</a>" + 
                                        "</div>" + 
                                        "<form id=\"mainbarright\" class=\"search_form\" action=\"/\" method=\"get\" style=\"width: 25em;\">" + 
                                            "View as " + 
                                            "<a href=\"#\" onclick=\"showGrid(); return false;\">icons</a>, " + 
                                            "<a href=\"#\" onclick=\"showList(); return false;\">list</a>, or " + 
                                            jQuery("#mainsearch").html() + 
                                        "</form>" + 
                                    "</div>");
    
    /* 
     * This is a semi-hack for loading images.  I want to load all the images from an image 
     * bundle so I can make the page load faster.  The problem is that the image bundle gets 
     * larger with more articles.  Putting every image in one image bundle makes the user wait 
     * for all the images to load before they see any of them even though they are only looking 
     * at the front page. 
     *  
     * We separate the images into multiple bundles to speed up the page.  However, we don't 
     * want to load all of the bundles when the page loads.  In order to make sure the images 
     * in the second page load later we  set them here in the JavaScript after the page loads.
     */
    jQuery(".bundletwo").css({
        backgroundImage: "url('http://images.gettheeye.com/images/main_images.png')",
        backgroundRepeat: "no-repeat"
    });
}



var isSubtitleExtendedVisible = false;

/*
 * Shows or hides the subtitle text.
 */
function showSub() {
    jQuery("#mainsubtitleextended").slideToggle("normal");
    isSubtitleExtendedVisible = !isSubtitleExtendedVisible;
    
    if (isSubtitleExtendedVisible) {
        jQuery("#subtitlereadmorelink").html("Less");
    } else {
        jQuery("#subtitlereadmorelink").html("More");
    }
    
    return false;
}

function getUrlParam(strParamName){
	  strParamName = escape(unescape(strParamName));
	  
	  var returnVal = new Array();
	  var qString = window.location.search.substr(1,window.location.search.length).split("&");
      
	  
	  if (qString==null) return null;
	  
	  
	  for (var i=0;i<qString.length; i++){
			if (escape(unescape(qString[i].split("=")[0])) == strParamName){
				returnVal.push(qString[i].split("=")[1]);
			}
			
	  }
	  
	  
	  if (returnVal.length==0) return null;
	  else if (returnVal.length==1) return returnVal[0];
	  else return returnVal;
}
