/**
 *  application
 *
 *  Created by Aloyzas Rimeika on 2007-08-10.
 *  Application draft
 */

var app = {
	parentNode: window,
	widgets: {},

	// app.ready must be inserted at the bottom of the page
	// <script type="text/javascript" charset="utf-8">app.ready()</script>
	ready: function(fn, elem) {
		window.setTimeout(function(){
			events.dispatch({
				type: 'ready',
				target: app
			})
		}, 0);
	}
};

new function(){
	/**
	 * Application widget module
	 */

	// create new widget and assign it to app
	app.newWidget = function(prototype) {
		// add widget class to application name space
		app.widgets[prototype.name] = new Widget(prototype);
	};

	// WidgetClass object constructor
	function Widget(prototype) {
		if (!prototype.name)
			throw new Error("Widget Class must have name defined.");

		// create new widget class
		this.__class = extend(function(element, settings) {
			// wrap element with widget object
			extend(this, settings, { element: element })
				.construct();
		}, {
			prototype: extend(
				copy(this._proto),
				prototype
			)
		});
	}

	extend(Widget.prototype, {
		run: function(select, settings) {
			// select dom elements
			var elems = typeof select == 'string'
				? array(dom.getByClass(select))
				: select instanceof Array
					? select : [select];

			// wrap widget on each element
			for (var i = 0; i < elems.length; i++) {
				var widgets = elems[i].__widgets;
				if (!widgets)
					widgets = elems[i].__widgets = {};

				(widgets[this.name] = widgets[this.name]
					// extend widget
					? extend(widgets[this.name], settings)
					// create widget
					: new this.__class(elems[i], settings)
				).initilize();
			}
		},
		// abstract widget class prototype
		_proto: {
			construct: function(){},
			initilize: function(){},
			destroy: function(){},

			addEvent: function(type, method) {
				events.add(this.element, type, method = bind(method, this));
				return method;
			},
			removeEvent: function(type, method) {
				events.remove(this.element, type, method);
			},
			dispatchEvent: function(event) {
				if (typeof event == 'string')
					event = { type: event, target: this.element };
				else if (!event.target)
					event.target = this.element;
				events.dispatch(event);
			},
			bind: function() {
				for (var i = 0, a = arguments; i < a.length; i++)
					this.element[a[i]] = bind(this[a[i]], this);
			}
		}
	});
};

app.newWidget({
	name: 'dateFormat',
	construct: function() {
		this.addEvent('blur', this.onblur);
	},
	onblur: function(e) {
		e.target.value = (date = e.target.value.toDate())
			? date.getFullYear() + '-' + (date.getMonth() + 1).pad() + '-' + date.getDate().pad()
			: '';
	}
});

app.newWidget({
	name: 'imageFix',
	construct: function() {
		var images = document.images;
		for (var i = images.length - 1; i >= 0; i--){
		  if (images[i].align) {
		    dom.addClass(images[i], images[i].align.toLowerCase());
		  };
		};
		
	}
});

events.add(window || app, 'ready', function() {
  app.widgets.imageFix.run(document, {});
});

// add "js" class to html element to let css know about javascript existense :)
dom.addClass(dom.last('html'), 'js');
// force IE background images cache
events.add(window, 'load', function() {
	if (!window.opera) {
		try { document.execCommand("BackgroundImageCache", false, true); } catch(e) {};
	}
});
