﻿/**
* Simplify calling ASP.NET AJAX services from jQuery
* http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/
*/
//(function($) {
//    $.ajaxSetup({
//        type: "POST",
//        contentType: "application/json; charset=utf-8",
//        data: "{}",
//        dataFilter: function(data) {
//            var msg;

//            if (typeof (JSON) !== 'undefined' &&
//            typeof (JSON.parse) === 'function')
//                msg = JSON.parse(data);
//            else
//                msg = eval('(' + data + ')');

//            if (msg.hasOwnProperty('d'))
//                return msg.d;
//            else
//                return msg;
//        },
//        error: function(xhr, msg) {
//            alert("An error occurred, please report this problem.");
//        },
//        beforeSend: function(xhr) {
//            $("#ajax-loader").show();
//        },
//        complete: function(xhr, status) {
//            $("#ajax-loader").hide();
//        }
//    });
//})(jQuery);

// Fancy borders around all the site thumbnails.
// Run as early as possible even before document.ready.
$(window).load(function() {
    $('div.border a.thumb-anchor').borders().vAlign();
});

(function($) {
    $(function() {
        $.prettyDateExec();

        $('a.tt, span.tt').tipsy({ gravity: 'n' });

        $('.eq-height').equalHeights();

        $('.buttonset').buttonset();

        $('.datepicker').datepicker({
            dateFormat: 'm/d/yy',
            changeMonth: true,
            changeYear: true,
            yearRange: '1880:+1'
        });

        // Hover for buttons.
        // http://www.filamentgroup.com/lab/styling_buttons_and_toolbars_with_the_jquery_ui_css_framework/
        $('.fg-button').hover(
	        function() { $(this).addClass('ui-state-hover'); },
	        function() { $(this).removeClass('ui-state-hover'); }
        )

        Confirmation();

        CKEditor();
    });

    $(function() {
        $('a.attending, a.notattending').click(function() {
            var thisLink = $(this);
            var otherLink = thisLink.siblings('a');
            $.ajax({
                url: thisLink.attr('href'),
                success: function(data) {
                    if (data.status == "ok") {
                        thisLink.toggle();
                        otherLink.toggle();
                    } else {
                        alert("Oops, something went wrong. Please try again.");
                    }
                }
            });

            return false;
        });

        $('a.cheer').click(function() {
            var cheerLink = $(this);

            $.ajax({
                url: cheerLink.attr('href'),
                success: function(data) {
                    var cheers = parseInt(cheerLink.children('span').text());
                    if (cheerLink.hasClass('selected')) {
                        cheerLink.removeClass('selected');
                        cheerLink.children('span').text(cheers - 1);
                        cheerLink.attr('title', 'Click to cheer');
                    } else {
                        cheerLink.addClass('selected');
                        cheerLink.children('span').text(cheers + 1);
                        cheerLink.attr('title', 'Click to uncheer');
                    }

                    // Swap the href with the rel so that if they click it again, it undoes their last action.
                    var tempLink = cheerLink.attr('href');
                    cheerLink.attr('href', cheerLink.attr('rel'));
                    cheerLink.attr('rel', tempLink);
                }
            });

            return false;
        });
    });
})(jQuery);

(function($) {
    $.fn.simpleselect = function(options) {
        var settings = {
            select: function() { }
        };
        if (options) {
            $.extend(settings, options);
        }

        this.children().each(function() {
            $(this).addClass('ui-state-default');
        }).hover(function() {
            $(this).addClass('ui-state-hover');
        }, function() {
            $(this).removeClass('ui-state-hover');
        }).click(function() {
            $(this).toggleClass('ui-state-active').siblings().removeClass('ui-state-active');

            settings.select($(this));
        });

        return this;
    }
})(jQuery);

