/**
 * @author jamp
 * @dependencies jquery-1.4.1.min.js
 * @dependencies lib.js
 *
 */

function form( func, mode ){

    /**
     * @var instance this
     **/
    var self = this;

    /**
     * @var object settings
     **/
    this.settings = {
        form: '',
        useAjax: true,
        file: {
            send: '',
            message: 'ajax/form.php'
        },
        button: {
            submit: 'input[name=kontakt-senden]',
            cancel: 'input[name=kontakt-abbrechen]'
        },
        overlay: {
            background: '#000000',
            opacity: 0.8,
            zIndex: 3000
        },
        error: {
            container: {
                id: '#popupformcontainer',
                button: {
                    use: true,
                    src: 'img/buttons/buttonok.gif',
                    title: 'ok'
                },
                link: {
                    title: 'ok'
                },
                opacity: 0.8
            }
        }
    };

    /**
     * @var int error
     **/
    this.error = 0;

    /**
     * @var object chars
     **/
    this.chars = [{
        1: 'A', 2: 'B', 3: 'C', 4: 'D', 5: 'E', 6: 'F', 7: 'G', 8: 'H', 9: 'I'
    }];

    /**
     * Constructor
     *
     * @param void
     * @return void
     **/
    this.load = function(){
        self.addButtonListener();
    };

    /**
     * checks if object is a filled object
     *
     * @param object o
     * @return boolean [true|false]
     */
    this.isObject = function( o ) {
        for( i in o ) {
            return true;
        }
        
        return false;
    };

    /**
     * Sets an event handling on the form buttons
     *
     * @param void
     * @return void
     */
    this.addButtonListener = function(){
        /* set submit button */
        if( self.settings.button.submit!='' ){
            if( $( self.settings.form+' '+self.settings.button.submit ) ){
                /* equal to <input onfocus="this.blur();"... */
                $( self.settings.form+' '+self.settings.button.submit ).focus(function(){
                    $( this ).blur();
                /* sets click status */
                }).click(function(){
                    self.validate();
                });
            }
        }

        /* set cancel button */
        if( self.settings.button.cancel!='' ){
            if( $( self.settings.form+' '+self.settings.button.cancel ) ){
                /* equal to <input onfocus="this.blur();"... */
                $( self.settings.form+' '+self.settings.button.cancel ).focus(function(){
                    $( this ).blur();
                /* sets click status */
                }).click(function(){
                    self.emptyForm();
                });
            }
        }
    };

    /**
     * Checks, if field is a valid e-mail address
     *
     * @param object field
     * @return boolean [true|false]
     */
    this.isValidEmail = function( field ) {
        return jamp.isValidEmail( field );
    };

    /**
     * Serializes all form fields
     *
     * @param void
     * @return void
     **/
    this.serialize = function() {
        var data = new Array();

        /* set input, incl select, textarea fields */
        if( $( self.settings.form+' :input' ) ){
            $( self.settings.form+' :input' ).each(function(){
                if( $( this ).attr('type')!='button' ){
                    if( !( self.inObject( $( this ).attr('name'), data ) ) ){
                        data.push( { name: $( this ).attr('name'), value: $( this ).val() } );
                    }
                }
            });
        }

        /* set textarea */
        /*if( $( 'textarea' ) ){
            $( 'textarea' ).each(function(){
                data.push( { name: $( this ).attr('name'), value: $( this ).val() } );
            });
        }*/

        /* set select */
        /*if( $( 'select' ) ){
            $( 'select' ).each(function(){
                data.push( { name: $( this ).attr('name'), value: $( this ).val() } );
            });
        }*/

        return data;
    };

    /**
     * Empties form fields after successfully sending a request
     * 
     * @param void
     * @return void
     **/
    this.emptyForm = function() {
        $( ':input', $( self.settings.form ) ).each(function( i, item ) {
            switch( item.tagName.toLowerCase() ) {
                case 'input':
                    switch( item.type.toLowerCase() ) {
                        case 'hidden': case 'text': item.value = ''; break;

                        case 'radio': case 'checkbox': item.checked = ''; break;
                    }
                break;
                case 'select': item.selectedIndex = 0; break;
                case 'textarea': item.value = ''; break;
            }
        });
    }

    /**
     * Validates the typed form values
     *
     * @param void
     * @return void
     **/
    this.validate = function(){
        self.error = 0;
        
        var data = self.serialize();
        var elementArray = new Array();
        elementArray.length = 0;

        for( i in data ){
            var el = data[i];

            var tagName = $( self.settings.form+' *[name='+el.name+']' )[0].tagName;

            /*
             *  Safari 5.0+ macht Probleme mit dem "required"-Attribut. Hier wird nicht der Wert abgefragt,
             *  sondern auf [true|false|undefined] geprüft.
             */
            if( $( self.settings.form+' *[name='+el.name+']' ).attr('required')=='required' || $( self.settings.form+' *[name='+el.name+']' ).attr('required')==true ){

                if( $( self.settings.form+' *[name='+el.name+']' ).attr('type')=='text' ) {
                    elementArray.push( self.input( el ) );
                } else if( $( self.settings.form+' *[name='+el.name+']' ).attr('type')=='password' ) {
                    elementArray.push( self.password( el ) );
                } else if( $( self.settings.form+' *[name='+el.name+']' ).attr('type')=='radio' ) {
                    elementArray.push( self.radio( el ) );
                } else if( $( self.settings.form+' *[name='+el.name+']' ).attr('type')=='checkbox' ) {
                    elementArray.push( self.checkbox( el ) );
                } else if( $( self.settings.form+' *[name='+el.name+']' ).attr('type')=='hidden' ) {
                    elementArray.push( self.hidden( el ) );
                } else if( $( self.settings.form+' *[name='+el.name+']' ).attr('type')=='file' ) {
                    elementArray.push( self.file( el ) );
                } else {
                    if(tagName=='TEXTAREA') {
                        elementArray.push( self.textarea( el ) );
                    } else if(tagName=='SELECT') {
                        elementArray.push( self.select( el ) );
                    }
                }

            }
        }

        //alert(elementArray);
        

        if( self.error==0 ){
            self.send();
        } else {
            self.message( elementArray );
        }
    };

    /**
     * Checkes, if value is already in object.value
     *
     * @param string value
     * @param object messageArray
     * @return boolean [true|false]
     **/
    this.inObject = function( value, messageArray ){
        if( self.isObject( messageArray ) ){
            for( i in messageArray ){
                if( value==messageArray[i].value || value==messageArray[i].name ){
                    return true;
                }
            }
        }
    };

    /**
     * Return error/success message layout
     *
     * @param array elementArray
     * @return void
     **/
    this.message = function( elementArray ){
        var messageArray = new Array();
        messageArray.length = 0;

        if( elementArray.length>0 ){
            for( i in elementArray ){
                if( elementArray[i]!=null ){
                    var element = elementArray[i];

                    if( $( self.settings.form+' [name='+element.name+']' ).attr('title')!=undefined && $( self.settings.form+' [name='+element.name+']' ).attr('title')!='' ){
                        if( !( self.inObject( $( self.settings.form+' [name='+element.name+']' ).attr('title'), messageArray ) ) ){
                            //alert( $( self.settings.form+' [name='+element.name+']' ).attr('name') );
                            messageArray.push( { name: element.name, value: $( self.settings.form+' [name='+element.name+']' ).attr('title') } );
                        } else {
                            
                        }
                        
                    } else {
                        alert( $( self.settings.form+' [name='+element.name+']' ).attr('name') );
                    }
                }

            }
        }

        if( messageArray.length>0 ){
            var overlay = '<div id="page-overlay"></div>';
            var list = '';
            var error = '';

            list = '<ul>'
            for( i in messageArray ) {
                list += '<li>'+messageArray[i].value+'</li>';
            }
            list += '</ul>';

            error += '<div id="'+self.settings.error.container.id+'" class="'+self.settings.error.container.id+'">';
                error += '<div class="popupform">';
                    error += '<div class="list2"></div>';
                    error += '<div align="right"><a class="popupformcontainerlink" onfocus="this.blur();" href="javascript: void(0);" onclick="$(\'#'+self.settings.error.container.id+'\').fadeOut(\'slow\',function() { $(this).remove(); $(\'#page-overlay\').remove(); });" title="'+self.settings.error.container.button.title+'">';
                    
                    if( self.settings.error.container.button.use==true ) {
                        error += '<img src="'+self.settings.error.container.button.src+'" alt="'+self.settings.error.container.button.title+'" title="'+self.settings.error.container.button.title+'">';
                    } else {
                        error += self.settings.error.container.link.title;
                    }
                    error += '</a></div>';
                error += '</div>';
            error += '</div>';

            /* add html to dom */
            $( 'body' ).append( overlay+error );

            /* layout #page-overlay */
            $( '#page-overlay' ).css({
                position: 'absolute',
                top: 0,
                left: 0,
                width: $( document ).width()+'px',
                height: $( document ).height()+'px',
                opacity: self.settings.overlay.opacity,
                background: self.settings.overlay.background,
                zIndex: self.settings.overlay.zIndex
            });

            $( '#'+self.settings.error.container.id+' .popupform .list2' ).append( list );

            $( '#'+self.settings.error.container.id ).css({
                position: 'absolute',
                top: ( ( $( window ).height()/2 )+( $( window ).scrollTop() )-( $( '#'+self.settings.error.container.id ).height()/2 ) ),
                left: ( $( document ).width()/2 )-( $( '#'+self.settings.error.container.id ).width()/2 ),
                opacity: self.settings.error.container.opacity,
                zIndex: self.settings.overlay.zIndex+100
            }).fadeIn('slow');

            $( window ).scroll(function() {
                $( '#'+self.settings.error.container.id ).css({ top : ( ( $( window ).height()/2 )+( $( window ).scrollTop() )-( $( '#'+self.settings.error.container.id ).height()/2 ) ) });
            });
        }

    };

    this.input = function( el ){
        var error = 0;
        var element = $( self.settings.form+' input[name='+el.name+']' );

        if( element!=undefined ) {

            if( element.attr('validate')=='text' ) {
                if( element.val()=='' ){
                    self.error++;
                    error++;
                }
            } else if( element.attr('validate')=='int' ){
                if( isNaN( parseInt( element.val() ) ) ){
                    self.error++;
                    error++;
                }
            } else if( element.attr('validate')=='email' ){
                if( self.isValidEmail( self.settings.form+' input[name='+el.name+']' )==false ){
                    self.error++;
                    error++;
                }
            }

            if( error==0 ){
                return null;
            } else {
                return el;
            }

        }

        return null;
    };

    this.password = function( el ){
        var error = 0;
        var element = $( self.settings.form+' input[name='+el.name+']' );

        if( element!=undefined ) {

            if( element.val()=='' ){
                self.error++;
                error++;
            }

            if( error==0 ){
                return null;
            } else {
                return el;
            }

        }

        return null;
    };

    this.radio = function( el ){
        var error = 0;
        var element = self.settings.form+' input[name='+el.name+']';

        if( $( element )!=undefined ) {

            $( element ).each(function(){
                if( $( this ).attr('checked')==false ){
                    self.error++;
                    error++;
                }

            });

            if( error==0 ){
                return null;
            } else if( error>0 && $( element+':checked').length<=0 ) {
                return el;
            }

        }

        return null;

    };

    this.checkbox = function( el ){
        var error = 0;
        var element = $( self.settings.form+' input[name='+el.name+']' );
        var multicheck = 0;

        if( element!=undefined ) {
            if( element.attr('group')!='' || element.attr('group')!=undefined ){

                // Checkboxhack
                var gruppen = [];
                $('input[group='+element.attr('group')+']').each(function(){
                    var g = $(this).attr('group');
                    if( g && $.inArray(g,gruppen)===-1 ) gruppen.push(g);
                });

                var nochNichtGewaehlteGruppen = [];
                for( var i in gruppen ){
                    var clicked = false;
                    $('input[group='+gruppen[i]+']').each(function(){
                        if(this.checked) clicked = true;
                    });
                    if( !clicked ) nochNichtGewaehlteGruppen.push(gruppen[i]);
                }

                if( nochNichtGewaehlteGruppen.length!=0 ){
                    self.error++;
                    error++;
                }
            } else {
                if( element.attr('checked')==false ){
                    self.error++;
                    error++;
                }
            }



            if( error==0 ){
                return null;
            } else {
                return el;
            }

        }

        return null;

    };

    this.hidden = function( el ){ return null; };

    this.file = function( el ){ return null; }

    this.textarea = function( el ){
        var error = 0;
        var element = $( self.settings.form+' textarea[name='+el.name+']' );

        if( element!=undefined ) {

            if( element.val()=='' ){
                self.error++;
                error++;
            }

            if( error==0 ){
                return null;
            } else {
                return el;
            }

        }

        return null;

    }

    this.select = function( el ){
        var error = 0;
        var element = $( self.settings.form+' select[name='+el.name+']' );

        if( element!=undefined ) {
            if( $( self.settings.form+' select[name='+el.name+'] option:selected' ).length==0 || ( $( self.settings.form+' select[name='+el.name+'] option:first' ).attr('selected')==true && $( self.settings.form+' select[name='+el.name+'] option:first' ).val()=='' ) ){
                self.error++;
                error++;
            }

            if( error==0 ){
                return null;
            } else {
                return el;
            }

        }

        return null;

    }

    /**
     * Sends serialized data to an ajax file
     *
     * @param string data
     * @return void
     */
    this.send = function(){
        if(self.settings.useAjax){
            var data = $( self.settings.form ).serialize();

            var modeString = '';
            if( mode!=null || mode!=undefined ){
                modeString = mode+'&';
            }

            $.ajax({
                url: self.settings.file.send,
                data: modeString+data,
                type: 'post',
                success: function( html ){
                    self.emptyForm();

                    if(func!='') {
                        func( html );
                    }
                }
            });
        } else {
            $( self.settings.form ).submit();
        }
    };
    

}
