var Tree = new Class({
	Implements: [Options, Events],

	options: {
		subSelector: 'ol|ul',

		openFirst: true,

		openCurrent: true,

		singleOpen: true,

		onOpen: {
			addClass: 'active'
		}
	},

	initialize: function (trees, options) {
		this.setOptions(options);

		this.trees = trees.map(function (cont) {
			return this.prepTree(cont);
		}, this);
	},

	prepTree: function (tree, level) {
		var opt = this.options;
		var subNodes = tree.getElements(opt.subSelector);
		var gotOpen = false;

		tree = subNodes.map(function (subNode) {
			var node = new Hash({open: false, target: subNode});
			node.set('parent', node.get('target').getParent());

			node = this.addOpener(node);

			if (opt.openCurrent) {
				var isCurrent = node.get('parent').getElement('a[href*='+window.location.href+']');
				
				if (isCurrent && !gotOpen) {
					if (isCurrent.getParent().getElements(opt.subSelector).length < 1)
						isCurrent.getParent().addClass('active');
					
					node.set('open', true);

					if (opt.openFirst) {
						gotOpen = true;
					}
				}
			}

			if (node.get('open')) {
				this.openNode(node);
			} else {
				this.closeNode(node);
			}

			return node;
		}.bind(this));

		return tree;
	},

	addOpener: function (node) {
		node.set('opener', node.get('target').getPrevious('a'));

		node.get('opener').addEvent('click', this.nodeClick.bindWithEvent(this, node));

		return node;
	},

	openNode: function (node) {
		node.get('parent').addClass(this.options.onOpen.addClass);
		node.get('target').setStyle('display', 'block');

		node.set('open', true);
	},

	closeNode: function (node) {
		node.get('parent').removeClass(this.options.onOpen.addClass);
		node.get('target').setStyle('display', 'none');

		node.set('open', false);
	},


	nodeClick: function (e, node) {
		e.stop();

		if (node.get('open')) {
			this.closeNode(node);
		} else {
			this.openNode(node);
		}
	}
});