/**
 * @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: '',
        file: {
            send: '',
            message: 'ajax/form.php'
        },
        button: {
            submit: 'input[name=kontakt-senden]',
            cancel: 'input[name=kontakt-abbrechen]'
        },
        overlay: {
            background: '#ffffff',
            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;

    this.errorMode = 0;
    this.messageMode = '';
    this.messageId='';
    /**
     * @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(errorMode,messageMode,messageId){
        self.addButtonListener();
        self.errorMode=errorMode;
        self.messageMode=messageMode;
        self.messageId=messageId;
    };

    /**
     * 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;
            }
        });
    };

    self.unsetError = function( id ){
        $(id).css('border','').css('border-bottom','1px #4F8095 solid');
    };

    /**
     * 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;

            if( self.errorMode==1 ){
                self.unsetError(self.settings.form+' *[name='+el.name+']');
            }

            /*
             *  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();
            if( self.errorMode==1 ){
                $('#validieren-error').html( '' );
            }
        } else {
            self.message( elementArray );
            if( self.errorMode==1 ){
                $('#validieren-error').html('Validierungsfehler: Bitte nach oben scrollen.');
            }
        }
    };

    /**
     * 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(self.messageMode==''){

            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') );
                                $( self.settings.form+' [name='+element.name+']' ).css('border','1px red solid');

                                messageArray.push( { name: element.name, value: $( self.settings.form+' [name='+element.name+']' ).attr('title') } );
                            } else {
                                //$( self.settings.form+' [name='+element.name+']' ).css('border','0');
                            }

                        } 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 ) ) });
                });
            }
        } else {
            var msg = '';
            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 ) ) ){
                                $( self.settings.form+' [name='+element.name+']' ).css('border','1px red solid');
                                
                            }
                        }

                        //msg += 'Feld: '+$( self.settings.form+' [name='+element.name+']' ).attr('name')+" => Wert: "+$( self.settings.form+' [name='+element.name+']' ).val()+"<br />";
                    }
                }

                
            }

            //$(self.messageId).html( msg );
        }

    };

    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')=='intnull'){
                if( isNaN( parseInt( element.val() ) ) || parseInt( element.val() )<=0 ){
                    self.error++;
                    error++;
                }

            } else if( element.attr('validate')=='plzger' ){
                if( isNaN( parseInt( element.val() ) ) || parseInt( element.val().length )<5 ){
                    self.error++;
                    error++;
                }
            } else if( element.attr('validate')=='bonauszug' ){
                if( parseInt( element.val().length )>17 ){
                    self.error++;
                    error++;
                }
            } else if( element.attr('validate')=='blz' ){
                if( element.val()=='' || parseInt( element.val().length )!=8 ){
                    self.error++;
                    error++;
                }
            } else if( element.attr('validate')=='ipaddress' ){
                var ipRE = new RegExp( "^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$" );
                if( !ipRE.test( 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 ) {

            if( $( element+':checked').length<=0 ){
                self.error++;
                error++;
            }

            /*$( 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+']' );

        if( element!=undefined ) {

            if( element.attr('checked')==false ){
                self.error++;
                error++;
            }

            if( error==0 ){
                return null;
            } else {
                return el;
            }

        }

        return null;*/

        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(){
        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 ){
                if(self.messageMode==''){
                    self.emptyForm();
                }
                
                if(func!='') {
                    func( html );
                }
            }
        });
    };
    

}
