// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
// 
// $(document).ready(function() {

// 
// });

// From http://zuzara.com/blog/2010/05/15/jquery-plugin-for-twitter-oauth-via-popup-window-facebook-style/
jQuery.oauthPopup = function(options) {
    options.windowName = options.windowName ||  'ConnectWithOAuth'; // should not include space for IE
    options.windowOptions = options.windowOptions || 'location=0,status=0,width=900,height=500';
    options.callback = options.callback || function(){ window.location.reload(); };
    var that = this;

    that._oauthWindow = window.open(options.path, options.windowName, options.windowOptions);
    that._oauthInterval = window.setInterval(function(){
        if (that._oauthWindow.closed) {
            window.clearInterval(that._oauthInterval);
            options.callback();
        }
    }, 1000);
};

// Makes hints appear and disappear for .blur input fields 
jQuery.fn.blurHint = function() {
	return this.each(function() {
		var $input = jQuery(this);
		var default_value = $input.attr('default_value');
		var value = $input.val();
		if (default_value !== undefined) {
		    this.defaultValue = default_value;
		    this.value = value;
		};
		
		// wierd issue with IE line feeds so remove line feeds from comparison...
		if (this.value.replace(/[\n\r]/g, '') != this.defaultValue.replace(/[\n\r]/g, '')) {
		    $input.removeClass('blur').addClass('focus');
		}
		    
		$input.focus(function() {
			if (this.value.replace(/[\n\r]/g, '') == this.defaultValue.replace(/[\n\r]/g, '')) {
				$input.removeClass('blur').addClass('focus');
				$input.parent().parent().find('button').removeClass('blur').addClass('focus');
				if ($input.hasClass('tweet_reply'))
				    this.value = $input.parent().find('#username').val();
				else
				    this.value = '';
			};
		});
		
		$input.blur(function() {
			if ( (this.value == '') || (this.value == $input.parent().find('#username').val()) ) {
				$input.removeClass('focus').addClass('blur');
				$input.parent().parent().find('button').removeClass('focus').addClass('blur');
				this.value = this.defaultValue;
			};
		});
	})
};


// makes border blue when focused, gray when blurred/unfocused
jQuery.fn.changeFocusBlurColor = function() {
	return this.each(function() {
		$(this).focus( function() {
	  	$(this).css('border-color', '#006699');
	  });
	  $(this).blur( function() {
	  	$(this).css('border-color','#ccc');
	  });
	})
};


// makes field editable
jQuery.fn.editable = function() {
	return this.each(function() {
		var $editable = $(this);
		$editable.click( function() {
	  	    $editable.find('form').show();
	  	    $editable.find('.item_content').hide();
	    });
	    
	    $editable.find('.cancel').click( function() {
	        $(this).parent().hide();
	        $(this).parent().parent().find('.item_content').show();
	        return false;
	    });
	})
};


// modalDialog is just a dialog with my site-specific default settings, but takes optional settings to pass on to dialog()
jQuery.fn.modalDialog = function(options) {
	return this.each(function() {
		var $container = jQuery(this);
		var settings = jQuery.extend({
			autoOpen: false,
    	    bgiframe: true,
    	    modal:true,
    	    resizable: false,
			draggable: true
		}, options);
		
		$container.dialog(settings);
	})
};

// Opens the dialog named '#dialog' by default on clicking object
jQuery.fn.dialogOnClick = function(dialog_selector) {
	var $dialog = $(dialog_selector || '#loading_dialog')
	
	return this.each(function() {
		$(this).click(function() {
			$dialog.dialog('open');
		})
	})
};

jQuery.fn.showFormOnClick = function() {
    return this.each(function() {
        var $form_link = $(this);
        $form_link.parent().find('form:first').hide();
        $form_link.show();

        $form_link.click(function() {
            $this = $(this);
            $form = $this.parent().find('form:first');
            $this.hide();
            $form.show();
            $form.find('textarea:first').focus();
            return false;
        });
    })
};

jQuery.fn.showWheelOnClick = function() {
    return this.each(function() {
        $(this).click(function() {
            $(this).parent().find('img.wheel').show();
        });
    })
};

jQuery.fn.oauthPopupOnClick = function(message) {
    return this.each(function() {
        $(this).dialogOnClick('#oauth_dialog');
        
        $(this).click(function(){
            $this = $(this);

            // Change oauth_dialog name
            $('#oauth_dialog span.oauth_consumer').text($this.attr('oauth_consumer'));

            $.oauthPopup({
                path: $this.attr('href'),
                callback: function(){
                    window.location = $this.attr('callback');
                }
            });

            return false;
        });
    })
};