(function($) {
    $.fn.borders = function(options) {
        var settings = {
        };
        if (options) {
            $.extend(settings, options);
        }

        this.each(function() {
            $(this)
                .before('<div class="border-top-220"><div class="shadow" /></div>')
                .after('<div class="border-bottom-220"><div class="shadow" /></div>')
                .wrap('<div class="border-middle-220" />');
        }).hover(function() {
        }, function() {
        }).click(function() {
            $(this);
        });

        return this;
    }
})(jQuery);

function CKEditor() {
    var config = {
        toolbar: [
			            ['Source'],
                        ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'],
                        ['Undo', 'Redo', '-', 'Find', 'Replace'],
                        ['Bold', 'Italic', 'Underline', '-', 'Subscript', 'Superscript'],
                        ['NumberedList', 'BulletedList'],
                        ['JustifyLeft', 'JustifyCenter', 'JustifyRight'],
                        ['Link', 'Unlink'],
                        ['Image', 'Flash', 'Table', 'HorizontalRule'],
                        ['Format', 'Font', 'FontSize'],
                        ['TextColor'],
                        ['Maximize', 'ShowBlocks']
			        ],
        extraPlugins: 'autogrow',
        autoGrow_maxHeight: 500
    };

    $('.jquery_ckeditor').ckeditor(config);
}

function Confirmation() {
    if ($('#dialogconfirm').length == 0 && $('a.confirm').length > 0) {
        $('body').append('<div id="dialogconfirm" title="Confirm" style="display: none;"><p id="dialogconfirmconfig-message"></p></div>');
    }

    // Link action.
    $('a.confirm').live('click', function(event) {
        var form = $(event.target).closest('form');
        var container = $(event.target).closest('.container');
        var confirm = $('#dialogconfirm');
        var text;
        if ($(this).hasClass("accept")) {
            text = "accept this offer";
        } else if ($(this).hasClass("decline")) {
            text = "decline this offer";
        } else if ($(this).hasClass("delete")) {
            text = "delete this";
        } else {
            text = "do this";
        }
        $('#dialogconfirmconfig-message').text("Are you sure you want to "+text+"?");
        confirm.data('callback', function() {
            $.ajax({
                url: form.attr('action'),
                type: 'POST',
                success: function(result) {
                    if (result.status == 'ok') {
                        container.fadeOut('normal');
                    } else {
                        alert('Oops, something went wrong. Please try again. ' + result.status);
                    }
                }
            });
        });
        confirm.dialog('open');

        return false;
    });

    // Confirm dialog.
    $('#dialogconfirm').dialog({
        autoOpen: false,
        width: 375,
        buttons: {
            'Ok': function() {
                var dialog = $(this);
                if (dialog.data('callback')) {
                    dialog.data('callback')();
                    dialog.removeData('callback');
                }
                dialog.dialog('close');
            },
            'Cancel': function() {
                $(this).dialog('close');
            }
        }
    });
}

/*
* JavaScript Pretty Date
* Copyright (c) 2008 John Resig (jquery.com)
* Licensed under the MIT license.
*/
// Takes an ISO time in UTC and returns a string representing how long ago the date represents.
function prettyDate(time) {
    var currentUtcTime = (new Date()).getTime() + new Date().getTimezoneOffset() * 60000;
    var date = new Date((time || "").replace(/-/g, "/").replace(/[TZ]/g, " "));
    var diff = ((currentUtcTime - date.getTime()) / 1000);
    var day_diff = Math.floor(diff / 86400);

    if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31)
        return;

    return day_diff == 0 && (
			diff < 60 && "just now" ||
			diff < 120 && "1 minute ago" ||
			diff < 3600 && Math.floor(diff / 60) + " minutes ago" ||
			diff < 7200 && "1 hour ago" ||
			diff < 86400 && Math.floor(diff / 3600) + " hours ago") ||
		day_diff == 1 && "Yesterday" ||
		day_diff < 7 && day_diff + " days ago" ||
		day_diff < 31 && Math.ceil(day_diff / 7) + " weeks ago";
}

(function($) {
    $.fn.prettyDate = function() {
        return this.each(function() {
            var date = prettyDate(this.title);
            if (date)
                $(this).text(date);
        });
    };

    $.prettyDateExec = function() {
        $('abbr.prettydate').prettyDate();
    };
})(jQuery);

