/**
 * ILazarte
 * 4/11/2008
 * JQuery, hoooah!
 */
/**
 * Simple Tab Panel
 * Very flexible since we can use css to make it left-aligned, right-aligned as desired.
 * This isn't totally complete yet, it's more a proof of concept.
 *
 * TODO Convert the usage of attrs to the data as appropriate.  Some attrs actually being selected against.
 * TODO Look go reduce css state complexity
 *
 * Reference on building a plugin:
 * http://blog.jeremymartin.name/2008/02/building-your-first-jquery-plugin-that.html
 */
(function($){
    $.fn.tabs = function(options){
    
        var defaults = {
            initTab: 1
        };
        
        options = $.extend(defaults, options);
        
        function getCurrentViewClass(item){
            if ($(item).hasClass('npr-tab-h-item-inactive')) {
                return 'npr-tab-h-item-inactive';
            }
            if ($(item).hasClass('npr-tab-h-item-active')) {
                return 'npr-tab-h-item-active';
            }
        }
        
        function updateTabsCss(item){
            $(item).addClass('npr-tab-h-item-active').removeClass('npr-tab-h-item-inactive').attr('viewCls', 'npr-tab-h-item-active').siblings().addClass('npr-tab-h-item-inactive').removeClass('npr-tab-h-item-active').attr('viewCls', 'npr-tab-h-item-inactive');
        }
        
        function switchPanel(sid, item){
            var hid = $(item).attr('headId');
            updateTabsCss(item);
            $(sid).find('.npr-tabs-d > li[dataId=' + hid + ']').show().siblings().hide();
        }
        
        return this.each(function(){
        
            var id = $(this).attr('id');
            var sid = '#' + id;
            
            /**
             * Initialize all the tabs on this page.
             */
            function init(){
                var count = 0;
                $(sid).find('.npr-tabs-h > li').each(function(){
                    var incr = count++;
                    $(this).addClass('npr-tab-h-items').addClass('npr-tab-h-item-' + incr).attr('headId', id + incr).css('cursor', 'pointer');
                    
                }).hover(function(){
                    var viewCls = getCurrentViewClass(this);
                    $(this).attr('viewCls', viewCls).removeClass(viewCls).addClass('npr-tab-h-item-hover');
                }, function(){
                    var viewCls = $(this).attr('viewCls');
                    $(this).removeClass('npr-tab-h-item-hover').addClass(viewCls);
                }).click(function(){
                    switchPanel(sid, this);
                });
                
                count = 0;
                $(sid).find('.npr-tabs-d > li').each(function(){
                    $(this).addClass('npr-tab-d-items');
                    $(this).attr('dataId', id + count++);
                });
                
                var query = '.npr-tabs-h > li:eq(' + options.initTab + ')';
                var initItem = $(sid).find(query).get();
                switchPanel(sid, initItem);
                $(sid).removeClass('init-hidden');
            }
            
            init();
        });
    };
})(jQuery);

/*
 * Username related functionality.
 */
(function($){
    
    /**
     * Static function which registers a click handler to check the nickname.
     * 
     * @param {Object} clickable A jquery for the item which will be clicked on..
     * @param {Object} nicknameInput A jquery for the nickname input tag.
     *     Must have a parent p tag in order to be able to position correctly.
     *     Creates a #nicknameresult to display and destroys it after the message. 
     */
    $.checkNickname = function(clickable, nicknameInput) {
        
        $(clickable)
            .click(function() {
                var inputEl = $(nicknameInput).get(0);
                var value = inputEl.value;
                var params = { public_user_nick_name : value };
                var render = function(result)
                {
                    var msg = '<div id="nicknameresult" class="activeerror">';
                    msg += 'Unable to check nickname.</div>';
                    switch (result) {
                        case true:
                            msg = '<div id="nicknameresult" class="activemsg">';
                            msg += 'This nickname is available</div>';
                            break;
                        case false:
                            msg = '<div id="nicknameresult" class="activeerror">';
                            msg += 'This nickname is not available</div>';
                            break;
                    }

                    var parent = $(inputEl).parent('p');
                    var offset = $(parent).offset();
                    var height = $(parent).height();
                    $(document.body).append(msg);

                    $('#nicknameresult')
                        .css('left', offset.left)
                        .css('top', offset.top + height)
                        .css('position', 'absolute');

                    setTimeout(function() {
                        var oncomplete = function() {
                            $('#nicknameresult').remove();
                        };
                        $('#nicknameresult').fadeOut("slow", oncomplete);
                    }, 4000);
                };

                $.ajax({
                    url: '/templates/reg/remoteValidateUsername.php',
                    type: 'GET',
                    data: params,
                    dataType: 'json',
                    timeout: 1500,
                    success: render});

                return false;
            });
    };
  
})(jQuery);

