/**
 * 
 * Common jQuery plugins for the UI
 * 
 * @category gogoyoko
 */

//live search score
String.prototype.score = function(abbreviation,offset) {
  offset = offset || 0; // TODO: I think this is unused... remove

  if(abbreviation.length == 0) return 0.9;
  if(abbreviation.length > this.length) return 0.0;

  for (var i = abbreviation.length; i > 0; i--) {
    var sub_abbreviation = abbreviation.substring(0,i);
    var index = this.indexOf(sub_abbreviation);


    if(index < 0) continue;
    if(index + abbreviation.length > this.length + offset) continue;

    var next_string       = this.substring(index+sub_abbreviation.length);
    var next_abbreviation = null;

    if(i >= abbreviation.length)
      next_abbreviation = '';
    else
      next_abbreviation = abbreviation.substring(i);

    var remaining_score   = next_string.score(next_abbreviation,offset+index);

    if (remaining_score > 0) {
      var score = this.length-next_string.length;

      if(index != 0) {
        var j = 0;

        var c = this.charCodeAt(index-1);
        if(c==32 || c == 9) {
          for(var j=(index-2); j >= 0; j--) {
            c = this.charCodeAt(j);
            score -= ((c == 32 || c == 9) ? 1 : 0.15);
          }

          // XXX maybe not port this heuristic
          //
          //          } else if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:[self characterAtIndex:matchedRange.location]]) {
          //            for (j = matchedRange.location-1; j >= (int) searchRange.location; j--) {
          //              if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:[self characterAtIndex:j]])
          //                score--;
          //              else
          //                score -= 0.15;
          //            }
        } else {
          score -= index;
        }
      }

      score += remaining_score * next_string.length;
      score /= this.length;
      return score;
    }
  }
  return 0.0;
};



/**
 * jQuery plugins
 */
(function($){
    /**
     * CONTAINS
     * a workaround for the lack of the contains() functino in FF
     * @see http://www.quirksmode.org/blog/archives/2006/01/contains_for_mo.html
     */
    if (window.Node && Node.prototype && !Node.prototype.contains){
            Node.prototype.contains = function(arg){
                    return !!(this.compareDocumentPosition(arg) & 16);
            };
    }
	
    /**
     * When a user selects an input files,
     * it's content is removed. If the user
     * changes, the new value will stay, else
     * the old value is returned
     */
    $.fn.clear_input = function(){
            return this.each(function(){
                    var text;
                    //FOCUS
                    //	on focus
                    $(this).focus(function(){
                            if($(this).val()==this.defaultValue){
                                    $(this).val('');
                            }else{
                                    //TODO this doesn't work on webkit browsers
                                    this.select();
                            }
                            text = $(this).val();
                    });
                    //BLUR
                    //	on blur
                    $(this).blur(function(){
                            if( $(this).val()=='' ){
                                    $(this).val(this.defaultValue);
                            }
                    });
            });
    };


    /**
     * Accordion menu
     * @todo finish
     */
    $.fn.menu_accordion = function(){
            return this.each(function(){
                    $('> li a',this).click(function(){
                            $(' > ul',$(this).parent()).toggle();
                    });
            });
    }

    /**
     * MENU
     * 
     * A menu is like a dialog that has no header or footer
     * and therefor no close/cancel/ok... buttons
     */
    $.fn.menu = function(trigger){
            var d = this[0];
            //REMOVE
            //	remove menu from sight (hide)
            var clean = function(event){
                    if(!d.contains(event.target)){
                            $(d).stop().animate({
                                    top: '-=60px',
                                    opacity: 'toggle'
                            },'middle');
                            $(document).unbind('mouseup',clean);				
                    }
            };
            //TRIGGER EVENT
            //	on trigger... display menu or hide
            $(trigger).click(function(event){
                    event.preventDefault();
                    event.stopPropagation();
                    if( $(d).css('display') == 'none' ){
                            $(d).stop().animate({
                                    top: '+=60px',
                                    opacity: 'toggle'
                            },'middle');
                            $(document).bind('mouseup',clean);
                    }else{
                            clean(event);
                    }
            });
            //RETURN
            //	return the complete menu
            //	ie. return the wrapper DIV element
            return $(d);
    };


     $.fn.menu_show = function(anchor){

             return this.each(function(){
                            //REMOVE
                            //	remove menu from sight (hide)
                            var clean = function(event){
                                    if(!d.contains(event.target)){
                                            $(d).stop().animate({
                                                    top: '-=25px',
                                                    opacity: 'toggle'
                                            },'middle');
                                            $(document).unbind('mouseup',clean);				
                                    }
                            };
                            //WRAPPER
                            //	wrapp element in menu markup
                            var d = $(this).wrap([
                            '<div style="display:none; position:absolute;" class="ui-dialog ui-widget-content ui-corner-all undefined">',
                            '<div class="ui-dialog-content ui-widget-content"></div>',
                            '</div>'
                            ].join('')).parents('.ui-dialog')[0];
                            var pos = $(anchor).offset();
                            $(d).css({
//					top: pos.top,
//					left: pos.left
                            });

                            $(d).stop().animate({
                                    top: '+=5px',
                                    opacity: 'toggle'
                            },'middle');
                            $(document).bind('mouseup',clean);

             });
     };

     /**
      * Confirm navigate away from form
      * 
      * If a form has been changed, and is not
      * beeing submitted when navigated away from a
      * page... "R U sure" modal will be displayed
      */
     $.fn.changeconfirm = function(message){
             var msg = message || '';
             this.each(function(){
                     $(this).change( function(){
                             window.onbeforeunload = function(){return msg;};
                     });
                     $(this).submit(function(){
                             window.onbeforeunload = function(){};
                     });
             });
     };


    /**
    *
    * jQuery livesearch
    *
    * A port of the Quicksilver string ranking algorithm
    * "hello world".score("axl") //=> 0.0
    * "hello world".score("ow") //=> 0.6
    * "hello world".score("hello world") //=> 1.0
    */
   $.fn.liveUpdate = function(list){

        list = jQuery(list);

        if ( list.length ) {
            var rows = list.children('li'),
                cache = rows.map(function(){
                    return this.innerHTML.toLowerCase();
                });

            this
                .keyup(filter).keyup()
                .parents('form').submit(function(){
                    return false;
                });
        }

        return this;

        function filter(){
            var term = jQuery.trim( jQuery(this).val().toLowerCase() ), scores = [];

                    //ugly ugly hint hack, sowwy! :/ - einarb
            if ( !term || term.toString() == 'type in your topic') {
                rows.show();
            } else {
                rows.hide();

                cache.each(function(i){
                    var score = this.score(term);
                    if (score > 0.8) { scores.push([score, i]); }
                });

                jQuery.each(scores.sort(function(a, b){return b[0] - a[0];}), function(){
                    jQuery(rows[ this[1] ]).show();
                });
            }
        }
    };

})(jQuery);


