/*
 *      ################################################################################################
 *      ###########################      VALIDATOR            CLASS       ##############################
 *      ################################################################################################
 *
 *
 *      Usage:
 *          - Import it; <script type="text/javascript" src="PATH_TO_FILE/validator.class.js"></script>
 *
 *          - Add the attr "validate" to the element you wish to validate.
 *              » E.g. <input type="text" name="email" id="email" validate="email" />
 *
 *              » Types of validation supported:
 *                  - email
 *                  - name
 *                  - phone / phone_pt
 *                  - required
 *                  - password / repassword
 *
 */



// #########################################    SETTINGS    ############################################

var alerts = false;                /* true = JavaScript alerts show up when field validation fails  ||  false = Appending a span to the element with the invalid value; */
var lang   = "pt";                 /* "en" = english  ||  "pt" = portuguese || "fr" = french; || "de" = german || "it" = italian */
var alternate_invalid_gui = true;  /* true = Shows errors with a dashed red border and a asterisk || false = shows errors in a default way */

/* Used if this landing has TIMWE */
var club_id     = "";
var textvariant = "";
var tracking_id = "";

// ########################################## END SETTINGS; ############################################



/* _____________________________________________________________________________________________________
 *
 *          #########               DO  NOT  EDIT  AFTER  THIS  LINE!                   #########
 * _____________________________________________________________________________________________________
 */



var array_lang = new Array();
var xml_lang   = "js/validator.langs/";
var obj_left   = "";
var obj_top    = "";
var obj_width  = "";


