// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

/********************************************************/
// Force position of occasions-plus and -minus popups.
// Used by _recipients ans _events.
function forcePosPopups() {
  // Depends on the distance to the top border of the frame
  var yBase = 124 /*6+81+16+26 - 5*/ - $('scroll-zone').cumulativeScrollOffset()[1];
  $$('.occasions-plus ul.level1').each(function(el, index){
    var y = yBase + index*94;
    el.setStyle("top: "+y+"px;");
  });
  $$('.occasions-minus ul.level1').each(function(el, index){
    var y = yBase + index*94;
    el.setStyle("top: "+y+"px;");
  });
}

/********************** Cookies *************************/
// Set a cookie for the session
function setCookie(key, value) {
  document.cookie = key + "=" + encodeURI(value) + "; path=/";
}
// Return null if not found
function readCookie(key) {
  var cookie = document.cookie;
  var first = cookie.indexOf(key+"=");
  // cookie exists
  if (first >= 0) {
    var str = cookie.substring(first,cookie.length);
    var last = str.indexOf(";");

    // if last cookie
    if (last < 0) last = str.length;

    // get cookie value
    str = str.substring(0,last).split("=");
    return decodeURI(str[1]);
  } else {
    return null;
  }
}

/********************** Delayed call *************************/
var delayCallArray = new Array();
// delay of 100ms. Cancel previous call if it is called twice during the interval
function delayCall(tag, func) {
  id = delayCallArray[tag]
  if ( id ) {
    window.clearTimeout(id);
  }
  delayCallArray[tag] = window.setTimeout(func, 100);
}

/*********************** Scrolling **************************/
/**
 * Makes the scrollZone scrollable
 * Example:
 * div#scrollTrack
 *   div#scrollHandle
 * div#panel
 *   bla bla
 *   div#scroll-zone
 *     bla1 bla2 bla3 bla4
 * <script>s = new Scrolling(4,3,'foo',$('panel'), $('scroll-zone'), ...)</script>
 *
 * itemsNb: total number of 'rows' in the scrollable area
 * shownNb: number of shown rows. The other one are hidden.
 * cookiePrefix: prefix for the cookie which contains the scrolltop value.
 * panelToObserve: div where we observe the mouse wheel events
 * scrollZone: the scrolled div
 * scrollTrack: the scrollbar div
 * scrollHandle: the handler in the scrollbar
 * itemIndex: optional. The index of a row that we want to be visible (the scroll will be adjusted)
 */
function Scrolling(itemsNb, shownNb, cookiePrefix, panelToObserve,
		   scrollZone, scrollTrack, scrollHandle, itemIndex) {
    var allNb = itemsNb,
	hiddenNb = itemsNb - shownNb,
	slider1;

    function storeScrollTop(){
	setCookie(cookiePrefix+'-scroll-top', scrollZone.scrollTop);
    }
    function initScrollTopOnLoad(){
	var strScrollTop = readCookie(cookiePrefix+'-scroll-top');
	if (strScrollTop) {
	    var scrollTop = parseInt(strScrollTop);
	    var ratio = scrollTop/(scrollZone.scrollHeight-scrollZone.offsetHeight);
	    if ( typeof(itemIndex) != 'undefined' ) {
		var indexMin = ratio*(itemsNb-shownNb);
		var indexMax = indexMin + shownNb - 1;
		if ( indexMin > itemIndex ) {
		    ratio = itemIndex/(itemsNb-shownNb);
		}
		if ( itemIndex > indexMax ) {
		    ratio = (itemIndex-(shownNb-1))/(itemsNb-shownNb);
		}
	    }
	    // scrollZone.scrollTop = scrollTop;
	    slider1.setValue(ratio);
	}
    }

    function handleWheel(delta) {
	slider1.setValueBy(-delta/(2*hiddenNb)); // 2 increments of the wheel for each item
    }
    // Event handler for mouse wheel event
    function wheel(event){
	var delta = 0;
	if (!event) // IE
	    event = window.event;

	if (event.wheelDelta) { // IE/Opera
	    delta = event.wheelDelta/120;
	} else if (event.detail) { // Mozilla
	    delta = -event.detail/3;
	}

	/** If delta is nonzero, handle it.
	 * Basically, delta is now positive if wheel was scrolled up,
	 * and negative, if wheel was scrolled down.
	 */
	if (delta)
	    handleWheel(delta);

	/** Prevent default actions caused by mouse wheel.
	 * That might be ugly, but we handle scrolls somehow
	 * anyway, so don't bother here..
	 */
	if (event.preventDefault)
	    event.preventDefault();

	event.returnValue = false;
    }

    // scroll the element vertically based on its height and the slider maximum value
    function scrollVertical(value, element) {
	element.scrollTop = Math.round(value/slider1.maximum*(element.scrollHeight-element.offsetHeight));
    }

    //////////////////////////////////////////////////////
    // Constructor
    scrollHandle.style.height = Math.round(100*shownNb/allNb) + '%';
    slider1 = new Control.Slider(scrollHandle, scrollTrack, {
	    axis: 'vertical',
	    onSlide: function(v) { scrollVertical(v, scrollZone);  },
	    onChange: function(v) { scrollVertical(v, scrollZone); }
	});
    // Mozilla
    panelToObserve.observe('DOMMouseScroll', wheel);
    // IE/Opera
    panelToObserve.observe('mousewheel', wheel);
    // disable vertical scrolling if text doesn't overflow the div
    if (scrollZone.scrollHeight <= scrollZone.offsetHeight) {
	slider1.setDisabled();
	scrollTrack.hide();
    }
    initScrollTopOnLoad();
    scrollZone.observe('scroll', function(e) {
	    delayCall(cookiePrefix+'-scroll', storeScrollTop);
		} );

    ////////////////////////////////////////////////////
    // Public data and methods
    return {
    };
}