/*
*
* Copyright (c) 2006/2007 Sam Collett (http://www.texotela.co.uk)
* Licensed under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
* 
* Version 1.0
* Demo: http://www.texotela.co.uk/code/jquery/numeric/
*
* $LastChangedDate: 2007-05-29 11:31:36 +0100 (Tue, 29 May 2007) $
* $Rev: 2005 $
*/

/*
* Allows only valid characters to be entered into input boxes.
* Note: does not validate that the final text is a valid number
* (that could be done by another script, or server-side)
*
* @name     numeric
* @param    validCallback       A function that runs if the number is valid (fires onblur)
* @param    invalidCallback     A function that runs if the number is not valid (fires onblur)
* @author   Sam Collett (http://www.texotela.co.uk)
* @example  $(".numeric").numeric(validCallback, invalidCallback);
*
*/
(function($) {
    $.fn.numeric = function(validCallback, invalidCallback) {
        allowNegative = false;
        decimal = ".";
        validCallback = typeof validCallback == "function" ? validCallback : function() { };
        invalidCallback = typeof invalidCallback == "function" ? invalidCallback : function() { };
        this.keypress(
		    function(e) {
		        var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
		        // allow enter/return key (only when in an input box)
		        if (key == 13 && this.nodeName.toLowerCase() == "input") {
		            return true;
		        } else if (key == 13) {
		            return false;
		        }
		        var allow = false;
		        // allow Ctrl+A
		        if ((e.ctrlKey && key == 97 /* firefox */) || (e.ctrlKey && key == 65) /* opera */) return true;
		        // allow Ctrl+X (cut)
		        if ((e.ctrlKey && key == 120 /* firefox */) || (e.ctrlKey && key == 88) /* opera */) return true;
		        // allow Ctrl+C (copy)
		        if ((e.ctrlKey && key == 99 /* firefox */) || (e.ctrlKey && key == 67) /* opera */) return true;
		        // allow Ctrl+Z (undo)
		        if ((e.ctrlKey && key == 122 /* firefox */) || (e.ctrlKey && key == 90) /* opera */) return true;
		        // allow or deny Ctrl+V (paste), Shift+Ins
		        if ((e.ctrlKey && key == 118 /* firefox */) || (e.ctrlKey && key == 86) /* opera */
			    || (e.shiftKey && key == 45)) return true;
		        // if a number was not pressed
		        if (key < 48 || key > 57) {
		            /* '-' only allowed at start */
		            if (allowNegative && key == 45 && this.value.length == 0) return true;
		            /* only one decimal separator allowed */
		            if (key == decimal.charCodeAt(0) && this.value.indexOf(decimal) != -1) {
		                allow = false;
		            }
		            // check for other keys that have special purposes
		            if (
					    key != 8 /* backspace */ &&
					    key != 9 /* tab */ &&
					    key != 13 /* enter */ &&
					    key != 35 /* end */ &&
					    key != 36 /* home */ &&
					    key != 37 /* left */ &&
					    key != 39 /* right */ &&
					    key != 46 /* del */
				    ) {
		                allow = false;
		            }
		            else {
		                // for detecting special keys (listed above)
		                // IE does not support 'charCode' and ignores them in keypress anyway
		                if (typeof e.charCode != "undefined") {
		                    // special keys have 'keyCode' and 'which' the same (e.g. backspace)
		                    if (e.keyCode == e.which && e.which != 0) {
		                        allow = true;
		                    }
		                    // or keyCode != 0 and 'charCode'/'which' = 0
		                    else if (e.keyCode != 0 && e.charCode == 0 && e.which == 0) {
		                        allow = true;
		                    }
		                }
		            }
		            // if key pressed is the decimal and it is not already in the field
		            if (key == decimal.charCodeAt(0) && this.value.indexOf(decimal) == -1) {
		                allow = true;
		            }
		        }
		        else {
		            allow = true;
		        }
		        return allow;
		    }
	    )
	    .blur(
		    function() {
		        var val = $(this).val();
		        if (val != "") {
		            var re = new RegExp("^\\d+$|\\d*" + decimal + "\\d+");
		            if (!re.exec(val)) {
		                invalidCallback.apply(this);
		            } else {
		                validCallback.apply(this);
    		        }
		        }
		    }
	    );
        return this;
    }
})(jQuery);


