$.extend(Function.prototype, {
    use: function() {
		var method = this, args = Array.prototype.slice.call(arguments), object = args.shift();
		return function() {
			return method.apply(object, args.concat(Array.prototype.slice.call(arguments)));
		}
    }
});

$.extend(String.prototype, {
    truncate: function(length, truncation) {
        length = length || 30;
        truncation = (!truncation) ? '...' : truncation;
        return (this.length > length) ? this.slice(0, length - truncation.length) + truncation : String(this);
    }
});

// animated link hovers
var JSHover = function(el) {
	if(
	    $(el).parents('#albums, #images, #projects').length 
	    && el.nodeName.toLowerCase() != 'span' 
	    || $(el).parents('#tagline').length
	) { return; }
	
	this.isThumb = (
	    ($(el).parents('#albums, #images, #projects').length && el.nodeName.toLowerCase() == 'span') 
	    || $(el).parents('#nav, #backtotop, .commentCount, #header, .simpleShow').length
	    || $(el).hasClass('twitter')
	    || $(el).hasClass('more')
	    || $(el).hasClass('btn')
	);
	this.noFade = ($(el).children('img').length || el.nodeName.toLowerCase() == 'input');
	
	this.el = $(el).bind('mouseover', this.hoverOn.use(this)).bind('mouseout', this.hoverOff.use(this));
    this.css = {
        opacity: this.el.css('opacity'),
        bgColor: this.el.css('background-color'),
        startBgColor: (this.el.css('background-color') != 'transparent') ? this.el.css('background-color') : '#FFF',
        toBgColor: (this.el.parents('#nav, #albums').length) ? this.el.css('background-color') : '#3A57AB',
        color: this.el.css('color'),
        highOpacity: 0.9,
        lowOpacity: 0.7
    };
    if(this.isThumb) {
        this.css.highOpacity = 0.9;
        this.css.lowOpacity = 0.85;
    }
    
    if(this.el.parents('#content, #sidebar').length && !this.el.parents('.simpleShow').length && !this.el.hasClass('btn')) {
        this.returnBgColor = true;
    }
    
	this.timer;
};
$.extend(JSHover.prototype, {
    hoverOn: function(e) {
        var newOpacity = (this.el.css('opacity') < this.css.highOpacity) ? 1 : this.css.lowOpacity;
		if(this.timer) { clearTimeout(this.timer); }
		if(!this.isThumb && !this.noFade) {
            this.el.stop().css({ backgroundColor: this.css.startBgColor, color: '#3A57AB' })
                .addClass('hovered')
                .animate({ backgroundColor: '#3A57AB', color: '#FFF' }, 500, 'easeInOutSine', function() { 
                    this.animate(); 
                }.use(this));
		} else if(this.isThumb) {
		    this.el.stop().css({ opacity: 0 })
                .addClass('hovered')
                .animate({ opacity: newOpacity }, 500, 'easeOutSine', function() { 
                    this.animate(); 
                }.use(this));
		} else {
            this.animate(); 
		}
    },
    animate: function() {
        var newOpacity = (this.el.css('opacity') < this.css.highOpacity) ? 1 : this.css.lowOpacity;
        this.el.animate({opacity: newOpacity}, 500, 'easeInOutSine', function() { this.animate(); }.use(this));
    },
    hoverOff: function(e) {
        this.timer = setTimeout(function() {
            var css = { opacity: this.css.opacity, color: this.css.color }
            if(this.returnBgColor) {
                css.backgroundColor = this.css.bgColor;
            }
            this.el.stop().animate(css, 500, 'easeInOutSine', function() { 
                this.el.removeClass('hovered').css({ backgroundColor: this.css.bgColor, color: this.css.color }); 
            }.use(this));
        }.use(this), 500);
    }
});