/******************** Client side pagination ********************/
/**
 * Example:
 * div#page-0
 * div#page-1
 * div#page-2
 * <script>var pagination = new Pagination('page-', 3);</script>
 */
function Pagination(prefix, pageNb) {
    var page = 0;

    function hidePage(page) {
        $(prefix+page).hide();
    }
    function showPage(page) {
        $(prefix+page).show();
    }

    // init
    showPage(page);

    ////////////////////////////////////////////////////
    // Public data and methods
    return {
	nextPage : function () {
	    hidePage(page);
	    page = (page + 1) % pageNb;
	    showPage(page);
	},
	previousPage : function () {
	    hidePage(page);
	    page = (page - 1 + pageNb) % pageNb;
	    showPage(page);
	}
    };
}

/********************** UserInput *************************/
// Clear text input field on focus
initClearOnFocus = function () {
    if ($$('.clearonfocus')) {
	$$('.clearonfocus').map( function(element) {
		element.observe('click', function(event) {
			var element = Event.element(event);
			element.removeClassName('clearonfocus');
			element.writeAttribute('value', '');
		    });
	    });
    }
};
Event.observe(window, 'load', initClearOnFocus);

function disableEnterKey(e) {
    var key = window.event ? window.event.keyCode/*IE*/:e.which/*FF*/;
    return key != 13;
}


/********************** Event creation *************************/
// Enable/Disable event name and recurrent field
updateEventNameField = function(event) {
    if ($('event_calendate_id_').checked) {
	$('event_name').enable();
	$('event_recurrent').enable();
    } else {
	$('event_name').disable();
	$('event_recurrent').disable();
    }
};
Event.observe(window, 'load', function() {
	var form = $('new_event');
	if (form) {
	    var inputs = form['event[calendate_id]'];
	    for (var i = 0; i<inputs.length; ++i) {
		Event.observe(inputs[i], 'click', updateEventNameField);
	    }
	    // Disable what must be disabled when the page is loaded
	    updateEventNameField();
	}
    }
    );

/********************** jQuery resetDefaultValue plugin *************************/
/** used for autocomplete */
/**
 * jQuery resetDefaultValue plugin
 * @version 0.9.1
 * @author Leandro Vieira Pinho 
 */
jQuery.fn.resetDefaultValue = function() {
	function _clearDefaultValue() {
		var _$ = jQuery(this);
		if ( _$.val() == this.defaultValue ) { _$.val(''); _$.removeClass('defaultvalue'); }
	};
	function _resetDefaultValue() {
		var _$ = jQuery(this);
		if ( _$.val() == '' ) { _$.val(this.defaultValue); _$.addClass('defaultvalue'); }
	};
	return this.click(_clearDefaultValue).focus(_clearDefaultValue).blur(_resetDefaultValue);
}
