var AdvPushbox = new Class({
	
	Implements: Options,
	
	options: {
		'xmlpath': null,
		'basepath': window.location.hostname
	},
	
	initialize: function(pbox, options) {
		
		// init globals
		this.container = pbox;
		this.loader = this.container.getElement('div.loader');
		this.msgBar = this.container.getElement('div.msgbar');
		this.titlecontainer = this.msgBar.getElement('p.title');
		this.subtitlecontainer = this.msgBar.getElement('p.subtitle');
		this.navigation = this.container.getElement('div.navigation');
		this.viewport = this.container.getElement('div.viewport');
		this.buttons = this.navigation.getElements('li.but');
		this.slides = [];
		this.xml = null;
		this.images = [];
		this.titles = [];
		this.links = [];
		this.progress = [];
		this.lastIndex = null;
		
		// add options
		this.setOptions(options);
		
		// load xml
		this.loadXml(this.options.xmlpath);

		// init
		this.initMsgBar();

		// show loader
		this.loader.fade('show');
		
		// preloading
		this.preload();

	},

	/**
	 * inits pushbox elements
	 * @return void
	 */
	init: function() {

		// init slides
		for (var i = this.images.length-this.buttons.length; i < this.images.length; ++i) {
			this.slides.include(this.images[i]);
		}

		this.slides.each(function(slide, index) {
			slide.setStyles({
				'position': 'absolute',
				'left': 0,
				'top': 0,
				'z-index': 19-index,
				'visibility': 'hidden',
				'cursor': 'pointer'
			});
			
			slide.removeEvents();
			slide.addEvents({
				'click': function(e) {
					e.stop();
					window.location.href = this.links[index];
				}.bind(this)
			});	
				
			slide.fade('hide');
			slide.inject(this.viewport, 'bottom');
		}.bind(this));

		// init navigation
		this.buttons.each(function(item, index) {
			
			var act = item.getElement('div.active');
			var progress = item.getElement('div.progress');
			
			act.fade('hide');
			progress.setStyles({
				'width': 0,
				'display': 'block'
			});
			progress.fade('in');
			
			var fx = new Fx.Tween(progress, {
				duration: 5000,
				transition: 'linear',
				onComplete: function() {

					ind = this.lastIndex || 0;
					if (ind+1 >= this.buttons.length) {
						this.showSlide(0);
					} else {
						this.showSlide(ind+1);
					}
					
				}.bind(this)
			});	
			this.progress.include(fx);		

			var img = this.images[index];
			
			img.setStyles({
				'position': 'absolute',
				'left': Math.floor(((item.getStyle('width')).toInt()-(img.getStyle('width')).toInt())/2),
				'top': Math.floor(((item.getStyle('height')).toInt()-(img.getStyle('height')).toInt())/2),
				'z-index': 60
			});
			
			item.removeEvents();
			item.addEvents({
				'click': function() {
					this.showSlide(index);
				}.bind(this)
			});			
			
			item.setStyle('cursor', 'pointer');
			
			img.fade('hide');
			img.inject(item, 'top');
			img.fade('in');
			
		}.bind(this));
	
		// do start
		this.showSlide(0);
	},

	/**
	 * displays requested slide
	 * @param {int} slide index
	 * @return void
	 */
	showSlide: function(index) {

		// animate title bar
		this.msgBarFx.start('left', 0);
		
		// update msgbar
		this.titlecontainer.fade('out').get('tween').chain(function() {
			this.titlecontainer.set('html', this.titles[index][0]);
			this.titlecontainer.fade('in');
		}.bind(this));
		
		this.subtitlecontainer.fade('out').get('tween').chain(function() {
			this.subtitlecontainer.set('html', this.titles[index][1]);
			this.subtitlecontainer.fade('in');	
		}.bind(this));

		// fade out last slide
		if (this.lastIndex != null) {
			this.progress[this.lastIndex].cancel();
			this.buttons[this.lastIndex].getElement('div.progress').fade('out');
			this.slides[this.lastIndex].fade('out');
			this.buttons[this.lastIndex].getElement('div.active').fade('out');
		}

		// fade in current slide
		this.slides[index].fade('in');
		this.buttons[index].getElement('div.active').fade('in');
		
		// start progress
		this.startProgress(index);
		
		this.lastIndex = index;
	},
	
	/**
	 * preload assets of the pushbox (images)
	 * @return void
	 */
	preload: function() {
		
		// get assets
		var assets = [];
		var path = 'http://' + this.options.basepath + '/';
		var buttons = this.xml.getElements('button');
		var slides = this.xml.getElements('content');
		
		// preload each image for buttons
		buttons.each(function(but, index) {
			assets.include(path + but.get('imageurl'));
		}.bind(this));
		
		// preload slides (and setup titles)
		slides.each(function(slide, index) {
			slidetitle = [slide.getElement('title').get('text') ,slide.getElement('subtitle').get('text')];
			this.titles.include(slidetitle);
			this.links.include(slide.getElement('link').get('text'));
			assets.include(path + slide.get('imageurl'));
		}.bind(this));
		
		// do the preloading
		this.images = Asset.images(assets, {
			onComplete: function() {
				this.loader.fade('out').get('tween').chain(function() {
					this.init();
				}.bind(this));
			}.bind(this)
		});
	},
	
	/**
	 * start progressbar
	 * @return void
	 */
	startProgress: function(index) {
		this.buttons[index].getElement('div.progress').fade('in');
		this.progress[index].start('width', [0, 165]);
	},
	
	/**
	 * loads xml data. no async call, because we need the xml contents to proceed
	 * @return void
	 */
	loadXml: function(path) {
		req = new Request({
			method: 'get',
			url: path,
			async: false,
			onSuccess: function(responseHTML, responseXML) {
				this.xml = responseXML;
			}.bind(this)			
		}).send();
	},
	
	initMsgBar: function() {
		this.msgBarFx = new Fx.Tween(this.msgBar, {
			duration: 500
		});
		this.msgBarFx.set('left', -500);
	}
});