// custom tooltips
var Tooltip = function(el) {
    this.el = el;
    
    this.title = this.el.attr('title') || '';
    this.alt = this.el.attr('alt') || '';

    if(this.title) { this.el.attr('title', ''); }
    if(this.alt) { this.el.attr('alt', ''); }

    this.content = this.title || this.alt;
    
    this.el.bind('mouseover.tooltip', this.show.use(this));
};
$.extend(Tooltip.prototype, {
    show: function(e) {
        this.tip = $('<div class="tooltip">'+this.content+'</div>').appendTo('body').css({opacity: 0});
        this.move(e);
        this.el.bind('mouseout.tooltip', this.hide.use(this)).bind('mousemove.tooltip', this.move.use(this));
        this.timeout = setTimeout(function() {
            this.tip.animate({opacity: 0.9}, 500, 'easeInOutSine');
        }.use(this), 1000);
    },
    move: function(e) {
        var leftOffset = (!$('body').offset().left) ? $('body').css('marginLeft').replace('px', '') : $('body').offset().left;
        var topOffset = (!$('body').offset().top) ? $('body').css('marginTop').replace('px', '') : $('body').offset().top;
        
        var leftRelative = (this.tip.width()+e.pageX > parseInt(leftOffset, 10)+$('body').width()) ? e.pageX-this.tip.width()-10 : e.pageX+10;
        var topRelative =  (e.pageY-this.tip.height() > parseInt(topOffset, 10)+$(document).scrollTop()) ? e.pageY-this.tip.height()-10 : e.pageY+this.tip.height()+10;
        
        this.tip.css({ top: topRelative-topOffset, left: leftRelative-leftOffset });
    },
    hide: function(e) {
        clearTimeout(this.timeout);
        this.el.unbind('mousemove.tooltip').unbind('mouseout.tooltip');
        this.tip.fadeOut(200, function() { this.tip.remove(); }.use(this));
    }
});
$.extend(Tooltip, {
    tooltips: []
});