// jQuery.fn.expandOnClick = function() {
//     return this.each(function() {
//         $(this).click(function() {
//             $expand_link = $(this);
//             $expand_link.parent().parent().find('.comment').fadeIn('slow');
//             $expand_link.parent().parent().find('.form_link').click();
//             $expand_link.parent().remove();
//             return false;
//       });
//     })
// };

// checking/unchecking text boxes will update #person_xxx_list
jQuery.fn.updateListOnClick = function(list_selector) {
	var $list = $(list_selector) || '#person_skill_list'
	
	return this.each(function() {        
		$(this).click(function() {
			var tag = $(this).val().toLowerCase();
            var tagRegex = new RegExp(tag, "g");
            var list_value = $list.val().toLowerCase();
			
			if ($(this).is(":checked")) {
              $list.val( list_value + ',' + tag );
              $list.formatTagList();
            }
            else {
              $list.val( list_value.replace(tagRegex, '') );
              $list.formatTagList();
            }
		})
	})
};


// checking/unchecking text boxes will update tag_list
jQuery.fn.formatTagList = function() {
	return this.each(function() {        
		var list_value =  $(this).val().toLowerCase();
        // add ', ' to end of line as this is autocomplete delimiter
        list_value = list_value + ", "
        // replace commas with or without spaces before, after or between commas Globally with a single comma
        list_value = list_value.replace(/ ?,[, ]*/g, ', ')
        // get rid of beginning of line commas 
        list_value = list_value.replace(/^[, ]+/g, '')
        
        // assign new value
        $(this).val( titleCaps(list_value) );
	})
};

// Hides unless success
jQuery.fn.hideUnlessSuccess = function() {
    return this.each(function() {
        var $this = $(this)
        if (!$this.hasClass('success') && !$this.hasClass('header') && !$this.hasClass('balance') )
            $this.toggle();
    })
};