/**
 * Bind an even with a delay.
 * The delay will wait N miliseconds before executing the callback.
 * The key handler checks for keys above 60000 which is a Mac/Safari issue.
 * Down/Up apparently are 65532 and 3 or something like that.
 * Enter/Esc are the same as other browsers.
 * @param {Object} $
 */
(function($){

    $.fn.delay = function(options){
    
        var timer;
        function count(scope){
            if (timer !== null) {
                clearTimeout(timer);
            }
            var newFn = function(){
                options.fn.apply(scope);
            };
            timer = setTimeout(newFn, options.delay);
        }
        
        return this.each(function(){
            var obj = $(this);
            obj.bind(options.event, function(event){
                var ignoreKey = null;
                if (event.keyCode) {
                    ignoreKey = event.keyCode;
                } else if(event.which) {
                    ignoreKey = event.which;
                }
                if (ignoreKey &&
                    ignoreKey == 13 ||
                    ignoreKey == 27 || 
                    ignoreKey == 38 ||
                    ignoreKey == 40 ||
                    ignoreKey > 60000) {
                    event.preventDefault();
                } else {
                    count(this);
                }
            });
        });
    };
    
})(jQuery);

/**
 * Add the custom validators used by the reg process.
 * @see http://docs.jquery.com/Plugins/Validation/Validator/addMethod#namemethodmessage
 * @param {Object} $
 */
