(function() {

	SL.ui.Accordion = Class.create(SL.Component, {

		init : function() {

			this.config.setDefault('duration', 0);
			this.config.setDefault('on_mouse_over', false);
			this.config.setDefault('css_prefix', 'accordion');
			this.config.setDefault('button_class', this.config.get('css_prefix') + '_btn');
			this.config.setDefault('mode', 'complex');

			if (this.config.get('fix_old_ie')) {
				var v = SL.getIE();
				if (v > 0 && v < 9) {
					this.config.set('duration', -1);
				}
			}

			this.cssPrefix = this.config.get('css_prefix');
			this.mode = this.config.get('mode');
			this.duration = this.config.get('duration');
			this.onMouseOver = this.config.get('on_mouse_over');

			this.active = -1;

			if (this.mode == 'list') {
				this.list = this.e.down('ul');
				var children = this.list.childElements();
				for ( var i = 0; i < children.length; i++) {
					var e = children[i];
					if (e.hasClassName('selected')) {
						this.active = i;
					}
					if (!e.down('ul')) {
						continue;
					}
					if (this.onMouseOver) {
						e.observe('mouseenter', this._onMouseOver.bind(this, i));
					} else {
						e.observe('click', this._onMouseClicked.bind(this, i));
					}
				}
			} else {
				this.children = this.e.down().childElements();

				for ( var i = 0; i < this.children.length; i++) {
					var e = this.children[i];
					e.store('acc_idx', i);

					// var head = e.down(this.cssPrefix + '_head');
					try {
						var body = e.down('.' + this.cssPrefix + '_body').down();

						var style = body.getStyle('display');
						if (style == null || style == 'block') {
							this.active = i;
							e.addClassName('active');
						} else {
							e.addClassName('inactive');
						}
					} catch (e) {
						console.error(e);
					}
				}

				if (this.onMouseOver) {
					for ( var i = 0; i < this.children.length; i++) {
						this.children[i].down().observe('mouseenter', this._onMouseOver.bind(this, i));
					}
				}
			}

			this.updateState(false);
		},

		_onMouseOver : function(active, e) {
			this.setActive(active);
		},

		_toggleBtn : function(element, state) {
			var btns = element.select('.' + this.config.get('button_class'));
			if (!btns) {
				return;
			}

			for ( var i = 0; i < btns.length; i++) {
				var img = btns[i].down();
				if (!img) {
					continue;
				}
				var pos = img.src.lastIndexOf('/');
				var pos2 = img.src.lastIndexOf('_');

				if (pos2 > pos) {
					pos = pos2;
				}

				if (pos < 0) {
					continue;
				}

				img.src = img.src.substring(0, pos + 1) + state + '.png';
			}
		},

		getElement : function(i) {
			if (this.mode == 'list') {
				var c = this.list.childElements()[i];
				if (c) {
					return c.down('ul');
				}
				console.error("No child for element:", i);
				return;
			}
			return this.children[i].down('.' + this.cssPrefix + '_body').down();
		},

		setActive : function(active) {
			if (this.onMouseOver && this.active == active) {
				return;
			}

			if (this.config.get('multi')) {
				var body = this.getElement(active);
				if (body.up().up().hasClassName('active')) {
					if (this.duration <= 0) {
						body.setStyle('display:none');
					} else {
						SL.effects.resetCurrent(body);
						SL.effects.registerCurrent(Effect.BlindUp(body, {
							duration : this.duration / 1000.0
						}));
					}

					body.up().up().addClassName('inactive');
					body.up().up().removeClassName('active');

					if (this.mode != 'list') {
						var c = this.children[active];
						if (c) {
							this._toggleBtn(c.down(), 'down');
						} else {
							console.error("No child for active element:", this.active);
						}
					}

					this.active = -1;
					this.updateState(true);
					return;
				}
			}

			if (this.active >= 0 && !this.config.get('multi')) {
				var body = this.getElement(this.active);
				if (this.duration <= 0) {
					body.setStyle('display:none');
				} else {
					SL.effects.resetCurrent(body);
					SL.effects.registerCurrent(Effect.BlindUp(body, {
						duration : this.duration / 1000.0
					}));
				}

				body.up().up().addClassName('inactive');
				body.up().up().removeClassName('active');

				if (this.mode != 'list') {
					var c = this.children[this.active];
					if (c) {
						this._toggleBtn(c.down(), 'down');
					} else {
						console.error("No child for active element:", this.active);
					}
				}
			}

			if (this.active == active) {
				this.active = -1;
				this.updateState(true);
				return;
			}

			var body = this.getElement(active);

			if (this.duration <= 0) {
				body.setStyle('display:block');
			} else {
				SL.effects.resetCurrent(body);
				SL.effects.registerCurrent(Effect.BlindDown(body, {
					duration : this.duration / 1000.0
				}));
			}

			body.up().up().addClassName('active');
			body.up().up().removeClassName('inactive');

			this.active = active;

			if (this.mode != 'list') {
				var c = this.children[this.active];
				if (c) {
					this._toggleBtn(c.down(), 'up');
				} else {
					console.error("No child for active element:", this.active);
				}
			}
			this.updateState(true);
		},

		updateState : function(send) {

			var stateURL = this.config.get('state_url');
			if (!stateURL) {
				return;
			}

			if (!this.states) {
				this.states = {};
			}

			for ( var i = 0; i < this.children.length; i++) {
				var e = this.children[i];
				var id = e.id;
				if (!id) {
					id = i;
				}

				this.states[id] = e.hasClassName('active');
			}

			if (send) {
				var states = Object.toJSON(this.states);
				var url = stateURL.replace('@state@', states);
				new Ajax.Request(url, {
					method : 'get'
				});
			}
		}
	});

})();

