//jQuery Jott Web Library Plugin
(function($){

$.jwlib = {
    //*Constants
    
    dragParam: 'dragparam=',
    
    dropParam: 'dropparam=',
    
    DDParam: 'DDParams=',//TODO - Legacy, remove before 5.0
    
    usaPhoneLength: 10,
    
    cardLength: 13,
    
    cardMaxLen: 19,
    
    minPassLength: 6,
    
    regExCanadaZip: /^[^\W_DFIOQUWZ\d]\d[^\W_DFIOQU\d][\055\s]{0,1}\d[^\W_DFIOQU\d]\d$/i,
    
    regExUsaZip: /^\d{5}$|^\d{5}[\055\s]{0,1}\d{4}$/,
    
    regExEmail: /^[\w!#$%*/?|\^{}`~&'+\-=_.]+@(\w[\w\.\-]*\w|\w)\.[a-zA-Z]{2,6}$/i,
    
    regExAuPhone: /^\d{9}$/,
    
    regExBePhone: /^\d{9,10}$/,
    
    regExDePhone: /^\d{10,11}$/,
    
    regExEsPhone: /^\d{3,9}$/,
     
    regExNzPhone: /^\d{8,11}$/,
    
    regExUkPhone: /^\d{9,10}$/,
    
    regExUsPhone: /^\d{10}$/,
    
    regExFrPhone: /^\d{9,10}$/,
    
    regExMultiDot: /\.\.+/,
    
    version: 0, //Set by server.
    
    //*Methods
    
    //Test if a string is a valid GUID.
    isGuid: function(str){
        return /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/
        .test(str);
    },
    
    //Demangles ASP.NET server control ID's.
    demangle: function(id){
        splitId = id.split('_');
        return splitId[splitId.length - 1];
    },

    //Strips the white space from the passed
    //in string.
    stripWhiteSpace: function(str){
        return str.replace(/\n|\f|\r|\t|\v|\s/gi, '');
    },
    
    //Strips non-digits from the passed in
    //string.
    stripNonDigits: function(str){
        return str.replace(/\D/gi, '');
    },
    
    //Trims whitespace and any specified
    //characters from the front and back 
    //of a string.
    trim: function(str, chars, front, back){
        if (undefined === chars)
            chars = '';
        if (undefined === front)
            front = true;
        if (undefined === back)
            back = true;
            
        var ret = str;
        if (front)
            ret = ret.replace(new RegExp('^[\\s'+chars+']*'), '');
        if (back)
            ret = ret.replace(new RegExp('[\\s'+chars+']*$'), '');
        return ret
    },
    
    getCurrentPage: function(){
        var query = location.search;
        var start = query.indexOf('page=');
        if (start < 0)
            return 1;
        else
            start += 'page='.length;
        var end = query.indexOf('&', start);
        var page = '1';
        if (end <= start)
            page = query.substring(start);
        else
            page = query.substring(start, end);
        return parseInt(page);
    },
    
    //Returns true if the passed in string
    //is a valid name.
    validateName: function(str){
        return /^[\w\047\055\056][\w\047\055\056\s]*[\w\047\055\056]$/.test(str);
    },
    
    //Returns true if the passed in string
    //is a valid e-mail address.
    validateEmail: function(str){
        var index = str.indexOf('@');
        
        //If no @ sign or @ sign is first char.
        if (index < 1)
            return false;
            
        var local = str.substring(0, index);
        
        //local part can not start or end with a .
        if (local.charAt(0) == '.' || local.charAt(local.length-1) == '.')
            return false;
            
        //Email addresses can't have consecutive dots.
        if ($.jwlib.regExMultiDot.test(str))
            return false;
        
        //Test for valid characters.
        return $.jwlib.regExEmail.test(str);
    },
    
    //Returns true if the passed in string
    //is a valid phone number.
    validatePhone: function(str){
        var country = parseInt($('.phonefield_countrycode').val());
        var phone = $.jwlib.stripNonDigits(str);
        switch (country) {
            case 1:
                return $.jwlib.regExUsPhone.test(phone);
            case 61:
                return $.jwlib.regExAuPhone.test(phone);
            case 64:
                return $.jwlib.regExNzPhone.test(phone);
            case 44:
                return $.jwlib.regExUkPhone.test(phone);
            case 32:
                return $.jwlib.regExBePhone.test(phone);
            case 49:
                return $.jwlib.regExDePhone.test(phone);
            case 34:
                return $.jwlib.regExEsPhone.test(phone);
            case 33:
                return $.jwlib.regExFrPhone.test(phone);
            default:
                return $.jwlib.usaPhoneLength == phone.length;
        }
        return false;
    },
    
    //Returns an length 2 array representing
    //the range of digits allowed for a specified
    //phone field.
    getValidPhoneRange: function(context){
        var ret = new Object;
        ret.min = 0;
        ret.max = 0;
        var country = parseInt($('.phonefield_countrycode', context).val());
        switch (country) {
            case 61:
                ret.min = 9;
                ret.max = 9;
                break;
            case 64:
                ret.min = 8;
                ret.max = 11;
                break;
            case 32:
                ret.min = 8;
                ret.max = 9;
                break;
            case 49:
                ret.min = 10;
                ret.max = 11;
                break;
            case 34:
                ret.min = 3;
                ret.max = 9;
                break;
            case 44:
            case 33:
                ret.min = 9;
                ret.max = 10;
                break;
            case 1:
            default:
                ret.min = 10;
                ret.max = 10;
                break;
        }
        return ret;
    },
    
    //Returns true if the passed in string
    //is a valid password.
    validatePassword: function(str){
        return /^\S+.{4,}\S+$/.test(str);
    },
    
    //Returns true if the passed in string
    //is a valid postal code.
    validateZip: function(str){
        return $.jwlib.regExUsaZip.test(str) ||
            $.jwlib.regExCanadaZip.test(str);
    },
    
    //Returns true if the passed in string could 
    //potentially be a valid card number.
    validateCreditCard: function(str){
        var len = $.jwlib.stripNonDigits(str).length;
        return len >= $.jwlib.cardLength && len <= $.jwlib.cardMaxLen;
    },
    
    //Returns true if the passed in string could
    //be a valid CVV code.
    validateVerificationNumber: function(str){
        return /^\d{3,4}$/.test(str);
    },
    
    //Just checks if the string is empty.
    validateAddress: function(str){
        return /^\S+.*$/.test(str);
    },
    
    validateExpDate: function(pair){
        var expDate = new Date(parseInt(pair[1]), parseInt(pair[0]));
        return expDate > new Date();
    },
    
    validateState: function(string){
        return string.indexOf('----------') < 0;
    },
       
    //Get's drag parameters from an HTML element
    //that are stored in the elements class attribute.
    getDragParam: function(element){
        var index;
        var dragParam = $.jwlib.dragParam;
        if (!element.className || 
            (index = element.className.indexOf(dragParam)) < 0){
            return null;
        }
        var end = element.className.indexOf(' ', index);
        if (end < 0)
            end = element.className.length;
        return element.className.substring(
            index + dragParam.length, 
            end);
    },
    
    //Get's drop parameters from an HTML element
    //that are stored in the elements class attribute.
    getDropParam: function(element){
        var index;
        var dropParam = $.jwlib.dropParam;
        if (!element.className || 
            (index = element.className.indexOf(dropParam)) < 0){
            return null;
        }
        var end = element.className.indexOf(' ', index);
        if (end < 0)
            end = element.className.length;
        return element.className.substring(
            index + dropParam.length, 
            end);
    },
    
    //Get legacy dd element. TODO - Remove before 5.0.
    getDDParam: function(element){
        var index;
        var DDParam = $.jwlib.DDParam;
        if (!element.className || 
            (index = element.className.indexOf(DDParam)) < 0){
            return null;
        }
        return element.className.substring(
            index + DDParam.length, 
            element.className.indexOf(' ', index));
    },
    
    drop: function(dragParam, dropParam){
        if (!dragParam || !dropParam)
            return;//Display activity?
           
        dragArgs = dragParam.split('&amp;');
        dropArgs = dropParam.split('&amp;');
        
        switch (dropArgs[0])
        {
            case 'iboxpost':
                //dropArgs 1:Url, 2:iBox title, 3: iBox Params.
                //dragArgs 1:Type, 2:ID.
                var url;
                if (0 > dropArgs[1].indexOf('?'))
                    url = dropArgs[1]+'?'+dragArgs[0]+'='+dragArgs[1];
                else
                    url = dropArgs[1]+'&'+dragArgs[0]+'='+dragArgs[1];
                
                var ibox = parseQuery(dropArgs[3].substr(5,999));
                OpenIbox(url, dropArgs[2], ibox);
                break;
            case 'callback':
                switch (dropArgs[1])
                {
                    case 'jmove':
                        //dropArgs 2: List ID, 3: List name
                        //dragArgs 1: Jott ID's
                        $.jwlib.jottList(dragArgs[1], dropArgs[2], dropArgs[3]);
                        break;
                    case 'jactivate':
                        $.jwlib.jottRecover(dragArgs[1]);
                        break;
                    case 'print':
                        $.jwlib.jottPrint(dragArgs[1]);                        
                        break;
                    case 'ctogroup':
                        Handle_ContactToGroup(dragArgs[1], args[2], args[3]);
                        break;
                    case 'removecontact':
                        Handle_RemoveContact(dragArgs[1], args[2], args[3]);
                        break;
                    case 'deletejott':
                        $.jwlib.jottTrash(dragArgs[1]);
                        break;
                    case 'deletecontact':
                        Handle_DeleteContact(dragArgs[1]);
                    default:
                        break;
                }
                break;
        }
        
    },
    
    //Change the list that the Jott belongs to.
    jottList: function(jottIds, listId, name){
        var ids = jottIds.split(';');
        for (i in ids){
            var $parent = $('input:hidden[value=\''+ids[i]+'\']').parent();
            if (!$parent.hasClass('tolist_static')) {
                $parent.hide();
                setTimeout(function(){
                    $parent.remove();
                }, 500);
            }
        }
        $.get('action.ashx?a=jottlist&i='+escape(jottIds)+
            '&y=1'+'&t=drop'+
            '&l='+listId,
            {},
            function(data){
                $.jwlib.displayAjaxCallback(data);
            });
    },
    
    jottRecover: function(jottIds){
        var ids = jottIds.split(';');
        for (i in ids){
            var $parent = $('input:hidden[value=\''+ids[i]+'\']').parent();
            if (!$parent.hasClass('torecover_static')) {
                $parent.hide();
                setTimeout(function(){
                    $parent.remove();
                }, 500);
            }
        }
        $.get('action.ashx?a=jottrecover&i='+escape(jottIds)+
            '&y=1'+'&t=drop',
            {},
            function(data){
                $.jwlib.displayAjaxCallback(data);
            });
    },
    
    jottPrint: function(jottIds){
        window.open('print.aspx?jottid='+jottIds, 'printwindow', '');
    },
    
    jottTrash: function(jottIds){
        var ids = jottIds.split(';');
        for (i in ids){
            var $parent = $('input:hidden[value=\''+ids[i]+'\']').parent();
            if (!$parent.hasClass('totrash_static')) {
                $parent.hide();
                setTimeout(function(){
                    $parent.remove();
                }, 500);
            }
        }
        $.get('action.ashx?a=jotttrash&i='+escape(jottIds)+
            '&y=1&b=true'+'&t=drop',
            {},
            function(data){
                $.jwlib.displayAjaxCallback(data);
            });
    },
    
    listReorder: function(listIds){
        $.get('action.ashx?a=listreorder&i='+escape(listIds)+
            '&y=1&f=false&b=true',
            {});    
    },
    
    contactChangeGroup: function(contactIds, groupId, name){
    },
    
    contactRemove: function(contactIds, groupId, name){
    },
    
    contactDelete: function(contactIds){
    },
    
    resendRegEmailValidation: function(phone, email, first, last, regcode, validationcode){
        $.get('action.ashx?a=resendregemail&p='+phone+'&e='+email+'&n='+first+'&l='+last+
                '&r='+regcode+'&v='+validationcode+'&y=true',
            {},
            function(data){
                $.jwlib.displayAjaxCallbackFringe(data);
            });
    },
    
    resendRegPhoneValidation: function(regId, phoneEndPointId){
        $.get('action.ashx?a=resendregphone&r='+regId+'&i='+phoneEndPointId+'&y=true',
            {},
            function(data){
                $.jwlib.displayAjaxCallbackFringe(data);
            });
    },
    
    //Shows a 'thinking' message to tell the
    //user that the website is currently 
    //performing an action.
    showThinking: function(){
        $('#feedback')
        .attr('class', 'typical')
        .html('<div class="thinking"></div>Thinking...')
        .show();
    },
    
    //Hides the 'thinking' message.
    hideThinking: function(){
        $('#feedback')
        .html('')
        .hide();
    },
    
    //Displays an activity message.  The message
    //will auto hide after the specified time
    //(0 for never hide).
    displayActivity: function(msg, time, undo, error){
        $('#feedback')
        .attr('class', error ? 'error' : 'typical')
        .html(msg)
        .append(' <a href="javascript:;" onclick="$(\'#feedback\').hide()">[X]</a>')
        .append(undo ? ' <a href="javascript:;">Undo</a>' : '')
        .show();
        
        if (0 < time){
            setTimeout(function(){$('#feedback').hide();}, time);
        }
    },
    
    //Displays the result of an ajax callback.
    displayAjaxCallback: function(data){
        var args = data.split('&amp;');
        var error = false;
        var successCode = args[0].toLowerCase();
        if (successCode == 'nserror' ||
            successCode == 'nsok')
            return;
        if (successCode == 'error')
            error = true;
        $.jwlib.displayActivity(args[1],
            0,
            false,
            error);
        return !error;
    },
    
    //Displays the result of an ajax callback.
    displayAjaxCallbackFringe: function(data){
        var args = data.split('&amp;');
        var error = false;
        var successCode = args[0].toLowerCase();
        if (successCode == 'nserror' ||
            successCode == 'nsok')
            return;
        if (successCode == 'error')
            error = true;
        $.jwlib.displayActivityFringe(args[1]);
        return !error;
    },
    
    //Displays an activity message for the fringe pages
    //(registration, login, etc.)
    displayActivityFringe: function(msg){
        $('.feedback').html(msg).show();
    },
    
    //Deletes the specified Jotts using AJAX.
    deleteJotts: function(ids, count, actionType){
        $.jwlib.showThinking();
        WebForm_DoCallback('__Page',
            'deletejott,'+actionType+','+ids,
            $.jwlib.deleteJottsCallback,
            count,
            null,
            true);
    },
    
    //Updates the Jott view after deleting Jotts.
    deleteJottsCallback: function(result, count){
        var morethanone = (count > 1) ? true : false;
        if (!result){
            var msg = 'Failed to move Jott'
                    + (morethanone ? 's' : '')
                    + ' to trash';
            $.jwlib.displayActivity(msg, 0, false, true);
            return;
        }
        
        $('#jotts')
        .html(result);
        
        //reinit the iboxes since we 
        //just dumped in a bunch of
        //new links.
        init_ibox();
        
        msg = count
                + ' Jott'
                + (morethanone ? 's ' : ' ')
                + (morethanone ? 'were' : 'was')
                + ' moved to the trash.';
        $.jwlib.displayActivity(msg, 0, false, false);
    
    },
    
    //Deletes the specified contacts using AJAX.
    deleteContacts: function(ids, count){
        $.jwlib.showThinking();
        WebForm_DoCallback('__Page', 
            'deletecontact,' + ids,
            $.jwlib.deleteContactsCallback,
            count,
            null,
            true);
    },
    
    //Updates the contact view after deleting contacts.
    deleteContactsCallback: function(result, count){
        function handleError(){
            var msg = 'Failed to delete contact'
                    + (count > 1 ? 's.' : '.');
            $.jwlib.displayActivity(msg, 0, false, true);
        };

        if (!result){
            handleError();
            return;
        }
        
        var args = result.split(',');
        if ('OK' != args[0]){
            handleError();
            return;
        }
        
        var sreplace = args[0]+','
                    + args[1]+','
                    + args[2]+',';
        var gcount = parseInt(args[2]);
        
        var $groupHeader = $('[id$=cGroupHeading]');
        var groupName = null;
        if ($groupHeader.length == 1)
            groupName = $groupHeader.html();
        
        for (var i = 0; i < gcount; ++i){
            var gname = args[i+3];
            if (gname == groupName){
                window.location = 'mygroups.aspx';
                return;
            }
            sreplace += (gname+',');
            $('.groups:has(a:contains('+gname+'))')
            .hide();
        }
        
        $('#contacts')
        .html(result.replace(sreplace, ''));
        
        //reinit the iboxes since we 
        //just dumped in a bunch of
        //new links.
        init_ibox();
   
        var morethanone = (count > 1) ? true : false;
     
        var msg = count 
                + ' contact' 
                + (morethanone ? 's ' : ' ')
                + (morethanone ? 'were' : 'was')
                + ' deleted.';
        $.jwlib.displayActivity(msg, 0, false, false);
        
        $('.selected').removeClass('selected');
    },
    
    playJott: function(jottid, eleid, start, width, height, bgcolor, version, type, wmode){
        var FO = {  
            movie:"flash/mp3player.swf?"+version,
            width:width,
            height:height,
            majorversion:"7",
            build:"0",
            bgcolor:bgcolor,
            flashvars:"file=JottAudio.ashx%3Fid="+jottid+"%26type="+type+"&showdigits=true&autostart="+start+"&showfsbutton=false" };
            
        if (wmode)
            FO.wmode = wmode;
            
        UFO.create(FO, eleid);
    },
    
    getCookie: function(c_name){
	    if (document.cookie.length>0) {
		    c_start=document.cookie.indexOf(c_name + "=");
		    if (c_start!=-1) {
		        c_start=c_start + c_name.length+1;
		        c_end=document.cookie.indexOf(";",c_start);
		        if (c_end==-1) c_end=document.cookie.length;
		        return unescape(document.cookie.substring(c_start,c_end));
		    }
		}
		return null;
	},
	
	getQueryVariable: function(variable){
        var query = window.location.search.substring(1);
        var vars = query.split("&");
        for (var i=0;i<vars.length;i++) {
            var pair = vars[i].split("=");
            if (pair[0] == variable) {
                return pair[1];
            }
        }
        return;
    } 
};

})(jQuery);
