/*
 *	dn v1.0

 *	@author donny nguyen
 *	jQuery for donnynguyen.com
 *  all i'd like is a shout out if you're gonna use this in any way. enjoy. thanks.
 */

(function($) {

    var firstTileInfo = "";
    var currTileInfo = "";
    var lastTile;
    var lastPane;
    var lastPaneIsOpen = false;
    var minPaneHeight = 35;
	var minWidth = 842; 
    var defaultCaption = "&nbsp;";
    var defaultColour = "#ffffff";
    var defaultBackgroundColour = "#a6a6a6";
    var defaultBookmarkedBackgroundColour = "#a6a6a6";
    var firstColour = 89;
    var secondColour = 144;
    var colourThreshold = 16777215;
    var colourModes = new Array("high", "low", "off");
    var colourModeIndex = 0;
    var clickCount = 0;
    var hoverCount = 0;
	var newsViewed = false;

    $.fn.dnBasketweave = function( options ) {
        var defaults = {
            colourModeIndex: 0, 
			duration: 400,
            minimumWidth: 30,
            minimumHeight: 35,
			maximumWidth: 548,            
            maximumHeight: 595,
            paneHeaderHeight: 35			
        },

		// initialisations
		options = $.extend(defaults, options);
		
		// set the widths according the browser size at load time
		var w = Math.max( minWidth , $(window).width() ); 
		
		$( '#header' ).css({ width : '61.8%' , marginLeft : "19.1%" });		
		$( '#nav' ).css({ width : '79.9%' , marginLeft : "19.1%" });		
		$( '#content' ).css({ width : '100%' });		
		$( '#info' ).css({ width: '100%' });		
		$( '#infoPane' ).css({ paddingLeft : "19.1%" , paddingRight : "19.1%" });		
		$( '#footer' ).css({ width : '100%' });		
		$( '.legalese' ).css({ paddingRight: '19.1%' });
		$( '.pane' ).css({ height: options.paneHeaderHeight	});		
		$( '.paneHeader' ).css({ paddingLeft: '19.1%' , paddingRight: '19.1%' });
		$( '#news' ).css('border-bottom' , '1px solid ' + defaultBackgroundColour );
		
		// set the colour mode based on the page's configuration
        colourModeIndex = options.colourModeIndex;
		$("#colourMode").attr("innerHTML", colourModes[colourModeIndex]);
		
        /*
         *	helpPane click event
         */
        $(".helpPane").click(function() {

            HandlePaneEvents(this, false);
            //ChooseNextColours();

        }); // end helpPane click

        /*
         *	infoPane click event
         */
        $(".infoPane").click(function() {

            HandlePaneEvents(this, true);
            //ChooseNextColours();

        }); // end infoPane click

        /*
         *	pane click event
         */
        $(".pane").click(function() {

            clickCount += 1;
            ShowActionCount();
            HandlePaneEvents(this, true);
            //ChooseNextColours();

        }); // end pane click

		$('#news').click( function() {
			$( this ).css( 'border-bottom' , 'none' );
		});

        /*
        *	tile click event
        */
        // $("a").bind( "dblclick", function() { 
        // if( this.id != "colourMode" && this.id != "ext" ) {
        // alert("piece was double-clicked!");
        // }
        // return false;
        // })

        /*
        *	tile click event
        */
        $("a").click(function() {
            clickCount += 1;
            ShowActionCount();

            if (this.id == "colourMode") { // change the colour mode
                colourModeIndex = (colourModeIndex + 1) % 3;
                $("#colourMode").attr("innerHTML", colourModes[colourModeIndex]);
                return false;
            }
            else if (this.id == "permalink") {
                ShowMessage(window.location);
				ChooseNextColours();
                return false;
            }
            else if (this.id == "bookmark") {
             
                var paneRef = "#" + $("." + $(this).attr("title")).parent().parent().parent().attr("id");
				
                var tileRef = paneRef + " ul > li > ." + $(this).attr("title")
                var tileWidth = $(tileRef + " > img").width();
                var currentCaption = $(tileRef).attr("title");

                if (currentCaption == undefined || currentCaption.length < 1) {
                    currentCaption = defaultCaption;
                }

				// close the news pane
                ClosePane("#newsPane", false);
				
				// open the bookmarked pane
				OpenPane(paneRef, true);
				
				//sent the background colour
				//$(paneRef).css("background-color", ColourValue(firstColour, secondColour));
				 SetCaption(paneRef + " > .caption", $(this).attr("title"), (colourModeIndex < 2));
				
				// $(paneRef + ' > .paneHeader').css("background-color", ColourValue(firstColour, secondColour));
				// $(paneRef + ' > .paneHeader').css("color", '#ffffff');
				// $(paneRef + ' > .paneHeader').css("color", ColourComplement( ColourValue(firstColour, secondColour) ) );
				
                OpenTile(tileRef, false, tileWidth);

                lastTile = $(tileRef).get(0);
                lastPane = $(paneRef).get(0);
                lastPaneIsOpen = true;
                SetHash($(this).attr("title"));
               

                if( colourModeIndex < 2 ) {
					// set the pane's colour to the next colour
					ChooseNextColours();					
					$(paneRef).css("background-color", ColourValue(firstColour, secondColour));
					// set the pane header's colour to the pane's colour complement
					$(paneRef + ' > .paneHeader').css("background-color", ColourComplement(ColourValue(firstColour, secondColour)));
					
				}
				else {
					// no background color for the pane header so reverse the background and fore colours
					$(paneRef + " > .paneHeader ").css("background-color", defaultColour);
					$(paneRef + " > .paneHeader ").css("color", defaultBackgroundColour);

                }				
				
                return false;
            }
            else if (this.id != "ext" ) { // panel and tile events
                currTileInfo = this.innerHTML;
                var currentCaption = $(this).attr("title");
                var captionRef = "#" + $(this).parent().parent().parent().get(0).id + " > .caption";
                var tileWidth = $("." + $(this).attr("class") + " > img").width();

                if (tileWidth == undefined || tileWidth < 1) {
                    tileWidth = options.maximumWidth;
                }

                if (currentCaption.length < 1) {
                    currentCaption = defaultCaption;
                }

                if (lastTile == undefined) {
                    // all tiles are closed
                    OpenTile(this, false, tileWidth);
                    SetCaption(captionRef, currentCaption, true);
                    lastTile = this;
                    SetHash($(this).attr("class"));
                }
                else {
                    CloseTile(lastTile, false);
                    if (lastTile != this) {
                        OpenTile(this, false, tileWidth);
                        SetCaption(captionRef, currentCaption, true);
                        SetHash($(this).attr("class"));
                        lastTile = this;
                    }
                    else {
                        SetCaption(captionRef, defaultCaption, true);
                        RemoveHash();
                        lastTile = undefined;
                    }
                }

                if (colourModeIndex < 1) {
                    ChooseNextColours();
                }

                // stop any pane animation
                return false;
            } // otherwise the link is external so redirect 

        });

        /*
         *	hover actions
         */
        $(".paneHeader").hover(
			function() {
			    hoverCount += 1;
			    ShowActionCount();
			    //$(this).addClass(this.id).fadeIn();		
			    if (colourModeIndex < 2) {
					ChooseNextColours();
			        $(this).css("background-color", ColourValue(firstColour, secondColour));
			        //ChooseNextColours();
			        // $(this).css("color", ColourValue(firstColour, secondColour));
					// $(this).css("color", ColourComplement(ColourValue(firstColour, secondColour)));
					$(this).css("color", defaultColour);
			        
			    }
			},
			function() {
			    //$(this).removeClass(this.id);
			    if (colourModeIndex > 0) {
			        //if( !lastPaneIsOpen ) {
			        $(this).css( 'background-color', defaultColour);
			        $(this).css( 'color', defaultBackgroundColour);
			        //}
			    }
			}
		);

        $("a").hover( function() {
			    hoverCount += 1;
			    ShowActionCount();
			    //$(this).addClass(this.id).fadeIn();		
			    if (colourModeIndex < 2) {
			        //$(this).css( "background-color" , ColourValue( firstColour , secondColour ) );
			        ChooseNextColours();
			        // $(this).css( "color" , ColourValue( firstColour , secondColour ) );
			        // ChooseNextColours();
			    }
			} /*,
			function() {
				//$(this).removeClass(this.id);
				if( colourModeIndex > 0 ) {
					//if( !lastPaneIsOpen ) {
						$(this).css( "background-color" , defaultColour );
						$(this).css( "color", "#a6a6a6" );
					//}
				}
			}*/
		);

        /*
         *	calculate a colour value
         */
        ColourValue = function(colour1, colour2) {
            var s = "000000" + ((colour1 + colour2) % colourThreshold).toString(16);
            var len = s.length;
            s = s.substr(len - 6, 6);
            //if( colour1 + colour2 > 255 )

            return "#" + s;
        }

        /*
         *	return a hex colours colours complement
         */
        ColourComplement = function(hexColourValue) {
            
            hexColourValue = hexColourValue.toString().replace('#', '');

            var hexR, hexG, hexB;
            var r, g, b;
            var compR, compG, compB;
            var min, max, delta;
            var hue, saturation, luminosity;
            var compHue;
            var deltaR, deltaG, deltaB;
            var v1, v2, vh;

            hexR = hexColourValue.toString().substr(0, 2);
            hexG = hexColourValue.toString().substr(2, 2);
            hexB = hexColourValue.toString().substr(4, 2);

            r = parseInt(hexR, 16) / 255;
            g = parseInt(hexG, 16) / 255;
            b = parseInt(hexB, 16) / 255;

            min = Math.min(r, g, b);
            max = Math.max(r, g, b);
            delta = max - min;

            // determine the luminosity value
            luminosity = (max + min) / 2;

            if (delta == 0) {
                hue = 0;
                saturation = 0;
            }
            else {
                // determine the saturation value
                if (luminosity < 0.5) {
                    saturation = delta / (max + min);
                }
                else {
                    saturation = delta / (2 - max - min);
                }

                deltaR = (((max - r) / 6) + (delta / 2)) / delta;
                deltaG = (((max - g) / 6) + (delta / 2)) / delta;
                deltaB = (((max - b) / 6) + (delta / 2)) / delta;

                // determine the hue value
                if (r == max) {
                    hue = deltaB - deltaG;
                }
                else if (g == max) {
                    hue = (1 / 3) + deltaR - deltaB;
                }
                else if (b == max) {
                    hue = (2 / 3) + deltaG - deltaR;
                }

                if (hue < 0) {
                    hue += 1;
                }

                if (hue > 1) {
                    hue -= 1;
                }

                
            }
            //alert( 'hue: ' + hue + ' | saturation: ' + saturation + ' | luminosity: ' + luminosity );
            compHue = hue + 0.5;

            if (compHue > 1) {
                compHue -= 1;
            }

            // start converting back...
            if (saturation == 0) {
                compR = luminosity * 255;
                compG = luminosity * 255;
                compB = luminosity * 255;
            }
            else {
                if (luminosity < 0.5) {
                    v2 = luminosity * (1 + saturation);
                }
                else {
                    v2 = (luminosity + saturation) - (saturation * luminosity);
                }
            }
            v1 = 2 * luminosity - v2;
            compR = 255 * HueToRGB(v1, v2, compHue + (1 / 3));
            compG = 255 * HueToRGB(v1, v2, compHue);
            compB = 255 * HueToRGB(v1, v2, compHue - (1 / 3));
			
			var len;
			hexR = '0' + Math.round(compR).toString(16);
			len = hexR.length;
			hexR = hexR.substr( len - 2 , 2 );
			
			hexG = '0' + Math.round(compG).toString(16);
			len = hexG.length;
			hexG = hexG.substr( len - 2 , 2 );
			
			hexB = '0' + Math.round(compB).toString(16);
			len = hexB.length;
			hexB = hexB.substr( len - 2 , 2 );
			
            //alert( 'r: ' + hexR + ' | g: ' + hexG + ' | b: ' + hexB );
            return '#' + hexR + hexG + hexB;
        }

        /*
         *	convert hue to rgb
         */
        HueToRGB = function(v1, v2, vh) {
            if (vh < 0) {
                vh += 1;
            }
            if (vh > 1) {
                vh -= 1;
            }
            if ((6 * vh) < 1) {
                return (v1 + (v2 - v1) * 6 * vh);
            }
            if ((2 * vh) < 1) {
                return v2;
            }
            if ((3 * vh) < 2) {
                return (v1 + (v2 - v1) * ((2 / 3 - vh) * 6));
            }
            return v1;
        }

        /*
         *	close a tile
         */
        ChooseForeColour = function(colour) {
            if (colour > (colourThreshold / 2)) {
                return "#FFFFFF";
            }
            else {
                return "#000000";
            }
        }

        /*
         *	close a tile
         */
        ChooseNextColours = function() {

            var tempColour = secondColour;
            secondColour += firstColour;
            firstColour = tempColour;
			
            if (!isFinite(firstColour) || !isFinite(secondColour) || !isFinite(firstColour + secondColour)) {
			
                firstColour = 89;
                secondColour = 144;
            }
        }

        /*
         *	close a tile
         */
        CloseTile = function(tile, queueAnimation) {
            $(tile).animate({ width: options.minimumWidth + "px" }, { queue: queueAnimation, duration: options.duration });
            HideMessage();
        }

        /*
         *	close a pane
         */
        ClosePane = function(pane, queueAnimation) {
            $(pane).animate({ height: options.minimumHeight + "px" }, { queue: queueAnimation, duration: options.duration });
			lastPane = undefined; 
			lastPaneIsOpen = false; 
            HideMessage();
        }

        /*
         *	get the next colour value
         */
        GetNextColourValue = function(colour1, colour2) {
            var tempColour = colour2;
            colour2 += colour1;
            colour1 = tempColour;
            return ColourValue(colour1, colour2);
        }

        /*
         *	handle pane events
         */
        HandlePaneEvents = function(base, changeColours) {

            //clickCount += 1;

            // the open pane is to be closed
            if (lastPane == base && lastPaneIsOpen == true) {
                // close all tiles in the currently opened pane before closing the pane
                CloseTile("#" + base.id + " > ul > li > a", false);                
                SetCaption("#" + base.id + " .caption", defaultCaption);
                RemoveHash();
                lastTile = undefined;

                ClosePane(lastPane, false);

                if (colourModeIndex < 2) {
                    ChooseNextColours();
                }
            }
            else { // a pane different from the previous one was clicked
                
                if (changeColours) {
                    if (colourModeIndex < 2) {
                        //$(base).css("background-color", ColourValue(firstColour, secondColour));
						$( base ).css( 'background-color' , ColourComplement( ColourValue(firstColour, secondColour) ) );
						$(base).css("color", '#ffffff');
                    }
                    else {
                        $(base).css( 'background-color' , defaultBackgroundColour);
                        $(base).css( 'color' , defaultColour);
                    }
                }

                if (lastPane != undefined) // a pane was previously open...
                {
                    // ...so close all tiles in the last opened pane
                    $("#" + lastPane.id + " > ul > li > a").animate({ width: options.minimumWidth + "px" }, { queue: false, duration: options.duration });
                    SetCaption("#" + lastPane.id + " > .caption", defaultCaption);
                    lastTile = undefined;
                    
                    ClosePane(lastPane, false);
                }

                // open the pane...
               
                OpenPane(base, false);

                if (lastTile == undefined) // the last tile was not in this pane...
                {
                    // ...so wait (this is a bit of a band-aid pause)...
                    $("#" + base.id + " > ul > li:first > a").animate({ opacity: 1.0 }, options.duration)
                }

                // ...and mark this pane as the last one opened...
                lastPane = base;
                lastPaneIsOpen = true;
                //paneJustOpened = true; 

                // ...and open the first tile
                var tileWidth = $("#" + base.id + " > ul > li:first > a > img").width();
                OpenTile("#" + base.id + " > ul > li:first > a", true, tileWidth);
                var currentCaption = $("#" + base.id + " > ul > li:first > a").attr("title");

                if (currentCaption == undefined) {
					currentCaption = defaultCaption;                    
                }
				else if (currentCaption.length < 1) {		
					currentCaption = defaultCaption;
                }

                SetCaption("#" + base.id + " > .caption", currentCaption);

                var hash = $("#" + base.id + " > ul > li:first > a").attr("class");

                if (hash != undefined) {
                    if (hash.length > 0) {
                        SetHash($("#" + base.id + " > ul > li:first > a").attr("class"));
                    }
                }

                lastTileInfo = $("#" + base.id + " > ul > li:first > a").attr("innerHTML");
                lastTile = $("#" + base.id + " > ul > li:first > a").get(0);
            }
        }

        /*
         *	hide messages
         */
        HideMessage = function() {
            //$("#messages").attr( "innerHTML" , "" );
            $("#messages").fadeOut(options.duration);
			//$("#messages").animate({ opacity: 0.5 }, options.duration )
        }

        /*
         *	open a tile
         */
        OpenTile = function(tile, queueAnimation, maxWidth) {
            var w = options.maximumWidth;

            if (maxWidth != undefined) {
                if (maxWidth > 0) {
                    w = maxWidth;
                }
            }

            $(tile).animate({ width: w + "px" }, { queue: queueAnimation, duration: options.duration });
			
			lastTile = $(tile);
        }

        /*
         *	open a pane
         */
        OpenPane = function(pane, queueAnimation) {
			/*// var h = 0; //= options.maximumHeight; 
			// var currHeight = 0;
			// if( $(pane).attr( 'class' ) == 'infoPane' ){
				// if( $(pane).attr( 'id' ) == 'newsPane' ) {
					// h = $(pane).find( 'table' ).height() ;
				// }
			// }
			// else if( $(pane).attr( 'class' ) == 'pane' ) {
				// $( '#' + pane.id + ' > ul > li ' ).each( function( index ) {
					// currHeight = ( $('#' + pane.id + ' > ul > li:nth-child(' + (index + 1) + ') > a > img' ).attr('height') );
					
					// if( currHeight > h ) {
						// h = currHeight;
					// }
				// });
				
			// }
			// else {
				// alert( 'none' );
			// }
			
			// h += $( '#' + pane.id + ' > .paneHeader' ).height() + 2 * options.paneHeaderHeight;
			
			// $(pane).animate({ height: Math.max( h , currHeight ) + "px" }, { queue: queueAnimation, duration: options.duration });*/
			$(pane).animate({ height: options.maximumHeight + "px" }, { queue: queueAnimation, duration: options.duration });
			
			lastPane = $(pane).get(0);
			lastPaneIsOpen = true;
        }

        /*
         *	open a tile
         */
        RemoveHash = function() {
            window.location.hash = "";
        }

        /*
         *	set a tile's caption
         */
        SetCaption = function(captionRef, caption, changeColours) {
            if ( changeColours && colourModeIndex < 2 ) {
				if( captionRef != undefined ) {				
					ChooseNextColours();
				}
            }

            if (caption != undefined) {
                if (caption.length > 0) {
                    $(captionRef).html(caption).fadeIn(options.duration);
                    $(captionRef).attr("title", caption);
                }
            }
        };

        // Taken from AJAXY jquery.history Plugin
        SetHash = function(hash) {
            // Write hash
            if (typeof window.location.hash != 'undefined') {
                if (window.location.hash != hash) {
                    window.location.hash = hash;
                };
            } else if (location.hash != hash) {
                location.hash = hash;
            };

            // Done
            return hash;
        };
        // <-- End AJAXY code

        /*
         *	display action count
         */
        ShowActionCount = function() {
            $("#actions").attr("innerHTML", hoverCount + clickCount);
        }

        /*
         *	show messages
         */
        ShowMessage = function(msg) {
            $("#messages").attr("innerHTML", msg);
            $("#messages").fadeIn(options.duration);
        }

        /*
         *	show permalink
         */
        ShowPermaLink = function(msg) {
            ShowMessage(msg);
        }

		/*
         *	return a random number
         */
        RandomNumber = function( upperBound ) {
			return Math.floor( Math.random() * upperBound );
		}
		
        /*
         *	open up the pane and tile a bookmarked image is in
         */
        GoToBookmark = function() {

            var ref = window.location.hash.substr(1);
			var showImage = false; 
			
            if (ref.length > 0) {
                var className = "." + ref;
                tileRef = "#" + $(className).parent().parent().parent().attr("id") + " > ul > li > " + className;
				showImage = true;
            }
			else {				
				var showRandomImage = true;		
				// var n = 11;
				// if( RandomNumber( n ) > 5 ) {
					// showRandomImage = true;
				// }
				
				if( showRandomImage ) {
					n = RandomNumber( $( '.pane > ul > li > a' ).length );					
					var className = "." + $( '.pane > ul > li > a' ).eq( n ).attr( 'class' );
					tileRef = "#" + $(className).parent().parent().parent().attr("id") + " > ul > li > " + className;
					showImage = true;
					SetHash( $( tileRef ).attr( 'class' ) );					
				}				
			}
			
			if( showImage ) {
				// tileRef should have been set 
				var currentCaption = $(tileRef).attr("title");
                var paneRef = "#" + $(className).parent().parent().parent().attr("id");
                $(paneRef).css("background-color", defaultBookmarkedBackgroundColour);
				$(paneRef).css('color' , '#ffffff');

                var tileWidth = $(tileRef + " > img").width();

                $(className).parent().parent().parent().animate({ height: options.maximumHeight + "px" }, { queue: true, duration: options.duration });

                OpenTile(tileRef, true, tileWidth);
                lastTile = $(tileRef).get(0);
                lastPane = $(paneRef).get(0);
                lastPaneIsOpen = true;
                SetCaption(paneRef + " > .caption ", currentCaption);
				
			}
            return true;
        };

		
		
        // if a hash / bookmark link has been provided, go to it. 
        HideMessage();
        //SelectColourMode();
        
        // wait until all images have loaded 
	$(window).load(function () {
		GoToBookmark();
	})

    }
})(jQuery);