$( function() {

    /* Load language XML */
    switch(lang)
    {
        case 'pt':
            xml_lang += "pt.xml";
            break;

        case 'de':
            xml_lang += "de.xml";
            break;

        case 'fr':
            xml_lang += "fr.xml";
            break;

        case 'it':
            xml_lang += "it.xml";
            break;

        case 'en':
        default:
            xml_lang += "en.xml";
            break;
    }
    
    /* F5 abuse fix */
    setTimeout ( function() {load_lang_XML();}, 100);
    /* _________________ */



    /**
     * #####################################################################
     * --------------------- Real time validations -------------------------
     * #####################################################################
     **/

    /* numbers only */
    $("[validate=numbers]").keydown( function(event) {
        var k = event.keyCode;
        return ( (k > 34 && k < 58 && event.shiftKey == false) || (k > 95 && k < 106 && event.shiftKey == false) || k == 8 ) ? true : false;
    });

    /* phone numbers only */
    $("input[validate*=phone]").keydown( function(event) {
        var k = event.keyCode;
        return ( (k > 34 && k < 58 && event.shiftKey == false) || (k > 95 && k < 106 && event.shiftKey == false) || k == 8 ) ? true : false;
    });



    /**
     * #####################################################################
     * ------------------ On form submission validations -------------------
     * #####################################################################
     **/
    
    $("form").submit( function() {

        $('input[type=submit]').attr('disabled', true);
        $(".__invalid_field").remove();

        var valid_fields = 0;           /* 0 = No errors; -1 = validation errors; -2 = used for timwe validation */
        var errors       = array_lang["sentence"] + "\n\n";

        /*  ###################      INPUT   TESTING      ##################  */
         /* Custom Validations */
        $("select").each( function() {
            if ($(this).find('option:selected').val() == '' ||
                $(this).find('option:selected').val() == '-1')
            {
                if (!alerts)
                {
                    create_error_element(this, 'Escolha inválida!');
                }
                valid_fields = -1;
                errors += "- Escolha inválida\n";
            }
        });

        $("input").each( function() {
            
            obj_width = $(this).width();
            obj_left  = $(this).offset().left + obj_width;
            obj_top   = $(this).offset().top  + 6;                                  /* "+6" - align fix */

            switch( $(this).attr('validate') )
            {
                case 'email':                                                       /* Email, has to be a valid email */
                    if( !validate_email($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " + array_lang["email"] + "\n";
                    }
                    break;

                case 'name':                                                        /* Names, can only contain characters */
                    if( !validate_name($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " + array_lang["name"] + "\n";
                    }
                    break;

                case 'numbers':                                                     /* Numbers, can only contain digits */
                    if( !validate_numbers_only($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " + array_lang["numbers"] + "\n";
                    }
                    break;

                case 'phone':                                                       /* Regular Phones with (9-14 digits) */
                    if( !validate_phone($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " + array_lang["contact"] + "\n";
                    }
                    break;

                case 'phone_pt':                                                    /* Portuguese Phone Numbers (9 digits, 2|9--------) */
                    if( !validate_phone_pt($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " + array_lang["contact"] + "\n";
                    }
                    break;

                case 'required':                                                    /* Required field (not null) */
                    if( !validate_required($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " +array_lang["required"] + "\n";
                    }
                    break;

                case 'password':                                                    /* Strong password required */
                    if( !validate_password($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " +array_lang["password"] + "\n";
                    }
                    break;

                case 'repassword':                                                  /* Same password in both fields (#password and #repassword) */
                    if( !validate_repassword($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " +array_lang["repassword"] + "\n";
                    }
                    break;

                case 'timwe_pass':                                                  /* Validate TIMWE password (usually, 4 random numbers) */
                    if( !validate_timwepass($(this)) )
                    {
                        valid_fields = -1;
                        errors += "- " +array_lang["repassword"] + "\n";
                    }
                    break;
            }
            
        });
        /* _________________________ !INPUT TESTING _________________________ */


        /**
         * #####################################################################
         * ------------------        TimWe Validations       -------------------
         * #####################################################################
         **/

        if ( $('[id^=timwe]').length > 0 && valid_fields == 0 )
        {
            var phone_nr = $('#phone').val();
            var operator = $('#operator').val();
            var var_id   = $('[id^=timwe]').attr('id');
            
            if( var_id == "timwe_subscribe" )   /* First step, subscribe */
            {
                var curr_subs  = $('#timwe_subscribe').val();
                if( curr_subs != '' )           /* Probably second call, seen as it has been filled */
                {
                    if( curr_subs.substr(0, 2) == 'OK' )
                    {
                        return true;
                    }
                    else
                    {
                        alert('Não foi possivel completar o seu pedido devido ao facto: ' + curr_subs.substr(3, curr_subs.length) );
                        $('#timwe_subscribe').val('');

                        /* Fechar a colorbox */
                        $.colorbox.close();
                        return false;
                    }
                }
                else                            /* No call has been made, due to the fact it hasn't been filled */
                {
                    $.ajax({
                        url: 'http://tools.adclick.pt/timwe/portugal.php?action=subscribe&clubid=' + club_id + '&textvariant=' + textvariant + '&tracking=' + tracking_id + '&phone=' + phone_nr + '&operator=' + operator,
                        dataType: 'script',
                        complete: function(data) {
                            /* To be changed */

                            /*  This is how it should be...
                             *
                             * $('#timwe_whatever').val(data); // data is = "-17|MESSAGE_ERROR_IN_PROPER_LANG" || "OK|98sa9dasd9812dashj"
                             * $('form').submit();
                             * 
                             */
                        }
                    });
                }
            }
            else                        /* Second step, password */
            {
                var curr_pw  = $('#timwe_password').val();
                var curr_pin = $('#password').val(); /* Fetch current pin */
                if( curr_pw != '' )     /* Probably second call, seen as it has been filled */
                {
                    if( curr_pw.substr(0, 2) == 'OK' )
                    {
                        return true;
                    }
                    else
                    {
                        alert('Não foi possivel completar o seu pedido devido ao facto: ' + curr_pw.substr(3, curr_pw.length) );
                        $('#timwe_password').val('');

                        /* Fechar a colorbox */
                        $.colorbox.close();
                        return false;
                    }
                }
                else                    /* No call has been made, due to the fact it hasn't been filled */
                {
                    $.ajax({
                        url: 'http://tools.adclick.pt/timwe/portugal.php?action=password&clubid=' + club_id + '&phone=' + phone_nr + '&password=' + curr_pin + '&operator=' + operator,
                        dataType: 'script',
                        complete: function(data) {
                            /* To be changed */

                            /*  This is how it should be...
                             *
                             * $('#timwe_whatever').val(data); // data is = "-17|MESSAGE_ERROR_IN_PROPER_LANG" || "OK|98sa9dasd9812dashj"
                             * $('form').submit();
                             *
                             */
                        }
                    });
                }

            }
            valid_fields = -2;
        }
        /* ##################################################################### */



        /**
         * #####################################################################
         * ------------------         ENABLE COLORBOX        -------------------
         * #####################################################################
         **/
        $.colorbox({
            html   :  '<span style="color: gray; font-style: bold; font-size: 20px;">' + array_lang["loading"] + '</span></div>',
            escKey : false,
            overlayClose: false
        });
        /* ##################################################################### */


        
        /* Remove 'disabled' attr on the submit button */
        $('input[type=submit]').removeAttr('disabled');


        /* If alerts are set to true and there are errors, show them: */
        if(valid_fields == -1)
        {
            if(alerts)
            {
                alert(errors);
            }
            /* Fechar a colorbox */
            $.colorbox.close();
        }


        /* Finally, return true to $form submission, if no errors were found (which is equal to '0') */
        if( valid_fields == 0 )
        {
            return true;
        }
        else
        {
            return false;
        }
        
    });

    /* Append span's css, <IF> they're being appended due alerts being set to 'false': */
    if(!alerts)
    {
        $("head").append("<style>" +
                         ".__invalid_field { color: red; font-weight: bold; font-size: 10px; font-style: italic; position: absolute; padding: 2px 3px; border: 1px dotted red; " +
                         "                     margin-left: -20px; margin-top: 3px; background: white; cursor: pointer; }\r\n" +
                         ".__invalid_field_obj { border: 1px dashed red !important; }\r\n" +
                         ".__invalid_field_obj_value { color: red; font-weight: bold; font-size: 30px; position: absolute; margin-left: -8px; margin-top: -2px; cursor: pointer;}\r\n" +
                         "</style>");
    }

    /* __________________________________________________________________________ */

}); /* END  $.ready; */







/**
 *
 * #################################################################################
 * #################################################################################
 * #################################################################################
 *
 * --------------------------------- FUNCTIONS -------------------------------------
 *
 * #################################################################################
 * #################################################################################
 * #################################################################################
 *
 **/




function appendErrorToElement(e, obj)
{
    if(!alerts)
    {
        if (!alternate_invalid_gui)
        {
            $(obj).parent().append("<span class='__invalid_field' onclick='$(this).remove();'> * " + e + "</span>");
        }
        else
        {
            $(obj).addClass('__invalid_field_obj');
            $(obj).focus(function(){
                $(this).removeClass('__invalid_field_obj');
            });
            $(obj).parent().append("<span class='__invalid_field_obj_value' onclick='$(this).remove();'>*</span>");
        }
    }
}


/**
 * Field that requires a valid email address
 *
 * Returns: boolean;
 */
function validate_email(obj)
{
    var regExp = /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i;
    if ( $(obj).val().search(regExp) == -1 )
    {
        appendErrorToElement(array_lang["email"], obj);
        return false;
    }
    return true;
}

/**
 * Field that can not be left blank
 *
 * Returns: boolean;
 */
function validate_required(obj)
{
    var text = trim_string($(obj).val());
    if ( text == "" )
    {
        appendErrorToElement(array_lang["required"], obj);
        return false;
    }
    return true;
}

/**
 * Field can only take numbers, one or more
 *
 * Returns: boolean;
 */
function validate_numbers_only(obj)
{
    var regExp = /^\s*\d+\s*$/;
    if( $(obj).val().search(regExp) == -1 )
    {
        appendErrorToElement(array_lang["numbers"], obj);
        return false;
    }
    return true;
}

/**
 * Field can only take phone numbers (9 - 14 digits)
 *
 * Returns: boolean;
 */
function validate_phone(obj)
{
    var regExp = /^\s*\d{9,14}\s*$/;
    if( $(obj).val().search(regExp) == -1 )
    {
        appendErrorToElement(array_lang["contact"], obj);
        return false;
    }
    return true;
}

/**
 * Field can only take phone numbers (9 digits, starts with a '2' - PT specific)
 *
 * Returns: boolean;
 */
function validate_phone_pt(obj)
{
    var regExp = /^[2|9]\d{8}$/;
    if( $(obj).val().search(regExp) == -1 )
    {
        appendErrorToElement(array_lang["contact"], obj);
        return false;
    }
    return true;
}

/**
 * Field can only characters
 *
 * Returns: boolean;
 */
function validate_name(obj)
{
    var text   = $(obj).val();
    var regExp = /^(([a-zA-z-']|[ÀÁÂÃÄÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäçèéêëìíîïòóôõöùúûüýÿ]){2,}(\s?|[-'])){1,4}$/;
    if( text.search(regExp) == -1 )
    {
        appendErrorToElement(array_lang["name"], obj);
        return false;
    }
    return true;
}


/**
 * Field requires at least one caps letter and 7 other letters / numbers / special chars
 *
 * Returns: boolean;
 */
function validate_password(obj)
{
    var text   = $(obj).val();
    var regExp = /(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/
    if( text.search(regExp) == -1 )
    {
        appendErrorToElement(array_lang["password"], obj);
        return false;
    }
    return true;
}


/**
 * Field requires at least 4 numbers
 *
 * Returns: boolean;
 */
function validate_password(obj)
{
    var text   = $(obj).val();
    var regExp = /[0-9]{4,}/
    if( text.search(regExp) == -1 )
    {
        appendErrorToElement(array_lang["password"], obj);
        return false;
    }
    return true;
}


/**
 * Tests if the password confirmation field value is equal to the password field
 *
 * Returns: boolean;
 */
function validate_repassword(obj)
{
    var text_repass = $(obj).val();
    var text_pass   = $("[validate=password]").val();
    if( text_repass != text_pass )
    {
        appendErrorToElement(array_lang["repassword"], obj);
        return false;
    }
    return true;
}


/**
 * Remove spaces from string
 *
 * Returns: boolean;
 */
function trim_string(s)
{
    return s.split(' ').join('');
}

/**
 * Remove special chars
 *
 * Returns: boolean;
 */
function clean_string(s)
{
    return s.replace(/[^\w|^\+|^-]*/g, "");

}

/**
 * Load XML file with language details;
 */
function load_lang_XML()
{
    $.get(xml_lang, function(d)
    {
        try
        {
            $(d).find('message').each( function() {
                switch ($(this).find('source').text())
                {
                    case 'The following data is incorrect':
                        array_lang["sentence"] = $(this).find('source').next().text();
                        break;

                    case 'Invalid email':
                        array_lang["email"] = $(this).find('source').next().text();
                        break;

                    case 'Invalid name':
                        array_lang["name"] = $(this).find('source').next().text();
                        break;

                    case 'Numbers only':
                        array_lang["numbers"] = $(this).find('source').next().text();
                        break;

                    case 'Invalid contact details':
                        array_lang["contact"] = $(this).find('source').next().text();
                        break;

                    case 'Required field':
                        array_lang["required"] = $(this).find('source').next().text();
                        break;

                    case 'Password is too weak':
                        array_lang["password"] = $(this).find('source').next().text();
                        break;

                    case 'Passwords do not match':
                        array_lang["repassword"] = $(this).find('source').next().text();
                        break;

                    case 'Loading, please wait':
                        array_lang["loading"] = $(this).find('source').next().text();
                        break;
                }
            });
        }
        catch (e)
        {
            console.log("ERROR!\n\nLoading '" + lang + "' language failed! \n\n( " + e + " )");
        }

    });
}