$(document).ready(function() {
    // Check if someone is trying to pull my site in with an iframe
    // Break out if so.
    if (top != self) {
        top.location.replace(self.location.href);
    }

    // smooth scrolling for hash links
    // http://www.learningjquery.com/2007/10/improved-animated-scrolling-script-for-same-page-links
    function filterPath(string) {
        return string
        .replace(/^\//,'')
        .replace(/(index|default).[a-zA-Z]{3,4}$/,'')
        .replace(/\/$/,'');
    }
    var locationPath = filterPath(location.pathname);
    $('a[href*=#]').each(function() {
        var thisPath = filterPath(this.pathname) || locationPath;
        if( locationPath == thisPath && (location.hostname == this.hostname || !this.hostname) && this.hash.replace(/#/, '') ) {
            var $target = $(this.hash), target = this.hash;
            if( $target.length ) {
                $(this).click(function(event) {
                    event.preventDefault();
                    var targetOffset = $target.offset().top;
                    $('html, body').animate({scrollTop: targetOffset}, 500, 'easeInOutSine', function() {
                        location.hash = target;
                        $target.css('-webkit-border-radius', '3px').css('-moz-border-radius', '3px').css('border-radius', '3px').animate({backgroundColor: '#C6CFEB'}, 200, 'easeInSine', function() {
                            $target.animate({backgroundColor: '#FFFFFF'}, 1000, 'easeOutSine');
                        });
                    });
                });
            }
        }
    });
    
    $('#nav a').each(function() {
        if(!$(this).hasClass('current')) { $(this).append('<span></span>').addClass('jshover'); }
    });
    $('#logo a').append('<span></span>').addClass('jshover');
    $('#header a span, span.title').css({ visibility: 'visible', opacity: '0' });
    $('#header a span, #crumbs a, #footer a, #images span.title, #albums span.title, #projects span.title, #sidebar a, #content a, input[type="submit"], input[type="reset"], a.img span.img').each(function() {
		$(this).data('jshover', new JSHover(this));
	});
    /* Zach thinks this is the most annoying thing ever
	$('input').focus(function() { 
		$(this).parents('form').find('input[type=submit]').data('jshover').animate();
	}).blur(function() {
		$(this).parents('form').find('input[type=submit]').data('jshover').hoverOff();
	});
	*/
	$('input, textarea, select').focus(function() { 
		$(this).siblings('label').addClass('current');
	}).blur(function() {
		$(this).siblings('label').removeClass('current');
	});
	
    $('a, abbr, acronym, img').each(function() {
        if($(this).attr('title') || $(this).attr('alt')) { Tooltip.tooltips.push(new Tooltip($(this))); }
    });
    
    $('body').append('<div class="ad banner"><img src="/images/advertisement.gif" /></div>');
        
    $(document).bind('imgloaded', function() {
        if($('img').length == imgsloaded) {
            $(document).trigger('imgsloaded');
        }
    });
    var imgsloaded = 0;
    var adsBlocked = false;
    // randomly fade images in around the page
    $('img').each(function() {
        if(this.src.indexOf('advertisement') != -1) { 
            imgsloaded++; 
            $(document).trigger('imgloaded'); 
            adsBlocked = true;
            return; 
        } 
        var img = new Image();
        img.onload = function() {
			// force a random delay
			setTimeout(function() {
	            $(this).wrap('<span class="img"></span>').parent('.img').css({ 
	                'background-image': 'url('+$(this).attr('src')+')',
	                'width': $(this).width(),
	                'height': $(this).height(),
	                'opacity': 0 
	            }).animate({opacity: '1'}, 500, function() {
	                imgsloaded++;
	                $(document).trigger('imgloaded');
	            }).parent('a').addClass('img');
			}.use(this), Math.floor((Math.random()*1000)/2))
        }.use(this);
        img.src = $(this).attr('src');
    });
    
    if(adsBlocked && $('.flash').length) {
        setInterval(function() {
            $('a[class*="abp-objtab"]').remove();
        }, 500)
    }
    
    // homepage animations
    $('p#tagline a').bind('mouseover', function() { 
        $(this).stop().animate({ color: '#3A57AB' }, 5000, 'easeInOutSine'); 
    }).bind('mouseout', function() { 
        $(this).stop().animate({ color: '#FFFFFF' }, 1000, 'easeOutSine'); 
    });
	$('p#tagline span').animate({ color: '#3A57AB' }, 20000, 'easeInOutSine').animate({ color: '#FFFFFF' }, 5000, 'easeOutSine');
    
    //if($.browser.msie && DD_roundies) {
    //    DD_roundies.addRule('span.img', 6, false);
    //    DD_roundies.addRule('span.title', 6, false);
    //    DD_roundies.addRule('dl.meta', 6, false);
    //    DD_roundies.addRule('a', 3, false);
    //}
        
    var formMove;
    function calcTop() {
        if($('#commentForm').position().top <= $(document).scrollTop() || $('#commentForm').position().top >= $('#comments').position().top) {
            var newTop = ($(document).scrollTop() > $('#comments').position().top) ? $(document).scrollTop() : $('#comments').position().top;
            if(
                $('#commentForm').height()+newTop >= $(document).height()-$('#footer').height() &&
                newTop >= $('#comments').position.top+$('#commentForm').height()-60
            ) {
                newTop = newTop-60;
            }
            return newTop;
        }
    }
    
    function moveForm() {
        clearTimeout(formMove);
        $('#commentForm').css('top', $('#commentForm').position().top+'px');
        var dist = calcTop();
        if(
            ($('#commentForm').position().top <= $(document).scrollTop() 
            || $('#commentForm').position().top >= $('#comments').position().top)
            && dist+$('#commentForm').height() < $(document).height()
        ) {
            formMove = setTimeout(function() {
                var time = (dist/0.6);
                $('#commentForm').dequeue().animate({top: calcTop()+'px'}, time, 'easeInOutQuart');
            }, 300);
        }
    }
    
    if($('#commentForm').length) {
        $(document).bind('scroll', moveForm);
        var commentingInterval;
        $('#commentContent').bind('focus', function() {
            clearInterval(commentingInterval);
            commentingInterval = setInterval(function() {
                if($('#commentContent').scrollTop()) {
                    $('#commentContent').height($('#commentContent').height()+20);
                }
            }, 50);
        }).bind('blur', function() {
            clearInterval(commentingInterval);
        });
    }
    
    if(typeof sh_highlightDocument == 'function') {
        sh_highlightDocument();
    }
    
    // special bullets for lists
    $('.post ul li, .nonsense ul li, ul.errors li, .copy ul li').each(function() {
        if($(this).hasClass('stalker')) { return; }
        $(this).prepend('<span class="bullet"></span>');
    });
    $('.post ol, .nonsense ol, .copy ol').each(function() {
        var count = 1;
        $(this).find('li').each(function() {
            $(this).prepend('<span class="bullet">'+count+'</span>');
            count++;
        });
    });
    
    if($('#searchInput').length) {
        $('#searchInput').data('val', $('#searchInput').attr('value')).focus(function() {
            if($(this).attr('value') == $(this).data('val')) {
                $(this).attr('value', '');
            }
        }).blur(function() {
            if($(this).attr('value') == '') {
                $(this).attr('value', $(this).data('val'));
            }
        });
    }
    
    $('#UserLoginForm').hide();
    $('#showLoginForm').click(function(e) {
        e.preventDefault();
        e.stopPropagation();
        $('#UserLoginForm').slideDown(500);
    });
    
	if (typeof pageTracker != 'undefined') {
	    // Outbound Links
	    $('a').each(function() {
	        var href = $(this).attr('href');
	        if( href.match('http://|https://') && href.indexOf(window.location.hostname) == -1) {
	            $(this).bind('click', function() {
    	            pageTracker._trackEvent('Outbound Link', $(this).attr('href'), window.location.pathname);
	            });
	        }
	    });
	    
	    // Downloads
        $('a.download').each(function() {
    		if($(this).attr('href').match(/[.](\w+)$/)) { 
				$(this).bind('click', function(event) {
					pageTracker._trackEvent('Downloads', $(this).attr('href'), $(this).text());
				});
    		}
        });
        
        // Copy Keyboard Shortcut
        function trackCopyEvent(type, selection) {
            pageTracker._trackEvent('Copy', type, selection);
        }
        
    	$(document).bind('keypress', function(event) { // Safari and Firefox
            if( (event.charCode == 99 && (event.metaKey || event.ctrlKey) ) && window.getSelection ) {
                var selection = String(window.getSelection() + '').truncate(60);
    	        trackCopyEvent('text', selection);
    	    }
    	});
    	$(document).bind('keyup', function(event) { // Opera Windows and Internet Explorer
            if( event.keyCode == 67 && event.ctrlKey ) {
                if( document.getSelection ) { // Opera Windows
    	            var selection = document.getSelection().truncate(60);
        	        trackCopyEvent('text', selection);
    	        } else if( document.selection ) { // Internet Explorer
    	            var selection = document.selection.createRange().text.truncate(60);
        	        trackCopyEvent('text', selection);
    	        } 
    	    }
    	});
    	
    	// Context Menu
    	$(document).bind('contextmenu', function(event) {
    	    if(event.target.nodeName == 'img' || $(event.target).hasClass('img')) {
    	        var image = $(event.target).attr('src') || $(event.target).css('background-image').replace('url(', '').replace(')', '');
    	        trackCopyEvent('image', image.replace('/"/g', ''));
    	    }
    	});
        
        // Browser Dimensions
	    pageTracker._trackEvent('Browser Dimensions', 'load', $(window).width() + 'x' + $(window).height(), $(window).width());
        $(window).resize(function () {
            if ($(this).data('gatimer')) {
                clearTimeout($(this).data('gatimer'));
                $(this).data('gatimer', null);
            }

            $(this).data('gatimer', 
                setTimeout(function () {
                    pageTracker._trackEvent('Browser Dimensions', 'resize', $(window).width() + 'x' + $(window).height(), $(window).width());
                }, 500)
            );
        });
	}
	
});
