
/**
 * @see http://plugins.jquery.com/project/tipsy, http://onehackoranother.com/projects/jquery/tipsy
 */
(function($) {
    $.fn.tips = function(options) {

        options = $.extend({}, $.fn.tips.defaults, options);
        
        return this.each(function() {
            
            var opts = $.fn.tips.elementOptions(this, options);
            
			var tip = $(this).data('active.tip');
			if (!tip) {
				tip = $('<div class="tip"><div class="tip-inner"/></div>');
				tip.css({position: 'absolute',left:'-9999px', zIndex: 100000});				
				$(this).data('active.tip', tip);
			}

			if ($(this).attr('title') || typeof($(this).data('title')) != 'string') {
				$(this).data('title', $(this).attr('title') || '').removeAttr('title');
			}
			
			$(this)
				.bind('showTip', function(){
			
				//.hover(function(){
					var tip = $(this).data('active.tip');
					
					$(this).data('cancel.tip', true).addClass('active');					

					var title;
					if (typeof opts.title == 'string') {
						title = opts.title;
						if(opts.title == 'title') title = $(this).data('title');							
					} else if (typeof opts.title == 'function') {
						title = opts.title.call(this);
					}

					tip.find('.tip-inner')[opts.html ? 'html' : 'text'](title || opts.fallback);

					var pos = $.extend({}, $(this).offset(), {width: this.offsetWidth, height: this.offsetHeight});
					tip.get(0).className = 'tip'; // reset classname in case of dynamic gravity
					if(opts.tipCSS) tip.css(opts.tipCSS);
					tip.css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
					var actualWidth = tip[0].offsetWidth, actualHeight = tip[0].offsetHeight;
					var gravity = (typeof opts.gravity == 'function') ? opts.gravity.call(this) : opts.gravity;

					switch (gravity.charAt(0)) {
						case 'n':
							tip.css({top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}).addClass('tip-north');
							break;
						case 's':
							tip.css({top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}).addClass('tip-south');
							break;
						case 'e':
							tip.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}).addClass('tip-east');
							break;
						case 'w':
							tip.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}).addClass('tip-west');
							break;
					}

					if (opts.fade) {
						tip.css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: 0.8});
					} else {
						tip.css({visibility: 'visible'});
					}
				})
				.bind('hideTip', function(){					
					var self = this;
					//clearTimeout($(this).data('active.tip.timeout'));
					$(this).data('cancel.tip', false);
					function _hideTip(){						
						if ($(self).data('cancel.tip')) return;
						$(self).removeClass('active');
						var tip = $(self).data('active.tip');						
						if(!tip || !tip.length) return;
						if (opts.fade) {
							tip.stop().fadeOut(function() { $(this).hide(); });
						} else {
							tip.hide();
						}
					}

					if(!opts.sticky)						
						$(this).data('active.tip.timeout', setTimeout(_hideTip, 200));
					else
						_hideTip();					
				});
			
			$.data(this, 'cancel.tip', false);
			
			var self = this;	
			
			if(!opts.sticky){				
				$(this).hover(
					function(){ $(this).triggerHandler('showTip'); }, 
					function(){ $(this).triggerHandler('hideTip'); }
				);
				
				$(self).data('active.tip').hover(
					function(){ clearTimeout($(self).data('active.tip.timeout'));  }, 
					function(){ $(self).trigger('hideTip'); }
				);
				
			}else{
				$(this).click(function(){					
					if($.data(this, 'cancel.tip'))
						$(this).triggerHandler('hideTip');
					else 
						$(this).triggerHandler('showTip');
					return false;	
				});
			}
			//$(this).bind('mouseover')
			
            //$(this).hover( $(this).trigger('show'), $(this).trigger('hide'));
            
        });
        
    };
    
    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tips-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tips-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tips.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };
    
    $.fn.tips.defaults = {
        sticky: false,
		fade: false,
        fallback: '',
        gravity: 'n',
        html: false,
        title: 'title'
    };
    
    $.fn.tips.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };
    
    $.fn.tips.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };
    
})(jQuery);

 
 


