/* Copyright (c) 2008 ilhan Kuzgun (http://www.birtek.com.tr)
 * Licensed with prayware. Pray and use. Feel free to do anything.
 * Just keep good feelings.
 * $LastChangedDate: 2008-05-10 11:00:36 $
 * Version 0.2
 */

 /**
 * NEEDS THESE PLUGINS
 *      JQUERY
 *      METADATA
 *      UI.resizable
 *      BGFRAME (for fixing ie6 combobox problem)
 */

 /**
 * This plugin for usage input text for using "choosing multiple"
 * from the list. Choisen option's keys will be in the input
 * with seperating commas.
 *
 * Usage:
 *  <input type='text' name='someName' id='someId' data='{"availables":{"first":"First Option", "second":"Second Option"}}'>
 *
 *  $('#someId').multipleSelect({maxWidth:250, maxHeight:250 }); // more option available
 *
 *
 **/
;(function($) {
     $.fn.multipleSelect = function( options ){
        options = $.extend({
                showSelected : false,
                resizable: true,
                maxWidth:200,
                maxHeight: 200,
                minWidth: 150,
                minHeight: 50,
                captionText : "please select"
            }, options);

        return this.each(function(){

            var $this = $(this);
            var $span, $pane, $table, onClickSpan = false;
            var $showSpan;
            var selected = [];
            var data = {};

            if(options.showSelected){
                $showSpan = $("<span></span>");
                $showSpan.insertBefore($this);
            }
            // I dont know why, when I select some option then focus other multiple select area, input is not triggering focus event. Is that a bug?
            // So solve the problem by click event redirecting focus.
            $this.bind("click",createSelect);
            //$this.bind("focus",createSelect);
            $this.bind("blur",removeSelect);
            if($.trim($this.val())!="")
                selected = $this.val().split(",");

            function _findPos (obj) {
                while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
                    obj = obj.nextSibling;
                }
                var position = $(obj).offset();
                return [position.left, position.top + obj.offsetHeight];
            }
            function createSelect(e){
                if($span)return true;

                $table = $("<table class='form' style='width:100%;'><caption>"+options.captionText+"</caption><colgroup><col style='width:20px;'/><col style='white-space:nowrap;'/></colgroup></table>");
                data = $this.metadata().availables;
                $.each(data, function(i,n){
                    if( typeof n != "object" ) {
                        $table.append("<tr class='multTr'><td><input type='checkbox' value='"+i+"' ></td><td>"+n+"</td></tr>");
                    }
                });
                //if the text is so long show as title because table size is fixed
                $('tr.multTr td', $table).each(function(){$(this).attr("title",$(this).text());});
                $(':checkbox', $table).bind("click", function(event){
                    var key = $(this).val();
                    //alert('k='+key+', chk='+box.attr("checked"));
                    if($.inArray(key, selected)>=0){
                       selected = $.grep(selected, function(value){
                           return value!=key;
                       });
                    }else{
                       selected[selected.length]=key;
                    }
                    $this.val(selected.join(","));

                    if(options.showSelected ){
                        $showTable = $("<table class='form sortTable' style='width:100px;'></table>");
                        $.each(selected,function(i,n){
                           $showTable.append("<tr><td>"+data[n]+"</td></tr>");
                        });
                        $showSpan.html($showTable);
                    }
                    return true;
                });

                var pos = _findPos($this[0]);

                $pane = $("<div></div>")
                         .attr('id','xxx')
                         .append($table)
                         .css({'z-index':9999,'overflow-y':'auto', 'overflow-x':'hidden', 'width':'99%' });

                $span = $("<span></span>")
                         .append($pane)
                         .attr('id', 'yyy')
                         .css({'background-color':'#ff0','width':130, 'height':100}) // start width height, actually not needed
                         .css({'position':'absolute','top':pos[1], 'left':pos[0]});

                // If bgFrame is available so do it. Fix ie6
                if ( $.fn.bgiframe ){
                    $span.bgiframe();
                }

                $("body").append($span);

                $pane.css({height: ($table.height() > options.minHeight)?(  ($table.height() < options.maxHeight)? $table.height() : options.maxHeight ):options.minHeight});
                $span.css({height: ($pane.height() +10)
                          ,width: ($this.width() +10) });

                if(options.resizable)
                   $span.resizable({
                        transparent:false, autohide:false,   // maxHeight is height of table. But if table will be more long think it with next version??
                        maxWidth: options.maxWidth, maxHeight: $pane.height() + 10, minWidth: options.minWidth, minHeight: options.minHeight,
                        resize: function(){$pane.css('height', $span.height()-10+'px');}
                });
                $(document.body).bind("mousedown",_checkExternalClick);

                $.each(data,function(i,n){
                   if($.inArray(i, selected)>=0){
                       $('input[value='+i+']',$table).attr("checked",true);
                   }
                });
            }
            function removeSelect(){
                if(!onClickSpan && $span){
                    $span.remove();
                    $span = null;
                    $(document.body).unbind("mousedown",_checkExternalClick);
                }
            }
            function _checkExternalClick(event) {
                var $target = $(event.target);
                if($span)
                if ( $target.attr('id') == $this.attr('id')    //tıklanan eleman inputsa
                 ||  $target.attr('id') == $span.attr('id')        //Ya da span ise ya da spanın içindeki elemanlardan biri ise
                 ||  $target.parents('#'+$span.attr('id')+'').length > 0 ) {
                    onClickSpan= true;
                }else {
                    onClickSpan = false;
                    removeSelect();
                }
            }
        });

    };
})(jQuery);