(function($){
    
    /* allows us to include this file without requiring the validate plugin file */
    if (!$.validator) { return; }
    
    /**
     * Validates the email only if it is not empty.
     * Used required as well if you want the email to be required.
     * 
     * @see http://en.wikipedia.org/wiki/E-mail_address
     * @see http://en.wikibooks.org/wiki/JavaScript/Best_Practices
     * @param {Object} value
     * @param {Object} element
     */        

    $.validator.addMethod("rfc2822email", function(value, element){
    
        if (value === "") {
            return true;
        }
        
        var atSym = value.lastIndexOf("@");
        
        // no local-part
        if (atSym < 1) {
            return false;
        }
        // no domain
        if (atSym == value.length - 1) {
            return false;
        } 
        // there may only be 64 octets in the local-part
        if (atSym > 64) {
            return false;
        } 
        // there may only be 255 octets in the domain
        if (value.length - atSym > 255) {
            return false;
        } 
        // Is the domain plausible?
        var lastDot = value.lastIndexOf(".");
        
        // Check if it is a dot-atom such as example.com
        if (lastDot > atSym + 1 && lastDot < value.length - 1) {
            return true;
        }
        
        //  Check if could be a domain-literal.
        if (value.charAt(atSym + 1) == '[' && value.charAt(value.length - 1) == ']') {
            return true;
        }
        
        return false;
        
    }, "Please enter a valid email.");
    
    /**
     * valid first/last names.
     * Allows apostrophes.
     *
     * @param {Object} value
     * @param {Object} element
     */
    $.validator.addMethod("personname", function(value, element){
    
        var regex = /^[a-z\.' -]+$/i;
        if (value === "") {
            return true;
        }
        var passes = regex.test(value);
        
        return passes;
        
    }, "Please enter a valid name.");
    
    /**
     * Validator to check for valid user names.
     * Includes periods, and wordchar.
     *
     * @param {Object} value
     * @param {Object} element
     */
    $.validator.addMethod("nickname", function(value, element){
    
        var regex = /^[a-z0-9_]+$/i;
        if (value === "") {
            return true;
        }
        var passes = regex.test(value);
        
        return passes;
        
    }, "Please enter a valid nickname. Only letters, numbers, and the underscore character may be used.");
    
    /**
     * valid alpha string.
     * Allows apostrophes.
     *
     * @param {Object} value
     * @param {Object} element
     */
    $.validator.addMethod("alpha", function(value, element){
    
        var regex = /^[a-z]+$/i;
        if (value === "") {
            return true;
        }
        var passes = regex.test(value);
        
        return passes;
        
    }, "Please enter a valid alpha string.");
    
})(jQuery);

/**
 * ILazarte, 7/23
 * The version says 1.0.x, but seems to work fine in 1.x.x
 * Modified the source a little to have no side-effects.
 * @see http://plugins.jquery.com/project/cookie
 * 
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

(function($){

    $.cookie = function(name, value, options){
        if (typeof value != 'undefined') { // name and value given, set cookie
            options = options || {};
            if (value === null) {
                value = '';
                options.expires = -1;
            }
            var expires = '';
            if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
                var date;
                if (typeof options.expires == 'number') {
                    date = new Date();
                    date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
                } else {
                    date = options.expires;
                }
                expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
            }
            // CAUTION: Needed to parenthesize options.path and options.domain
            // in the following expressions, otherwise they evaluate to undefined
            // in the packed version for some reason...
            var path = options.path ? '; path=' + (options.path) : '';
            var domain = options.domain ? '; domain=' + (options.domain) : '';
            var secure = options.secure ? '; secure' : '';
            document.cookie =[name,'=',encodeURIComponent(value),expires,path,domain,secure] .join('');
        } else { // only name given, get cookie
            var cookieValue = null;
            if (document.cookie && document.cookie !== '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = $.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
    };        

    /**
     * Returns a ready to use newsletter id array.
     */
    $.newsletterscookie = function() {
        var cookie = $.cookie('nl');
        if (cookie === null) {
            return null;
        }
        return cookie.split(",");    
    };    

    /**
     * Returns a ready to use station array.
     */
    $.stationscookie = function() {
        var cookie = $.cookie('st');
        if (cookie === null) {
            return null;
        }
        return cookie.split(",");    
    };

    /**
     * Returns a ready to use Javascript object.
     */
    $.authcookie = function() {

        var obj = {};        
        var cookie = $.cookie('at');
        if (cookie === null) { return obj; }
        var items = cookie.split('&');
        for(var i = 0; i < items.length; i++) {
            var kv = items[i].split('=');
            var key = kv[0];
            var val = kv[1];
            switch (key) {
                case 'u':
                obj.userid = val;
                break;
                case 'a':
                obj.username = val;
                break;
                case 'e':
                obj.email = val;
                break;
                case 'f':
                obj.fname = val;
                break;
                case 'l':
                obj.lname = val;
                break;
                case 'g':
                obj.gender = val;
                break;
                default:
                obj[key] = val;
            } 
        }

        /*
         * Create a fullname field for convenience.
         * Do not create it if no valid values are found.
         */        
        if (obj.fname !== 'undefined') {
            obj.fullname = obj.fname;    
        } 
        if (obj.lname !== 'undefined') {
            if (obj.fullname) {
                obj.fullname += ' ' + obj.lname;
            } else {
                obj.fullname = obj.lname;
            }
        }

        return obj;
    };
    
})(jQuery);

(function($){
    /**
     * Grab the station ids from the hidden inputs.
     * Used in a legacy form integrations.
     */
    $.grabStationIds = function() {
        var stations = $('input[name="public_user_stations[]"]').get();
        var sids = [];
        for (var i = 0; i < stations.length; i++) {
            sids.push(stations[i].value);
        }                  
        var csv = sids.join(',');               
        return csv;
    };
    
})(jQuery);

(function($){

    /**
     * Simple function to check to see if an array has an element.
     * @param {Object} element
     * @param {Object} arr
     */
    $.arrayContains = function (element, arr) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] == element) {
                return true;
            }
        }
        return false;
    };
    
})(jQuery);    

/**
 * Simple login/logout event abstractions.
 * The code below could probably be made shorter, but eh.
 */
(function($){

    $.fn.login = function(callback){
        var fn = null;
        if (callback) {
            fn = function() {
                $(this).bind('login', callback);
            };
        } else {
            fn = function() {
                $(this).trigger('login');                    
            };                        
        }             
        return this.each(fn);
    };
    
    $.fn.logout = function(callback) {
        var fn = null;
        if (callback) {
            fn = function() { 
                $(this).bind('logout', callback);
            };
        } else {
            fn = function() {
                $(this).trigger('logout');
            };                        
        }                        
        return this.each(fn);
    };
    
})(jQuery);