// Title Caps function
// from: http://ejohn.org/blog/title-capitalization-in-javascript/
(function(){
    var small = "(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v[.]?|via|vs[.]?)";
    var punct = "([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]*)";

    this.titleCaps = function(title){
    	var parts = [], split = /[:.;?!] |(?: |^)["Ò]/g, index = 0;

    	while (true) {
    		var m = split.exec(title);

    		parts.push( title.substring(index, m ? m.index : title.length)
    			.replace(/\b([A-Za-z][a-z.'Õ]*)\b/g, function(all){
    				return /[A-Za-z]\.[A-Za-z]/.test(all) ? all : upper(all);
    			})
    			.replace(RegExp("\\b" + small + "\\b", "ig"), lower)
    			.replace(RegExp("^" + punct + small + "\\b", "ig"), function(all, punct, word){
    				return punct + upper(word);
    			})
    			.replace(RegExp("\\b" + small + punct + "$", "ig"), upper));

    		index = split.lastIndex;

    		if ( m ) parts.push( m[0] );
    		else break;
    	}

    	return parts.join("").replace(/ V(s?)\. /ig, " v$1. ")
    		.replace(/(['Õ])S\b/ig, "$1s")
    		.replace(/\b(AT&T|Q&A)\b/ig, function(all){
    			return all.toUpperCase();
    		});
    };

    function lower(word){
    	return word.toLowerCase();
    }

    function upper(word){
      return word.substr(0,1).toUpperCase() + word.substr(1);
    }
})();


// Assigns tooltip functionality to <a> links
jQuery.fn.tooltipLink = function() {
	return this.each(function() {
		$(this).tooltip({
			bodyHandler: function() {
      	return $($(this).attr("href")).html();
	    },
	    showURL: false,
	    track: true,
	    delay: 0, 
	    fade: 250
		})	
	})
};

// Fancy bubble tooltip
jQuery.fn.bubbleTipLink = function() {
	return this.each(function() {
		$(".bubble_tip").tooltip({ 
    	bodyHandler: function() {
	    	return $($(this).attr("href")).html();
	    },
	    track: true, 
	    delay: 0,
	    fade: 250, 
	    showURL: false, 
	    opacity: 1, 
	    fixPNG: true, 
	    extraClass: "pretty fancy", 
	    top: -15, 
	    left: 5 
	  }); 
	})
};


// sets up the hover image for activity feed items  
jQuery.fn.imgHover = function() {
	return this.each(function() {
		$(this).tooltip({
		  showURL: false,
		  bodyHandler: function() {
		    var i = $(this).children()[0]
		    var imgsrc = $(i).attr('src');
		    return $('<img src="'+imgsrc+'" />');
		  }
	  });
	})
};

// Pretty effects when hovering over activity lists
jQuery.fn.listHover = function() {
    return this.each(function() {
        var $list = $(this);
        $list.find('.action').hide();
        $list.hover(
            function () {
                $list.addClass('hover');
                $list.find('.action').show();
            },
            function () {
                $list.removeClass('hover');
                $list.find('.action').hide();
            })
    })
};

// Checks all boxes on page if clicked
jQuery.fn.selectAll = function() {
    return this.each(function() {
        $(this).click(function() {
            var checked_status = this.checked;
            $(':checkbox').each(function(){this.checked = checked_status;});
        });
    })
};

// Renders link unclickable and displays alert instead
jQuery.fn.alertOnClick = function(message) {
    return this.each(function() {
        $(this).click(function() {
            alert(message);
            return false;
        });
    })
};

// Checks all child checkboxes if clicked
// from http://www.learningjquery.com/2008/12/quick-tip-click-table-row-to-trigger-a-checkbox-click
jQuery.fn.checkableRow = function() {
    return this.each(function() {
        $(this)
            .filter(':has(:checkbox:checked)')
            .addClass('selected')
            .end()
        .click(function(event) {
            $(this).toggleClass('selected');
            if (event.target.type !== 'checkbox') {
                $(':checkbox', this).attr('checked', function() {
                    return !this.checked;
                });
            }
        })
    })
};


// Resets form, re-blur default texts and re-ajaxify all ajax forms/links on page
jQuery.fn.resetForm = function() {
    return this.each(function() {
        this.reset();
        this.beenSubmitted = false;
        $(this).find(".focus").addClass('blur');
        $(this).find(".focus").removeClass('focus');
        ajaxLinks();
        $("textarea.blur, input:text.blur").blurHint();	
    })
};
  

function ajaxNewTweetLinks() {
    // Bring up form when clicking "Reply" to tweets
    $('a.new_tweet').click(function() {
      var screen_name = $(this).attr('screen_name')
      var twitter_account = $(this).attr('twitter_account')
      var tweet_id = $(this).attr('tweet_id')
      var in_reply_to_status_id = $(this).attr('in_reply_to_status_id')
      var rel = $(this).attr('rel')
      var action = $(this).attr('action')

      // Opens dialog
      $('#new_tweet_dialog').dialog('open');

      // Displays in_reply_to_tweet, note different CSS applies as inside #new_tweet_dialog in _dialog.sass
      $('#in_reply_to_tweet').empty().append( $('#tweet_' + tweet_id).html() );

      // Updates various fields that are useful
      $('#tweet_text').val( '@' + screen_name + ' ' );
      $('#tweet_in_reply_to_status_id').val( in_reply_to_status_id );
      $('form#new_tweet').attr('action', action );
      $('#ui-dialog-title-dialog_new_tweet').text( 'Reply to @' + screen_name );

      // clobbers the default <a> action otherwise window moves about
      return false;
    });

    // Disable submit button on click and show 'loading'
    $('form#new_tweet #submit_button').click(function() {
      $('#new_tweet_dialog').dialog('close');
      $('#loading_dialog').dialog('open');
    })
    
}
  




/*
Jquery and Rails powered default application.js
Easy Ajax replacement for remote_functions and ajax_form based on class name
All actions will reply to the .js format
Unostrusive, will only works if Javascript enabled, if not, respond to an HTML as a normal link
respond_to do |format|
  format.html
  format.js {render :layout => false}
end
*/
 
jQuery.ajaxSetup({ 'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")} })
 
function _ajax_request(url, data, callback, type, method) {
    if (jQuery.isFunction(data)) {
        callback = data;
        data = {};
    }
    return jQuery.ajax({
        type: method,
        url: url,
        data: data,
        success: callback,
        dataType: type
        });
}
 
jQuery.extend({
    put: function(url, data, callback, type) {
        return _ajax_request(url, data, callback, type, 'PUT');
    },
    delete_: function(url, data, callback, type) {
        return _ajax_request(url, data, callback, type, 'DELETE');
    }
});

// From http://gist.github.com/110410
/*
Submit a form with Ajax
Use the class ajaxForm in your form declaration
<% form_for @comment,:html => {:class => "ajaxForm"} do |f| -%>
*/
jQuery.fn.submitWithAjax = function() {
  this.unbind('submit', false);
	this.submit(function() {
		// prevent submitting default text
        var $input = $(this).find('textarea, input:text');
	    if ( !($input.hasClass('optional')) && ($input.length != 0) && ($input[0].value == $input[0].defaultValue) ) {
			$input.fadeOut('fast').fadeIn('fast').focus();
			return false;
		};
		
		
		// prevent double submitting
		if (this.beenSubmitted)
      return false;
    else
      this.beenSubmitted = true;
		
		// if script makes it here then submit
    $.post(this.action, $(this).serialize(), null, "script");
    return false;
  })
 
  return this;
};
 
/*
Retreive a page with get
Use the class get in your link declaration
<%= link_to 'My link', my_path(),:class => "get" %>
*/
jQuery.fn.getWithAjax = function() {
  this.unbind('click', false);
  this.click(function() {
    $.get($(this).attr("href"), $(this).serialize(), null, "script");
    return false;
  })
  return this;
};
 
/*
Post data via html
Use the class post in your link declaration
<%= link_to 'My link', my_new_path(),:class => "post" %>
*/
jQuery.fn.postWithAjax = function() {
  this.unbind('click', false);
  this.click(function() {
    $.post($(this).attr("href"), $(this).serialize(), null, "script");
    return false;
  })
  return this;
};
 
/*
Update/Put data via html
Use the class put in your link declaration
<%= link_to 'My link', my_update_path(data),:class => "put",:method => :put %>
*/
jQuery.fn.putWithAjax = function() {
  this.unbind('click', false);
  this.click(function() {
    $.put($(this).attr("href"), $(this).serialize(), null, "script");
    return false;
  })
  return this;
};
 
/*
Delete data
Use the class delete in your link declaration
<%= link_to 'My link', my_destroy_path(data),:class => "delete",:method => :delete %>
*/
jQuery.fn.deleteWithAjax = function() {
  this.removeAttr('onclick');
  this.unbind('click', false);
  this.click(function() {
    var $this = $(this);
    var message = $this.attr('confirm_message');
    if (message == undefined || confirm(message)) {
        $.delete_($(this).attr("href"), $(this).serialize(), null, "script");
    }
    return false;
  })
  return this;
};
 
/*
Ajaxify all the links on the page.
This function is called when the page is loaded. You'll probaly need to call it again when you write render new datas that need to be ajaxyfied.'
*/
function ajaxLinks(){
    $('.ajaxForm').submitWithAjax();
    $('a.get').getWithAjax();
    $('a.post').postWithAjax();
    $('a.put').putWithAjax();
    $('a.delete').deleteWithAjax();
    $('div.wheeled a').showWheelOnClick();
}

// from http://stackoverflow.com/questions/1258805/how-to-check-for-current-date-and-time-in-jquery
function updateCounter( callback, times )
{
  var internalCallback = function( t, counter )
  {
    return function()
    {
      if ( --t > 0 )
      {
        window.setTimeout( internalCallback, Math.floor(Math.random()*5000) );
        callback();
      }
    }
  }( times, 0 );

  window.setTimeout( internalCallback, 5000 );
};

$(document).ready(function() {
// All non-GET requests will add the authenticity token
 $(document).ajaxSend(function(event, request, settings) {
       if (typeof(window.AUTH_TOKEN) == "undefined") return;
       // IE6 fix for http://dev.jquery.com/ticket/3155
       if (settings.type == 'GET' || settings.type == 'get') return;
 
       settings.data = settings.data || "";
       settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(window.AUTH_TOKEN);
     });
 
  ajaxLinks();
	$("textarea.blur, input:text.blur").blurHint();	
    $("div[id$='_dialog']").modalDialog();
    // $('#new_tweet_dialog').modalDialog({ width: 510 });
	$('a.tooltip').tooltipLink();
	$('input, textarea').changeFocusBlurColor();
	$('.imgHoverMarker').imgHover();
	$('a.bubble_tip').bubbleTipLink();
    $('.flash').effect("pulsate", {times: 1}, 500);
    $('ul.hoverable li.hoverable').listHover();
    $('.preview').listHover();
    $('#select_all').selectAll();
    $('.checkable_row').checkableRow();
    $('.editable').editable();
    $('.form_link').showFormOnClick();
    $('a.oauth_popup').oauthPopupOnClick();
    // $('.expand_link').expandOnClick();
    ajaxNewTweetLinks();
    
    $('form a.add_child').live('click', function() {
      var assoc   = $(this).attr('data-association');
      var content = $('#' + assoc + '_fields_template').html();
      var regexp  = new RegExp('new_' + assoc, 'g');
      var new_id  = new Date().getTime();

      $(this).parent().before(content.replace(regexp, new_id));    
      return false;
    });

    $('form a.remove_child').live('click', function() {
      var hidden_field = $(this).prev('input[type=hidden]')[0];
      if(hidden_field) {
        hidden_field.value = '1';
      }
      $(this).parent('.fields').hide();
      return false;
    });
  // 
  // // facebox popups
  // jQuery('a[rel*=facebox]').facebox();
});