jQuery.fn.print = function(){
	if (!this.length|| !window.print) return;
		
	var tmpFrame = $('<iframe>').attr('name',('tmpFrame'+(new Date()).getTime()));
	
	tmpFrame.css({
		'width': 	'1px',
		'height': 	'1px',
		'position': 'absolute',
		'left':		'-9999px'
	}).appendTo(document.body);
	
	var tmpFrameDoc = (window.frames[tmpFrame[0].name]).document, tmpFrameStyles = $('<div>').append($("style").clone());

	tmpFrameDoc.open();
	tmpFrameDoc.write(([
		'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"',
		'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
		'<html>',
		'<head>',
		'<title>',document.title,'</title>',
		tmpFrameStyles.html(),		
		'</head>',
		'<body onload="window.focus();window.print();">',
		$(this).html().replace(/<!(?:--[\s\S]*?--\s*)?>\s*/g,'').replace(/<(iframe|script|noscript|object|embed)\b[^>]*>[\s\S]*?<\/\1>/ig,''),
		'</body>',
		'</html>'
	]).join(''));
	tmpFrameDoc.close();
	
	setTimeout(function(){tmpFrame.remove()},30000);
	
	return;
};



/*! Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * Version: 3.0.2
 * 
 * Requires: 1.2.2+
 */

(function($) {

	var types = ['DOMMouseScroll', 'mousewheel'];

	$.event.special.mousewheel = {
		setup: function() {
			if ( this.addEventListener )
				for ( var i=types.length; i; )
					this.addEventListener( types[--i], handler, false );
			else
				this.onmousewheel = handler;
		},
		
		teardown: function() {
			if ( this.removeEventListener )
				for ( var i=types.length; i; )
					this.removeEventListener( types[--i], handler, false );
			else
				this.onmousewheel = null;
		}
	};

	$.fn.extend({
		mousewheel: function(fn) {
			return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
		},
		
		unmousewheel: function(fn) {
			return this.unbind("mousewheel", fn);
		}
	});


	function handler(event) {
		var args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true;
		
		event = $.event.fix(event || window.event);
		event.type = "mousewheel";
		
		if ( event.wheelDelta ) delta = event.wheelDelta/120;
		if ( event.detail     ) delta = -event.detail/3;
		
		// Add events and delta to the front of the arguments
		args.unshift(event, delta);

		return $.event.handle.apply(this, args);
	}

})(jQuery);


/**
 * Mapbox, the jQuery Map
 * jQuery Map Plugin
 * Version 0.6.0 beta
 * Author Abel Mohler
 * Released with the MIT License: http://www.opensource.org/licenses/mit-license.php
 */