/*-------------------------------------------------------------------- 
* javascript method: "pxToEm"
* by:
Scott Jehl (scott@filamentgroup.com) 
Maggie Wachs (maggie@filamentgroup.com)
http://www.filamentgroup.com
*
* Copyright (c) 2008 Filament Group
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
*
* Description: Extends the native Number and String objects with pxToEm method. pxToEm converts a pixel value to ems depending on inherited font size.  
* Article: http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/
* Demo: http://www.filamentgroup.com/examples/pxToEm/	 	
*							
* Options:  	 								
scope: string or jQuery selector for font-size scoping
reverse: Boolean, true reverses the conversion to em-px
* Dependencies: jQuery library						  
* Usage Example: myPixelValue.pxToEm(); or myPixelValue.pxToEm({'scope':'#navigation', reverse: true});
*
* Version: 2.0, 08.01.2008 
* Changelog:
*		08.02.2007 initial Version 1.0
*		08.01.2008 - fixed font-size calculation for IE
--------------------------------------------------------------------*/

Number.prototype.pxToEm = String.prototype.pxToEm = function(settings) {
    //set defaults
    settings = jQuery.extend({
        scope: 'body',
        reverse: false
    }, settings);

    var pxVal = (this == '') ? 0 : parseFloat(this);
    var scopeVal;
    var getWindowWidth = function() {
        var de = document.documentElement;
        return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
    };

    /* When a percentage-based font-size is set on the body, IE returns that percent of the window width as the font-size. 
    For example, if the body font-size is 62.5% and the window width is 1000px, IE will return 625px as the font-size. 	
    When this happens, we calculate the correct body font-size (%) and multiply it by 16 (the standard browser font size) 
    to get an accurate em value. */

    if (settings.scope == 'body' && $.browser.msie && (parseFloat($('body').css('font-size')) / getWindowWidth()).toFixed(1) > 0.0) {
        var calcFontSize = function() {
            return (parseFloat($('body').css('font-size')) / getWindowWidth()).toFixed(3) * 16;
        };
        scopeVal = calcFontSize();
    }
    else { scopeVal = parseFloat(jQuery(settings.scope).css("font-size")); };

    var result = (settings.reverse == true) ? (pxVal * scopeVal).toFixed(2) + 'px' : (pxVal / scopeVal).toFixed(2) + 'em';
    return result;
};


/*-------------------------------------------------------------------- 
* JQuery Plugin: "EqualHeights"
* by:	Scott Jehl, Todd Parker, Maggie Costello Wachs (http://www.filamentgroup.com)
*
* Copyright (c) 2008 Filament Group
* Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
*
* Description: Compares the heights or widths of the top-level children of a provided element 
and sets their min-height to the tallest height (or width to widest width). Sets in em units 
by default if pxToEm() method is available.
* Dependencies: jQuery library, pxToEm method	(article: 
http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/)							  
* Usage Example: $(element).equalHeights();
Optional: to set min-height in px, pass a true argument: $(element).equalHeights(true);
* Version: 2.0, 08.01.2008
--------------------------------------------------------------------*/

$.fn.equalHeights = function(px) {
    $(this).each(function() {
        var currentTallest = 0;
        $(this).children().each(function(i) {
            if ($(this).height() > currentTallest) { currentTallest = $(this).height(); }
        });
        if (!px || !Number.prototype.pxToEm) currentTallest = currentTallest.pxToEm(); //use ems unless px is specified
        // for ie6, set height since min-height isn't supported
        if ($.browser.msie && $.browser.version == 6.0) { $(this).children().css({ 'height': currentTallest }); }
        $(this).children().css({ 'min-height': currentTallest });
    });
    return this;
};

