(function($){
    var 
        drpdwn_height    = 26,
        search_func = function( search_string , value )
            {
                var
                    regex = new RegExp( escape( value ) , "i" );
                                                
                $( search_string )
                    .each(
                        function()
                            {                                    
                                if( !regex.test( $( this ).text() ) )
                                    $( this )
                                        .removeClass( 'show' );
                            }
                        );
            },
        escape = function( str )
            {
                return str.replace(new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"), "\\$&");
            };

    $('.dropdown_container')
        //Het laten zien van de lijst
        .live( 'show_list' , function()
            {
                var $container     = $( '.dropdown_box_container' , $( this ) ),
                    $list        = $( 'div.dropdown_box_list' , $container.parent() );

                $container.trigger( 'pos_list' );

                $list.show();
            }
        )
        //Het verstoppen van de lijst
        .live( 'hide_list' , function()
            {
                var $container     = $( '.dropdown_box_container' , $( this ) ),
                    $list        = $( 'div.dropdown_box_list' , $container.parent() );

                $list.hide();
            }
        )
        //Het positioneren van de lijst
        .live( 'pos_list' , function()
            {
                var $container    = $( '.dropdown_box_container' , $( this ) ),
                    pos            = $container.position(),
                    $list        = $( 'div.dropdown_box_list' , $container.parent() ),
                    margin        = parseInt($container.css("margin-left").replace( "px" , "" ), 10) || 0;

                $list
                    .css(
                        {
                            top        : ( pos.top + drpdwn_height ) + "px",
                            //TODO FIX THIS
                            left    : ( pos.left + margin ) + "px"
                        }
                    );
            }
        )
        //De click op een item handlen
        .live( 'handle_click' , function( e , sel_id )
            {
                var
                    $container    = $( this ),
                    $sel_li        = $( 'ul li#' + sel_id , $container ),
                    cont_data    = $container
                                    .data( "dropdown" ),
                    sel_aantal    = $( 'li.choice' , $container ).length;
                            
                if( !$sel_li.hasClass( 'optgroup' ) )
                {
                    if( sel_aantal === cont_data.max_select_items && cont_data.max_select_items > 1 )
                    {
                        if( $sel_li.is( '.choice' ) )
                        {
                            $sel_li
                                .removeClass( 'choice' )
                                .children( ':checkbox' )
                                .removeAttr( 'checked' );
                        }
                        else
                            $container.trigger( 'max_select_reached' );
                    }
                    else if( cont_data.max_select_items === 1 )
                    {
                        var 
                            $val_field = $( 'input[type=hidden]' , $container );
                        
                        //Keuze class verwijderen bij de anderen, omdat er maar 1 geselecteerd kan worden
                        $( 'li.choice' , $container )
                            .removeClass( 'choice' );
                        
                        //Keuze class toevoegen
                        $sel_li
                            .addClass( 'choice' );
                        
                        //Wijziging doorvoeren in het hidden field
                        $val_field
                            .val( sel_id.replace( "val_" , "" ) );
                        
                        //List hiden
                        $( this ).trigger( 'hide_list' );
                    }
                    else
                    {                            
                        if( $sel_li.is( '.choice' ) )
                        {
                            $sel_li
                                .removeClass( 'choice' );
                        
                            //De checkbox checken
                            if( $( ':checkbox' , $sel_li ).length > 0 )
                                $( ':checkbox' , $sel_li ).removeAttr( 'checked' );
                        }
                        else
                        {
                            //De keuze doorvoeren
                            $sel_li
                                .addClass( 'choice' );

                            //De checkbox checken
                            if( $( ':checkbox' , $sel_li ).length > 0 )
                            {                                    
                                $( ':checkbox' , $sel_li ).attr( 'checked' , true );
                            }
                        }
                    }
                    $( this )
                        .trigger( 'change_value' );
                }
                else
                {
                    $( this ).trigger( 'cant_select_optgroup' );
                }
                $(this)
                    .trigger("dropdown_callback", [sel_id.replace("val_","") , $container]);
            }
        )
        //Value wijzigen
        .live( 'change_value' , function()
            {
                var 
                    $container    = $( this ),
                    $var_field    = $container
                                    .children( '.dropdown_box_container' )
                                    .children( '.dropdown_box_value' ),
                    $list        = $container
                                    .children( 'div.dropdown_box_list' )
                                    .children( 'ul' ),
                    selected    = $( '.choice' , $list )
                                    .length,
                    destValue    = "",
                    $contData    = $container.data("dropdown"),
                    change        = true;
                    
                if( $( 'input' , $var_field ).length > 0 && !$( 'input' , $var_field ).is( '.no_search') )
                    change = false;
                
                if( change )
                {
                    if( selected === 1 )
                        //Als er 1 geselecteerd is: value = value van die li
                        destValue = $.trim( $( 'li.choice span' , $list ).html() );
                    else if( selected > 1 )
                        //Als er meer geselecteerd zijn: 10 items geselecteerd
                        destValue = selected + " items geselecteerd";
                    else if( $( 'li.optgroup span' , $list  ).length > 0 )
                    {
                        //Bij 0 geselecteerde items: eerste optgroup value
                        destValue = $.trim( $( 'li.optgroup:first span' , $list ).html() );
                        
                        $( 'input:text:hidden' , $container )
                            .val( '' );
                    }
                    else
                    {
                        $( 'li:first' , $container )
                            .addClass( 'choice' );
                        
                        $( 'input:text:hidden' , $container)
                            .val( ($( 'li.choice' , $container ).attr( 'id' )||"").replace("val_","") );
                        
                        //Geen optgroup: gewoon eerste value
                        destValue = $.trim( $( 'li:first span' , $list ).html() );
                    }

                    // Toevoeging: maximale aantal selecties aan het einde
                    
                    if( $contData.max_select_items > 1 )
                        destValue += " (max. " + $contData.max_select_items + ")";

                    //Hier krijgt het field ook echt zn value
                    if( $( 'input' , $var_field ).length >= 1 )
                    {
                        if( $( 'input' , $var_field ).is( '.no_search' ) )
                        {
                            //Wanneer er een textfield aanwezig is: value daarvan wijzigen
                            $var_field
                                .children( 'input' )
                                .val( destValue );
                        }                        
                    }
                    else
                        //Anders gewoon de html van de div wijzigen
                        $var_field
                            .html( destValue );
                }
            }
        );

    //Click op de button
    $( 'div.dropdown_box_button, div.dropdown_box_value' )
    //$( 'div.dropdown_box_container' )
        .live( 'click' , function( e )
            {
                var $container     = $( this )
                                    .parent()
                                    .parent(),
                    $list        = $( 'div.dropdown_box_list' , $container );

                $( '.dropdown_container' )
                    .not( $container )
                    .trigger( 'hide_list' );

                if( $list.is( ':hidden' ) )
                    $container
                        .trigger( 'show_list' );
                else if( !$( e.target ).is( 'input' ) )
                    $container
                        .trigger( 'hide_list' );
                
                //Zorgen dat het event niet naar het document bubbled
                e.stopImmediatePropagation();
                return false;
            }
    );
    
    //De zoek variabele waar de timeout in staat
    var zoeken;
    
    //De keyup event, hier wordt dus gezocht!:D
    $( 'div.dropdown_box_value input' )
        .live( 'keyup' , function( e )
            {
                window
                    .clearTimeout( zoeken );
                
                var    
                    search        = $( this )
                                    .val(),
                    $container    = $( this )
                                    .closest( '.dropdown_container' ),
                    prev_search    = $container
                                    .data( "dropdown" )
                                    .last_search
                                ||
                                  search,
                    jQuery_src    = "div.dropdown_box_list ul li.show";
                
                if( search.substr( 0 , search.length - 1 ) !== prev_search )
                    $( 'div.dropdown_box_list ul li' )
                        .addClass( 'show' );
                
                zoeken = setTimeout( 
                            function()
                                {
                                    search_func( jQuery_src , search );
                                } 
                            , 200 );
                
                $container
                    .data( "dropdown" )
                    .last_search = search;
            }
        );
    // 
    // $( 'div.dropdown_container div.dropdown_box_list ul li.show :checkbox' )
    //     .live( 'click' , function( e )
    //         {
    //             alert( 'checkbox click bubble' );
    //             
    //             if( $( this ).is( ':checked') )
    //                 $( this ).removeAttr( 'checked' );
    //             else
    //                 $( this ).attr( 'checked' , true );
    //         }
    //     );
    $( 'div.dropdown_container div.dropdown_box_list ul li.show' )
        .live( 'click' , function( e )
             {
                var
                    $container     = $( this )
                                    .closest( 'div.dropdown_container' ),
                    $target        = $( e.target ),
                    li_id        = $( this )
                                    .attr('id') || 0;
                
                $( this ).trigger( 'handle_click' , [ li_id ] );

                e.stopImmediatePropagation();

                return false;
            }
        );
    
    //Hover, omdat internet explorer pauper is
    $( 'div.dropdown_box_list ul li' )
        .live( 'mouseover' ,
            function()
                {
                    $( 'div.dropdown_box_list ul li.selected' )
                        .removeClass( 'selected' );
                    
                    $( this ).addClass( 'selected' );
                } )
        .live( 'mouseout' , 
            function()
                {
                    $( 'div.dropdown_box_list ul li.selected' )
                        .removeClass( 'selected' );
                }
            );


    $( document )
        .bind( 'click' , function( e )
            {
                if( !$( e.target ).is( 'div.dropdown_box_list :checkbox' ) )
                    $( '.dropdown_container' ).trigger( 'hide_list' );
            }
        );
    
    $.fn.dropdown = function(options2) {
        var defaults = {
            select_list                : true,
            filter_items            : false,
            max_select_items        : 1,
             button_background        : '/templates/default/images/drpdwn_pijl.png',
             button_background_click    : '/templates/default/images/drpdwn_pijl.png',
             button_background_hover    : '/templates/default/images/drpdwn_pijl.png',
            text_value                : 'items geselecteerd',
            total_width                : 290,
            total_height             : 250, 
            lelijk                    : true,
            callback                : function( val, object ){ },
            verplicht                : false
        };
        
        var options = $.extend(defaults, options2),
            trim     = function(value) 
                {
                      value = value.replace(/^\s+/,'');
                    value = value.replace(/\s+$/,'');
                    return value;
                },
            format_li = function( type , $option , name )
                {
                    var val        = $option.val() || "",
                        text    = $option.attr('label') || $option.html() || "";
            
                    if( $option.is( 'optgroup' ) )
                    {
                        return "<li class=\"optgroup show\"><span>" + text + "</span></li>";
                    }
                    else if( $option.is( 'option' ) )
                    {
                        var multiple = false,
                            selected = $option.is( ':selected' );
                        
                        if( $option.val() !== "" )
                        {
                            if( type === "multiple" )
                            {
                                if( selected )
                                    return "<li class=\"choice show\" id=\"val_" + val + "\"><input type=\"checkbox\" name=\"" + name + "\" checked=\"checked\" value=\"" + val + "\" /><span>" + text + "</span></li>";
                                else
                                    return "<li class=\"show\" id=\"val_" + val + "\"><input type=\"checkbox\" name=\"" + name + "\" value=\"" + val + "\" /><span>" + text + "</span></li>";
                            }
                            else
                            {
                                if( selected )
                                    return "<li class=\"choice show\" id=\"val_" + val + "\"><span>" + text + "</span></li>";
                                else
                                    return "<li class=\"show\" id=\"val_" + val + "\"><span>" + text + "</span></li>";
                            }
                        }
                        else
                        {
                            return "<li class=\"optgroup show\"><span>" + text + "</span></li>";
                        }
                    }
                };

        return this.each(function(){
            var search_value     = '',
                id                 = Math.floor(Math.random() * 999999),
                $container        = (options.select_list ? $( '<div />' ).addClass( "dropdown_container"    ).insertAfter( $( this ) ) : $( this ) );
                //$label            = $( 'label[for=]' );
            		
            if( options.select_list !== true )
            {
                if( $( this ).is( 'select' ) )
                {
                    options.select_list = true;
                }
            }
            
            //De styles
            var styles = {
                dropdown_box_container : 'width:' + options.total_width + 'px;' + ( options.lelijk ? '' : 'margin-left:8px;' ),
                dropdown_box_list : 'min-width:' + options.total_width + 'px; max-height: ' + options.total_height + 'px; overflow-y:scroll;',
                dropdown_box_value : 'width:' + ( options.total_width - 35 ) + 'px;',
                dropdown_box_button : 'background:url(\'' + options.button_background_hover + '\') center center no-repeat'
            };
            
            if($(this).is('.obl'))
                options.verplicht = true;
            
            if( options.select_list )
            {
                var $select     = $( this ),
                    sel_name    = $select.attr( 'name' ),
                    sel_id        = $select.attr( 'id' ) || false;
                                
                // Max select items instellen op het juiste aantal
                if( $select.attr('multiple') !== undefined && $select.attr('multiple') !== false )
                {
                    if( options.max_select_items === 1 )
                        options.max_select_items = 0;
                }
                else
                {
                    options.max_select_items = 1;
                }
                
                $container
                    .prepend('<div class="dropdown_box_container" style="' + styles.dropdown_box_container + '"><div class="dropdown_box_value" style="' + styles.dropdown_box_value + '"></div><div class="dropdown_box_button" style="' + styles.dropdown_box_button + '"></div></div><div class="dropdown_box_list" style="' + styles.dropdown_box_list + '"><ul></ul></div>');    
            
                if( options.max_select_items === 1 )
                {
                    $container.append( '<input type="hidden" ' + ( options.verplicht ? 'class="obl"' : '' ) + ' name="' + sel_name + '" value="" />' );
                }
                else
                    $( '.dropdown_box_list ul' , $container )
                        .addClass( 'multiple' );
                
                if( options.filter_items )
                    $( '.dropdown_box_value' ,  $container )
                        .append( '<input type=\"text\" class=\"no_search\" style=\"width: ' + ( options.total_width - 35 ) + 'px;\" />' );
                                
                var $ul = $( 'ul' , $container );
                
                if( sel_id !== false )
                    $ul.attr( 'id' , sel_id );
                
                $select
                    .children( 'option, optgroup' )
                    .each(function()
                        {
                            if( $( this ).is( 'option' ) )
                                $ul.append( 
                                    format_li( ( options.max_select_items !== 1 ? "multiple" : "single" ) , $( this ) , sel_name ) 
                                );
                            else
                            {
                                $ul.append( 
                                    format_li( ( options.max_select_items !== 1 ? "multiple" : "single" ) , $( this ) , sel_name ) 
                                );
                                                                
                                $( this )
                                    .children( )
                                    .each(function()
                                        {
                                            $ul.append(
                                                format_li( ( options.max_select_items !== 1 ? "multiple" : "single" ) , $( this ) , sel_name )
                                            );
                                        }
                                    );
                            }
                        }
                    );
                
                if( $select.is( '.manditory' ) ) 
                    $container.addClass( 'manditory' );
			} else {
			    var $container = $( this ).closest('.dropdown_container');
			
			}			
			
            if( options.max_select_items === 1 )
                $( 'input:hidden' , $container )
                    .val( ( $( '.choice' , $container ).attr('id') || "" ).replace("val_","") );
    
            //Dit moet hier binnen de each omdat jquery nog geen focus ondersteund in live events
            if( options.filter_items )
                $( 'input' , $container )
                    .bind( 'focus' , function()
                        {
                            if( $( this ).is( '.no_search' ) )
                                $( this )
                                    .removeClass( 'no_search' )
                                    .val( '' );
                            
                            $( this )
                                .trigger( 'click' );
                        }
                    )
                    .bind( 'blur' , function()
                        {
                            if( $.trim( $( this ).val() ) === "" )
                            {
                                $( this )
                                    .addClass( 'no_search' );
                                
                                $container
                                    .trigger( 'change_value' );
                            }
                        }
                    );
  
            if( options.select_list )
                $select.remove();
            
            $container
                .data( "dropdown" , options )
                .bind("dropdown_callback", function(e, val , object) { options.callback(val , object); })
                .trigger( 'change_value' );
            
            return this;
        });
    }
})(jQuery);