(function($) {// jQuery.noConflict compliant
    $.fn.mapbox = function(o, callback) {
        var defaults = {
            zoom: true, // does map zoom?
            pan: true, // does map move side to side and up to down?
            defaultLayer: 0, // starting at 0, which layer shows up first
            layerSplit: 4, // how many times to split each layer as a zoom level
            mapContent: ".mapcontent", // the name of the class on the content inner layer
            defaultX: null, // default positioning on X-axis
            defaultY: null, // default positioning on Y-axis
            zoomToCursor: true, // if true, position on the map where the cursor is set will stay the same relative distance from the edge when zooming
            doubleClickZoom: false, // if true, double clicking zooms to mouse position
            clickZoom: false, // if true, clicking zooms to mouse position
            doubleClickZoomOut: false, // if true, double clicking zooms out to mouse position
            clickZoomOut: false, // if true, clicking zooms out to mouse position
            doubleClickMove: false, // if true, double clicking moves the map to the cursor position
            clickMove: false, // if true, clicking moves the map to the cursor position
            doubleClickDistance: 1, // number of positions (determined by layerSplit) to move on a double-click zoom event
            clickDistance: 1, // number of positions (determined by layerSplit) to move on a click zoom event
            callBefore: function(layer, xcoord, ycoord, viewport) {}, // this callback happens before dragging of map starts
            callAfter: function(layer, xcoord, ycoord, viewport) {}, // this callback happens at end of drag after map is released "mouseup"
            beforeZoom: function(layer, xcoord, ycoord, viewport) {}, // callback before a zoom happens
            afterZoom: function(layer, xcoord, ycoord, viewport) {}, // callback after zoom has completed
            mousewheel: false // requires mousewheel event plugin: http://plugins.jquery.com/project/mousewheel
        }

        if(typeof callback == "function") {
            o.callAfter = callback;
        }
        var command, arg = arguments;
        if(typeof o == "string") {
            command = o;//command passes "methods" such as "zoom", "left", etc.
        }

        o = $.extend(defaults, o || {});//inherit properties

        $(this).css({
            overflow: "hidden",
            position: "relative"
        });

        function _zoom(distance) {
            if(!o.zoom) return false;

            if(distance === 0) distance = 0;
                else distance = distance || 1;

            var layers = $(this).find(">div"), limit = layers.length - 1, current = $(this).find(".current-map-layer");
            if(typeof o.beforeZoom == "function") {
                o.beforeZoom(current[0], this.xPos, this.yPos, this);
            }

            var move = this.visible, eq = move;
            move += (distance / o.layerSplit);
            if(move < 0) move = 0;
            if(move > limit) move = limit;
            eq = Math.ceil(move);
            var movement = (this.visible == move) ? false : true;
            this.visible = move;

            var oldWidth = current.width(), oldHeight = current.height();
            var xPercent = (($(this).width() / 2) + this.xPos) / oldWidth,
            yPercent = (($(this).height() / 2) + this.yPos) / oldHeight;

            if ((o.layerSplit > 1 && eq > 0)) {
                var percent = move - (eq -1), thisX = layers.eq(eq)[0].defaultWidth, thisY = layers.eq(eq)[0].defaultHeight, lastX = layers.eq(eq - 1).width(), lastY = layers.eq(eq - 1).height();
                var differenceX = thisX - lastX, differenceY = thisY - lastY, totalWidth = lastX + (differenceX * percent), totalHeight = lastY + (differenceY * percent);
            }
            if(o.layerSplit > 1 && eq > 0) {
                layers.eq(eq).width(totalWidth).find(".map-layer-mask").width(totalWidth).height(totalHeight);
                layers.eq(eq).height(totalHeight).find(o.mapContent).width(totalWidth).height(totalHeight);
            }

            //left and top adjustment for new zoom level
            var newLeft = (layers.eq(eq).width() * xPercent) - ($(this).width() / 2),
            newTop = (layers.eq(eq).height() * yPercent) - ($(this).height() / 2);

            newLeft = 0 - newLeft;
            newTop = 0 - newTop;

            var limitX = $(this).width() - layers.eq(eq).width(),
            limitY = $(this).height() - layers.eq(eq).height();

            if(newLeft > 0) newLeft = 0;
            if(newTop > 0) newTop = 0;
            if(newLeft < limitX) newLeft = limitX;
            if(newTop < limitY) newTop = limitY;

            this.xPos = 0 - newLeft;
            this.yPos = 0 - newTop;

            function doCallback() {
                if(typeof o.afterZoom == "function") {
                    o.afterZoom(layers.eq(eq)[0], this.xPos, this.yPos, this);
                }
            }

            layers.removeClass("current-map-layer").hide();
            layers.eq(eq).css({
                left: newLeft + "px",
                top: newTop + "px",
                display: "block"
            }).addClass("current-map-layer");
            doCallback();
            
            return movement;
        }

        function _move(x, y, node) {
            node = node || $(this).find(".current-map-layer");
            var limitX = 0, limitY = 0, mapWidth = $(this).width(), mapHeight = $(this).height(),
            nodeWidth = $(node).width(), nodeHeight = $(node).height();

            if(mapWidth < nodeWidth) limitX = mapWidth - nodeWidth;
            if(mapHeight < nodeHeight) limitY = mapHeight - nodeHeight;

            var left = 0 - (this.xPos + x), top = 0 - (this.yPos + y);

            left = (left > 0) ? 0 : left;
            left = (left < limitX) ? limitX : left;
            top = (top > 0) ? 0 : top;
            top = (top < limitY) ? limitY : top;

            this.xPos = 0 - left;
            this.yPos = 0 - top;

            $(node).css({
                left: left + "px",
                top: top + "px"
            });
        }

        function _position(x, y, node) {
            node = node || $(this).find(".current-map-layer");

            x = 0 - x;
            y = 0 - y;

            var limitX = 0 - ($(node).width() - $(this).width());
            var limitY = 0 - ($(node).height() - $(this).height());

            if(x > 0) x = 0;
            if(y > 0) y = 0;
            if(x < limitX) x = limitX;
            if(y < limitY) y = limitY;

            this.xPos = 0 - x;
            this.yPos = 0 - y;

            $(node).css({
                left: x + "px",
                top: y + "px"
            });
        }

        function _makeCoords(s) {
            s = s.replace(/px/, "");
            s = 0 - s;
            return s;
        }

        var method = {//public methods
            zoomin: function(distance) {
                distance = distance || 1;
                _zoom.call(this, distance);
            },
            zoomout: function(distance) {
                distance = distance || 1;
                _zoom.call(this, 0 - distance);
            },
            left: function(amount) {
                amount = amount || 10;
                _move.call(this, 0 - amount, 0);
            },
            right: function(amount) {
                amount = amount || 10;
                _move.call(this, amount, 0);
            },
            up: function(amount) {
                amount = amount || 10;
                _move.call(this, 0, 0 - amount);
            },
            down: function(amount) {
                amount = amount || 10;
                _move.call(this, 0, amount);
            },
            center: function(coords) {
                coords = coords || {
                    x: $(this).find(".current-map-layer").width() / 2,
                    y: $(this).find(".current-map-layer").height() / 2
                }
                var node = $(this).find(".current-map-layer");
                var newX = coords.x - ($(this).width() / 2), newY = coords.y - ($(this).height() / 2);
                _position.call(this, newX, newY, node[0]);
            },
            zoomto: function(level) {
                var distance = Math.round((level - this.visible) / (1 / this.layerSplit));
                _zoom.call(this, distance);
            }
        }

        return this.each(function() {
            if(typeof command == "string") {//execute public methods if called
                var execute = method[command];
                o.layerSplit = this.layerSplit || o.layerSplit;
                execute.call(this, callback);
            }
            else {
                this.visible = o.defaultLayer, this.layerSplit = o.layerSplit;//magic
                var viewport = this, layers = $(this).find(">div"), mapHeight = $(this).height(), mapWidth = $(this).width(), mapmove = false, first = true;
                layers.css({
                    position: "absolute"
                }).eq(o.defaultLayer).css({
                    display: "block",
                    left: "",
                    top: ""
                }).addClass("current-map-layer").find(o.mapContent).css({
                    position: "absolute",
                    left: "0",
                    top: "0",
                    height: mapHeight + "px",
                    width: "100%"
                });

                layers.each(function() {
                    this.defaultWidth = $(this).width();
                    this.defaultHeight = $(this).height();
                    $(this).find(o.mapContent).css({
                        position: "absolute",
                        top: "0",
                        left: "0"
                    });
                    if($(this).find(o.mapContent).length > 0) $(this).find(">img").css({
                        width: "100%",
                        position: "absolute",
                        left: "0",
                        top: "0"
                    }).after('<div class="map-layer-mask"></div>')
                });

                $(this).find(".map-layer-mask").css({
                    position: "absolute",
                    left: "0",
                    top: "0",
                    background: "white",// omg, horrible hack,
                    opacity: "0",// but only way IE will not freak out when
                    filter: "alpha(opacity=0)"// mouseup over IMG tag occurs after mousemove event
                });

                if (o.defaultLayer > 0) {
                    layers.eq(o.defaultLayer).find(".map-layer-mask").width(layers.eq(o.defaultLayer).width()).height(layers.eq(o.defaultLayer).height());
                    layers.eq(o.defaultLayer).find(o.mapContent).width(layers.eq(o.defaultLayer).width()).height(layers.eq(o.defaultLayer).height());
                }

                $(this).find(">div:not(.current-map-layer)").hide();
                if(o.defaultX == null) {
                    o.defaultX = Math.floor((mapWidth / 2) - ($(this).find(".current-map-layer").width() / 2));
                    if(o.defaultX > 0) o.defaultX = 0;
                }
                if(o.defaultY == null) {
                    o.defaultY = Math.floor((mapHeight / 2) - ($(this).find(".current-map-layer").height() / 2));
                    if(o.defaultY > 0) o.defaultY = 0;
                }

                this.xPos = 0 - o.defaultX;
                this.yPos = 0 - o.defaultY;
                this.layerSplit = o.layerSplit;

                var mapStartX = o.defaultX;
                var mapStartY = o.defaultY;
                var clientStartX;
                var clientStartY;

                $(this).find(".current-map-layer").css({
                    left: o.defaultX + "px",
                    top: o.defaultY + "px"
                });

                /**
                 * Event Handling and Callbacks
                 */

                var weveMoved = false;

                $(this).mousedown(function() {
                    var layer = $(this).find(".current-map-layer");
                    var x = layer[0].style.left, y = layer[0].style.top;
                    x = _makeCoords(x);
                    y = _makeCoords(y);
                    o.callBefore(layer, x, y, viewport);
                    mapmove = true;
                    first = true;
                    return false;//otherwise dragging on IMG elements etc inside the map will cause problems
                });

                $(document).mouseup(function() {
                    var layer = $(viewport).find(".current-map-layer");
                    var x = layer[0].style.left, y = layer[0].style.top;
                    x = _makeCoords(x);
                    y = _makeCoords(y);
                    o.callAfter(layer, x, y, viewport);
                    mapmove = false;
                    if(weveMoved) {
                        clickDefault = false;
                    }
                    weveMoved = false;
                    return false;
                });

                $(document).mousemove(function(e) {
                    var layer = $(viewport).find(".current-map-layer");
                    if(mapmove && o.pan) {
                        if(first) {
                            clientStartX = e.clientX;
                            clientStartY = e.clientY;
                            mapStartX = layer[0].style.left.replace(/px/, "");
                            mapStartY = layer[0].style.top.replace(/px/, "");
                            first = false;
                        }
                        else {
                            weveMoved = true;
                        }
                        var limitX = 0, limitY = 0;
                        if(mapWidth < layer.width()) limitX = mapWidth - layer.width();
                        if(mapHeight < layer.height()) limitY = mapHeight - layer.height();
                        var mapX = mapStartX - (clientStartX - e.clientX);
                        mapX = (mapX > 0) ? 0 : mapX;
                        mapX = (mapX < limitX) ? limitX : mapX;
                        var mapY = mapStartY - (clientStartY - e.clientY);
                        mapY = (mapY > 0) ? 0 : mapY;
                        mapY = (mapY < limitY) ? limitY : mapY;
                        layer.css({
                            left: mapX + "px",
                            top: mapY + "px"
                        });
                        viewport.xPos = _makeCoords(layer[0].style.left);
                        viewport.yPos = _makeCoords(layer[0].style.top);
                    }
                });

                if(o.mousewheel && typeof $.fn.mousewheel != "undefined") {
                    $(viewport).mousewheel(function(e, distance) {
                        if(o.zoomToCursor) {
                            //should probably DRY this.
                            var layer = $(this).find('.current-map-layer'),
                            positionTop = e.pageY - layer.offset().top,//jQuery normalizes pageX and pageY for us.
                            positionLeft = e.pageX - layer.offset().left,
                            //recalculate this position on current layer as a percentage
                            relativeTop = e.pageY - $(this).offset().top,
                            relativeLeft = e.pageX - $(this).offset().left,
                            percentTop = positionTop / layer.height(),
                            percentLeft = positionLeft / layer.width();
                        }
                        if(_zoom.call(this, distance) && o.zoomToCursor/* && distance > 0*/) {
                            //only center when zooming in, since it feels weird on out.  Don't center if we've reached the floor
                            //convert percentage to pixels on new layer
                            layer = $(this).find('.current-map-layer');
                            var x = layer.width() * percentLeft,
                            y = layer.height() * percentTop;
                            //and set position
                            _position.call(this, x - relativeLeft, y - relativeTop, layer[0]);
                        }
                        return false;//don't scroll the window
                    });
                }

                var clickTimeoutId = setTimeout(function(){},0), clickDefault = true;

                if(o.doubleClickZoom || o.doubleClickZoomOut || o.doubleClickMove) {
                    $(viewport).dblclick(function(e) {
                        //TODO: DRY this
                        //prevent single-click default
                        clearTimeout(clickTimeoutId);
                        clickDefault = false;
                        var layer = $(this).find('.current-map-layer'),
                        positionTop = e.pageY - layer.offset().top,//jQuery normalizes pageX and pageY for us.
                        positionLeft = e.pageX - layer.offset().left,
                        //recalculate this position on current layer as a percentage
                        percentTop = positionTop / layer.height(),
                        percentLeft = positionLeft / layer.width();
                        if(o.doubleClickZoom) {
                            distance = o.doubleClickDistance;
                        }
                        else if (o.doubleClickZoomOut) {
                            distance = 0 - o.doubleClickDistance;
                        }
                        else {
                            distance = 0;
                        }
                        _zoom.call(this, distance);
                        //convert percentage to pixels on new layer
                        layer = $(this).find('.current-map-layer');
                        var x = layer.width() * percentLeft,
                        y = layer.height() * percentTop;
                        //and center
                        method.center.call(this,{x: x, y: y});
                        return false;
                    });
                }

                if(o.clickZoom || o.clickZoomOut || o.clickMove) {
                    $(viewport).click(function(e) {
                        function clickAction() {
                            if(clickDefault) {
                                //TODO: DRY this
                                var layer = $(this).find('.current-map-layer'),
                                positionTop = e.pageY - layer.offset().top,//jQuery normalizes pageX and pageY for us.
                                positionLeft = e.pageX - layer.offset().left,
                                //recalculate this position on current layer as a percentage
                                percentTop = positionTop / layer.height(),
                                percentLeft = positionLeft / layer.width();
                                var distance;
                                if(o.clickZoom) {
                                    distance = o.clickDistance;
                                }
                                else if (o.clickZoomOut) {
                                    distance = 0 - o.clickDistance;
                                }
                                else {
                                    distance = 0;
                                }
                                _zoom.call(this, distance);
                                //convert percentage to pixels on new layer
                                layer = $(this).find('.current-map-layer');
                                var x = layer.width() * percentLeft,
                                y = layer.height() * percentTop;
                                //and center
                                method.center.call(this,{x: x, y: y});
                            }
                            clickDefault = true;
                        }
                        if(o.doubleClickZoom || o.doubleClickZoomOut || o.doubleClickMove) {
                            //if either of these are registered we need to set the clickAction
                            //into a timeout so that a double click clears it
                            clickTimeoutId = setTimeout(function(){clickAction.call(viewport)}, 400);
                        }
                        else {
                            clickAction.call(this);
                        }
                    });
                }

                /**
                 *  End Event Handling and Callbacks
                 */

                //deferred, load images in hidden layers
                $(window).load(function() {
                    layers.each(function() {
                        var img = $(this).find("img")[0];
                        if(typeof img == "object") $("<img>").attr("src", img.src);
                    });
                });
            }
        });
    }
})(jQuery);