/*
    * Form Sender jQuery Plugin v1.1b
    * Made for Nigel S. Ball and Chris Lang
    * @author Jaycliff Arcilla
    
    Requires jQuery 1.6.x
    
    Version History:
    
    v1.1b   -   Added default form-checking routines
            -   Added 'dataType' option (default is 'html')
    v1.1    -   Modified to adapt to jQuery 1.6.x preferences [changed all attr() methods to prop()]
    v1.0    -   Initial release
*/

(function($){
    
    /*
        See http://docs.jquery.com/index.php?title=Core/fn.extend for more details on jQuery.fn.extend
    */
    
    jQuery.fn.extend({
        
        formSender: function(user_defined_options){
            
            /* Insert all plugin-specific code inside this anonymous function */
            
            // Insert all default option values here
            var default_options = {
                serverSideFormProcessorURL: '',
                waitText: 'Please wait...',
                redirectText: 'Redirecting...',
                resubmitText: 'Resubmit form',
                method: 'POST',
                dataType: 'html',
                executeBeforeSend: function(obj){
                    
                    var failsend = false;
                    
                    function inputIsEmpty(value){
                        var i;
                        if(typeof value == 'undefined' || value == '')return true;
                        for(i in value){
                            if(value[i] != ' ')return false;
                        }
                        return true;
                    }
                    
                    if(obj.find('input[name="first_name"]').length != 0){
                        var firstName = obj.find('input[name="first_name"]');
                        firstName.data('default_border',firstName.css('border')).data('line-height',firstName.css('line-height'));
                    }
                    else {
                        failsend = true;
                    }
                    
                    if(obj.find('input[name="last_name"]').length != 0){
                        var lastName = obj.find('input[name="last_name"]');
                        lastName.data('default_border',lastName.css('border')).data('line-height',lastName.css('line-height'));
                    }
                    else {
                        failsend = true;
                    }
                    
                    if(obj.find('input[name="full_name"]').length != 0){
                        var fullName = obj.find('input[name="full_name"]');
                        fullName.data('default_border',fullName.css('border')).data('line-height',fullName.css('line-height'));
                    }
                    
                    if(obj.find('input[name="email_address"]').length != 0){
                        var emailAddress = obj.find('input[name="email_address"]');
                        emailAddress.data('default_border',emailAddress.css('border')).data('line-height',emailAddress.css('line-height'));
                    }
                    else {
                        failsend = true;
                    }
                    
                    if(inputIsEmpty(firstName.prop('value')) || firstName.prop('value') === '' || firstName.prop('value') === undefined || firstName.prop('value') === null){
                        firstName.css('border','solid 1px #f00').css('line-height',firstName.data('line-height'));
                        firstName.prop('value','');
                        failsend = true;
                    }
                    else {
                        firstName.css('border',firstName.data('default_border'));
                    }
                    
                    if(inputIsEmpty(lastName.prop('value')) || lastName.prop('value') === '' || lastName.prop('value') === undefined || lastName.prop('value') === null){
                        lastName.css('border','solid 1px #f00').css('line-height',lastName.data('line-height'));
                        lastName.prop('value','');
                        failsend = true;
                    }
                    else {
                        lastName.css('border',lastName.data('default_border'));
                    }
                    
                    if(inputIsEmpty(fullName.prop('value')) || fullName.prop('value') === '' || fullName.prop('value') === undefined || fullName.prop('value') === null){
                        fullName.css('border','solid 1px #f00').css('line-height',fullName.data('line-height'));
                        fullName.prop('value','');
                        //failsend = true;
                    }
                    else {
                        fullName.css('border',fullName.data('default_border'));
                    }
                    
                    if(inputIsEmpty(emailAddress.prop('value')) || emailAddress.prop('value') === '' || emailAddress.prop('value') === undefined || emailAddress.prop('value') === null){
                        emailAddress.css('border','solid 1px #f00').css('line-height',emailAddress.data('line-height'));
                        emailAddress.prop('value','');
                        failsend = true;
                    }
                    else {
                        emailAddress.css('border',emailAddress.data('default_border'));
                    }
                    
                    /* Avoid the strict warning JSMSG_ANON_NO_RETURN_VALUE by always returning a value no matter what */
                    
                    if(failsend) return false;
                    else return true;
                    
                },
                executeOnFinish: function(obj){
                    if(obj.serverReturnedData.search('errorcode:666') != -1){
                        
                        obj.messageContainer.html(obj.serverReturnedData.substring(obj.serverReturnedData.indexOf(':')+4));
                        obj.submitButton.setContent(obj.submitButton.data('otext')).enable();
                        
                    }
                    else {
                        
                        obj.messageContainer.html('');
                        obj.submitButton.setContent('Submitted!');
                        
                        if(obj.find('input[name="redirect_url"]').length != 0){
                            var redirect_to = obj.find('input[name="redirect_url"]').prop('value');
                            if(obj.find('input[name="send_details"]').length != 0)redirect_to+='?firstname='+obj.find('input[name="first_name"]').prop('value');
                            window.top.location.href = redirect_to;
                        }
                        else alert('Message is sent!');
                        
                    }
                }
            }
            
            /* This function mimics PHP's handy isset function. Unlike the php variant, this doesn't work with undeclared variables. A great shame. */
            function isset(variable){
                if(variable === null || variable === '' || variable === undefined) return false;
                else return true;
            }
            
            if(!isset(user_defined_options)) user_defined_options = default_options; // If the user didn't pass any parameter, set options with the default one
            else user_defined_options = jQuery.extend(default_options,user_defined_options); // ^Otherwise, update the default options with the user-defined ones
            
            /* This function sets the inner text of submit buttons. Calling this function without the 'content' parameter backs up the original text as a jQuery data */
            function setSubmitterMessage(obj,content){
                var tag_name = obj.get(0).nodeName; /* the get() method returns the dom element itself */
                var backup;
                if(!isset(obj.data('otext'))){
                    backup = true;
                    if(!isset(content))content = '';
                }
                switch(tag_name.toLowerCase()){
                    case 'input':
                        switch(obj.prop('type')){
                            case 'submit':
                                if(isset(backup))obj.data('otext',obj.prop('value'));
                                obj.prop('value',content);
                                break;
                            case 'image':
                                if(isset(backup))obj.data('otext',obj.prop('alt'));
                                obj.prop('alt',content);
                                break;
                        }
                        break;
                    case 'button':
                        var lo = obj;
                        while(lo.children().length > 0){
                            lo = lo.children().eq(0); /* the eq() method returns a jQuery object based on the given index */
                        }
                        if(isset(backup))obj.data('otext',lo.html());
                        lo.html(content);
                        break;
                }
            }
            
            this.each(function(){ /* 'this' here contains the jquery object itself (the one calling this plugin) so no need to wrap it with jQuery() */
                
                var options = user_defined_options; /* Makes a local set of options for each object */
                var formObject = jQuery(this); /* 'this' here, however, refers to the HTML dom element itself so you have to wrap it with jQuery() to use, uh, jQuery methods */
                var ssfp_url; /* Server-side Form Processor URL. Now you know. :p */
                formObject.submitButton = formObject.find('button[type="submit"], input[type="submit"], input[type="image"]');
                
                if(formObject.find('input[name="submitted"]').length == 0)formObject.prepend('<input type="hidden" name="submitted" value="true" />');
                if(formObject.find('div.note').length == 0)formObject.append('<div class="note"></div>');
                
                formObject.messageContainer = formObject.find('div.note');
                
                formObject.submitButton.setContent = function(content){
                    this.each(function(){
                        setSubmitterMessage(jQuery(this),content);
                    });
                    return this;
                };
                
                formObject.submitButton.disable = function(){
                    this.each(function(){
                        jQuery(this).prop({disabled:true});
                    });
                    return this;
                };
                
                formObject.submitButton.enable = function(){
                    this.each(function(){
                        jQuery(this).prop({disabled:false});
                    });
                    return this;
                };
                
                formObject.serverReturnedData = null;
                
                formObject.submit(function(event){
                    
                    var form_data = jQuery(this).serialize(); /* Converts form data into standard URL-encoded notation (e.g. 'fname=Jaycliff&lname=Arcilla') */
                    if(options.serverSideFormProcessorURL == ''){
                        if(formObject.prop('action') == ''){
                            //alert("Please provide a url for the server-side form processor\n\nExample: http://www.yoursite.com/form.php");
                            formObject.messageContainer.html('<div style="border:solid 1px #f00;padding:10px;margin:10px;"><strong style="color:#f00;">Error: No target url specified</strong><br /><br />Please provide the url of the server-side form processor.<br /><strong>Example: http://www.yoursite.com/form.php</strong></div>');
                            event.preventDefault();
                            return;
                        }
                        else {
                            ssfp_url = formObject.prop('action');
                        }
                    }
                    else ssfp_url = options.serverSideFormProcessorURL;
                    
                    formObject.submitButton.setContent(options.waitText).disable();
                    
                    if(typeof options.executeBeforeSend === 'function'){
                        var before_send_return_value = options.executeBeforeSend(formObject);
                        if(before_send_return_value === false || before_send_return_value === 0 || before_send_return_value === null) {
                            
                            //alert('The function returned false. Form submission failed.');
                            formObject.submitButton.setContent(formObject.submitButton.data('otext')).enable();
                            event.preventDefault();
                            return;
                            
                        }
                        else {
                            //alert('The function returned either true or nothing. Form submission will continue');
                        }
                        
                    }
                    else {
                        alert('Error: Value for \'executeBeforeSend\' must be a function');
                        formObject.submitButton.setContent(formObject.submitButton.data('otext')).enable();
                        event.preventDefault();
                        return;
                    }
                    
                    jQuery.ajax({
                        
                        type: options.method,
                        url: ssfp_url,
                        dataType: options.dataType,
                        data: form_data,
                        success: function(ssfp_msg){
                            
                            formObject.serverReturnedData = ssfp_msg;
                            if(typeof options.executeOnFinish === 'function')options.executeOnFinish(formObject);
                            
                        }
                        
                    });
                    
                    event.preventDefault(); // Prevents the form element from performing its default action (form submission)
                    
                });
                
            });
            
            return this; /* Returns the calling object to maintain jQuery's 'chainability' */
            
        }
        
    });
    
})(jQuery);
