//Timer
Object.extend(PeriodicalExecuter.prototype, {
     initialize: function(callback, frequency) {
         this.callback = callback;
         this.frequency = frequency;
         this.currentlyExecuting = false;
         this.timer = null;
         //this.start();
     },
 
     isAlive: function() {
        return (this.timer != null) ? true : false;
     },
     
     start: function() {
         this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
     },
 
     pause: function() {
         clearInterval(this.timer);
         this.timer = null;
     },
 
     reset: function() {
        this.pause();
        this.start();
     },
     
     setFrequency: function(f) {
         this.frequency = f;
         if (this.timer != null) {
             this.reset();
         }
     }
 });
 
 //Cookies
 var Cookie = {
  set: function(name, value, daysToExpire) {
    var expire = '';
    if (daysToExpire != undefined) {
      var d = new Date();
      d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));
      expire = '; expires=' + d.toGMTString();
    }
    return (document.cookie = escape(name) + '=' + escape(value || '') + expire);
  },
  get: function(name) {
    var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));
    return (cookie ? unescape(cookie[2]) : null);
  },
  erase: function(name) {
    var cookie = Cookie.get(name) || true;
    Cookie.set(name, '', -1);
    return cookie;
  },
  accept: function() {
    if (typeof navigator.cookieEnabled == 'boolean') {
      return navigator.cookieEnabled;
    }
    Cookie.set('_test', '1');
    return (Cookie.erase('_test') === '1');
  }
};

//DOM ready
Object.extend(Event, {
  _domReady : function() {
    if (arguments.callee.done) return;
    arguments.callee.done = true;

    if (this._timer)  clearInterval(this._timer);
    
    this._readyCallbacks.each(function(f) { f() });
    this._readyCallbacks = null;
},
  onDOMReady : function(f) {
    if (!this._readyCallbacks) {
      var domReady = this._domReady.bind(this);
      
      if (document.addEventListener)
        document.addEventListener("DOMContentLoaded", domReady, false);
        
        /*@cc_on @*/
        /*@if (@_win32)
            document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
            document.getElementById("__ie_onload").onreadystatechange = function() {
                if (this.readyState == "complete") domReady(); 
            };
        /*@end @*/
        
        if (/WebKit/i.test(navigator.userAgent)) { 
          this._timer = setInterval(function() {
            if (/loaded|complete/.test(document.readyState)) domReady(); 
          }, 10);
        }
        
        Event.observe(window, 'load', domReady);
        Event._readyCallbacks =  [];
    }
    Event._readyCallbacks.push(f);
  }
});

//Events
Event.Publisher = Class.create();
Object.extend( Event.Publisher, {
	_ls_event_targets: null,
	
	getEventTarget: function( event_name ) {
		if ( ! this._ls_event_targets )
			this._ls_event_targets = new Array();
		
		if ( ! this._ls_event_targets[ event_name ] )
			document.body.appendChild( this._ls_event_targets[ event_name ] = document.createElement( 'A' ) );
		
		return this._ls_event_targets[ event_name ];
	},
	
	addEventListener: function( event_name, callback_func, capturing ) {
		var targ = this.getEventTarget( event_name );
		
		Event.observe( targ, 'click', callback_func, capturing );
	},
	
	removeEventListener: function( event_name, callback_func, capturing ) {
		var targ = this.getEventTarget( event_name );
		
		Event.stopObserving( targ, 'click', callback_func, capturing );
	},
	
	dispatchEvent: function( event_name, data, can_bubble, cancelable ) {
		var targ = this.getEventTarget( event_name );
		var event_data = { event_name: event_name, event_target: this, data: ( typeof( data ) == 'undefined' ) ? null : data };
		
		Event.create( targ, event_data, can_bubble, cancelable, true );
	}
} );

Event.Listener = Class.create();
Object.extend( Event.Listener, {
	_listens: null,
	
	getEventHandlerName: function( event_name ) {
		var onEvent_name = event_name.split( /[ _]/ ).join( '-' ).camelize();
		
		return "on" + onEvent_name.charAt( 0 ).toUpperCase() + onEvent_name.substr( 1 );
	},
	
	listenForEvent: function( event_source, event_name, use_capture, onEvent_name ) {
		if ( ! onEvent_name )
			onEvent_name = this.getEventHandlerName( event_name );
		
		if ( ! this._listens ) this._listens = new Array();
		
		var cb = this[ onEvent_name ].bindAsEventListener( this );
		this._listens.push( [ event_source, event_name, use_capture, onEvent_name, cb ] )
		
		event_source.addEventListener( event_name, cb, use_capture );
	},
	
	stopListeningForEvent: function( event_source, event_name, use_capture, onEvent_name ) {
		if ( ! this._listens ) return false;
		
		if ( ! onEvent_name )
			onEvent_name = this.getEventHandlerName( event_name );
		
		var ix_item;
		var ls = this._listens.detect( function( val, ix ) {
			if ( ( val[ 0 ] == event_source ) && ( val[ 1 ] == event_name ) && ( val[ 2 ] == use_capture ) && ( val[ 3 ] == onEvent_name ) ) {
				ix_item = ix;
				return true;
			}
		} );
		
		if ( ix_item ) {
			this._listens.splice( ix_item, 1 );
			
			event_source.removeEventListener( event_name, ls[ 4 ], use_capture );
			
			return true;
		}
		
		return false;
	}
} );

Object.extend( Event, {
	create: function( event_data, can_bubble, cancelable, fl_dispatch, target ) {
		var event;
		
		if ( document.createEvent ) {  // gecko, safari
			if ( ! can_bubble ) can_bubble = false;
			if ( ! cancelable ) cancelable = false;
			
			if ( /Konqueror|Safari|KHTML/.test( navigator.userAgent ) ) {
				event = document.createEvent( 'HTMLEvents' )
				
				event.initEvent( 'click', can_bubble, cancelable );
			}
			else {  // gecko uses MouseEvents
				event = document.createEvent( 'MouseEvents' )
				
				event.initMouseEvent( "click", can_bubble, cancelable,
				                      window, 0, 0, 0, 0, 0,
				                      false, false, false, false, 0, null );
			}
		}
		else {  // msie
			event = document.createEventObject();
			event.event_type = 'click';
		}
		
		event.event_data = event_data;
		
		if ( fl_dispatch )
			Event.dispatch( target, event );
		
		return event;
	},
	
	dispatch: function( target, event ) {
		if ( document.createEvent )
			return target.dispatchEvent( event );
		else
			return target.fireEvent( ( typeof( event.event_type ) != "undefined" ) ? event.event_type : 'onclick', event );
	}
} );