// http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/
(function($) {
    $.fn.vAlign = function() {
        return this.each(function(i) {
            var ah = $(this).height();
            var ph = $(this).parent().height();
            var mh = (ph - ah) / 2;
            $(this).css('margin-top', mh);
        });
    };
})(jQuery);

/* Tipsy */
(function($) {
    $.fn.tipsy = function(options) {

        options = $.extend({}, $.fn.tipsy.defaults, options);

        return this.each(function() {

            var opts = $.fn.tipsy.elementOptions(this, options);

            $(this).hover(function() {

                $.data(this, 'cancel.tipsy', true);

                var tip = $.data(this, 'active.tipsy');
                if (!tip) {
                    tip = $('<div class="tipsy"><div class="tipsy-inner"/></div>');
                    tip.css({ position: 'absolute', zIndex: 100000 });
                    $.data(this, 'active.tipsy', tip);
                }

                if ($(this).attr('title') || typeof ($(this).attr('original-title')) != 'string') {
                    $(this).attr('original-title', $(this).attr('title') || '').removeAttr('title');
                }

                var title;
                if (typeof opts.title == 'string') {
                    title = $(this).attr(opts.title == 'title' ? 'original-title' : opts.title);
                } else if (typeof opts.title == 'function') {
                    title = opts.title.call(this);
                }

                tip.find('.tipsy-inner')[opts.html ? 'html' : 'text'](title || opts.fallback);

                var pos = $.extend({}, $(this).offset(), { width: this.offsetWidth, height: this.offsetHeight });
                tip.get(0).className = 'tipsy'; // reset classname in case of dynamic gravity
                tip.remove().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('tipsy-north');
                        break;
                    case 's':
                        tip.css({ top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 }).addClass('tipsy-south');
                        break;
                    case 'e':
                        tip.css({ top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth }).addClass('tipsy-east');
                        break;
                    case 'w':
                        tip.css({ top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }).addClass('tipsy-west');
                        break;
                }

                if (opts.fade) {
                    tip.css({ opacity: 0, display: 'block', visibility: 'visible' }).animate({ opacity: 0.8 });
                } else {
                    tip.css({ visibility: 'visible' });
                }

            }, function() {
                $.data(this, 'cancel.tipsy', false);
                var self = this;
                setTimeout(function() {
                    if ($.data(this, 'cancel.tipsy')) return;
                    var tip = $.data(self, 'active.tipsy');
                    if (opts.fade) {
                        tip.stop().fadeOut(function() { $(this).remove(); });
                    } else {
                        tip.remove();
                    }
                }, 100);

            });

        });

    };

    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tipsy-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tipsy.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };

    $.fn.tipsy.defaults = {
        fade: false,
        fallback: '',
        gravity: 'n',
        html: false,
        title: 'title'
    };

    $.fn.tipsy.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };

    $.fn.tipsy.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };

})(jQuery);


/* cookies for jquery https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js */
jQuery.cookie = function(key, value, options) {

    // key and value given, set cookie...
    if (arguments.length > 1 && (value === null || typeof value !== "object")) {
        options = jQuery.extend({}, options);

        if (value === null) {
            options.expires = -1;
        }

        if (typeof options.expires === 'number') {
            var days = options.expires, t = options.expires = new Date();
            t.setDate(t.getDate() + days);
        }

        return (document.cookie = [
            encodeURIComponent(key), '=',
            options.raw ? String(value) : encodeURIComponent(String(value)),
            options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
            options.path ? '; path=' + options.path : '',
            options.domain ? '; domain=' + options.domain : '',
            options.secure ? '; secure' : ''
        ].join(''));
    }

    // key and possibly options given, get cookie...
    options = value || {};
    var result, decode = options.raw ? function(s) { return s; } : decodeURIComponent;
    return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
};
