if(typeof('Classmaker') == 'undefined')
	Classmaker = {};

Classmaker.CPP_Form = Class.create({
	initialize: function(form) {
		this.form = form;
		form.cpp_form = this;
		
		this.name = form.down('#classname');
		
		this.attribute_wrapper = form.down('#fieldset-attributes').down('dl');
		this.method_wrapper    = form.down('#fieldset-methods').down('dl');
		
		this.attributes = [];
		this.methods    = [];
		this.operators  = [];
		this.attribute_id = 0;
		this.method_id    = 0;
		
		this.dynamic_memory_methods = {
			assignoperator: false
		};
		
		if(memory_support_fld = form.down('#memory_support_fld'))
			this.activate_memory_fld(memory_support_fld);
		
		if(add_attribute_btn = form.down('#add_attribute_btn'))
			this.activate_attribute_btn(add_attribute_btn);
		
		if(add_method_btn = $('add_method_btn'))
			this.activate_method_btn(add_method_btn);
		
		if(add_operator_btn = $('add_operator_btn'))
			this.activate_operator_btn(add_operator_btn);
	},
	
	classname: function() {
		return this.name.value ? this.name.value : 'Class';
	},
	
	activate_memory_fld: function(activate_memory_fld) {
		if(memory_support_fld.checked)
			this.add_dynamic_memory_methods();
		memory_support_fld.observe('change',function(ev){
			if(ev.element().checked)
				this.add_dynamic_memory_methods();
			else
				this.remove_dynamic_memory_methods();
		}.bind(this));
	},
	
	activate_attribute_btn: function(add_attribute_btn) {
		add_attribute_btn.observe('click',function(ev){
			this.add_attribute();
		}.bind(this));
	},
	
	activate_method_btn: function(add_method_btn) {
		add_method_btn.observe('click',function(ev){
			this.add_method();
		}.bind(this));
	},
	
	activate_operator_btn: function(add_operator_btn) {
		add_operator_btn.observe('click',function(ev){
			this.add_operator();
		}.bind(this));
	},
	
	add_dynamic_memory_methods: function() {
		if(typeof(console) != 'undefined') console.log("Adding dynamic memory mandatory methods");
		
		$$('.memory_mandatory').each(function(input){
			if(input.tagName.toLowerCase() == 'select') {
				if(typeof(console) != 'undefined') console.log('Removing default implementation option for field '+input.id);
				input.removedOption = input.down('option');
				input.prevSelected = input.selectedIndex;
				input.down('option').remove();
			}
			else if(input.tagName.toLowerCase() == 'input' && input.type == 'checkbox') {
				if(typeof(console) != 'undefined') console.log('Locking field '+input.id+' on checked');
				input.wasChecked = input.checked;
				input.checked = true;
				input.readOnly = true;
			}
		});
		
		if(!this.operatorExists('='))
			this.dynamic_memory_methods.assignoperator = this.add_operator('=');
		else if(typeof(console) != 'undefined')
			console.log('No need to add operator=: allready defined');
	},
	
	remove_dynamic_memory_methods: function() {
		if(typeof(console) != 'undefined') console.log("Removing dynamic memory mandatory methods");
		
		$$('.memory_mandatory').each(function(input){
			if(input.tagName.toLowerCase() == 'select') {
				if(!input.removedOption)
					return;
				
				if(typeof(console) != 'undefined') console.log('Restoring default implementation option for field '+input.id);
				
				if(input.selectedIndex > 0)
					input.prevSelected = input.selectedIndex + 1;
				
				input.insert({'top': input.removedOption});
				
				if(input.prevSelected)
					input.selectedIndex = input.prevSelected;
			}
			else if(input.tagName.toLowerCase() == 'input' && input.type == 'checkbox') {
				if(typeof(console) != 'undefined') console.log('Unlocking field '+input.id);
				
				input.readOnly = false;
				
				if(typeof(input.wasChecked) == "undefined")
					return;
				
				input.checked = input.wasChecked;
			}
		});
		
		if(this.dynamic_memory_methods.assignoperator)
			this.remove_operator(this.dynamic_memory_methods.assignoperator.id);
		this.dynamic_memory_methods.assignoperator = false;
	},
	
	add_attribute: function() {
		if(typeof(console) != 'undefined') console.log('Adding new attribute');
		
		attribute_div = this.copyInputRowIntoDiv(this.attribute_wrapper);
		this.attribute_wrapper.insert({'bottom': attribute_div});
		
		this.attributes.push(attribute_div);
		
		return operator_flds;
	},
	
	add_method: function(privacy, return_type, method_name, parameters) {
		if(typeof(console) != 'undefined') console.log('Adding method '+(typeof(method_name) != 'undefined' ? method_name : ''));
		
		method_div = this.copyInputRowIntoDiv(this.method_wrapper);
		this.methods.push(method_div);
		method_div.id = 'method_'+this.method_id++;
		this.method_wrapper.insert({'bottom': method_div});
		
		method_div.childElements().each(function(el){
			switch(el.name) {
				case "privacy[]":
					if(typeof(privacy) != 'undefined')
						el.selectedIndex = privacy;
					break;
				case "return_type[]":
					if(typeof(return_type) != 'undefined')
						el.value = return_type;
					
					break;
				case "method_name[]":
					if(typeof(method_name) != 'undefined')
						el.value = method_name;
					break;
				case "parameters[]":
					if(typeof(parameters) != 'undefined')
						el.value = parameters;
					
					break;
			}
		});
		
		remove_btn = new Element('img',{
			src: 'images/icons/delete.png',
			'className': 'remove_btn'
		});
		remove_btn.observe('click',function(ev){
			this.remove_method(ev.element().up().id);
		}.bind(this));
		method_div.insert({'bottom': remove_btn});
		
		return method_div;
	},
	
	remove_method: function(method_id) {
		if(!$(method_id))
			return;
		
		method_name = $(method_id).down('input.method_name').value;
		
		if(typeof(console) != 'undefined') console.log('Removing method '+method_name);
		
		for(i = 0; i < this.methods.size(); i++)
			if(this.methods[i].id == method_id) {
				this.methods.splice(i,1);
				break;
			}
		
		$(method_id).remove();
	},
	
	add_operator: function(operator) {
		if(typeof(operator) == 'undefined') {
			operators = $('operator_options');
			operator = operators.options[operators.selectedIndex].value;
		}
		
		if(this.operatorExists(operator))
			return;
		
		if(typeof(console) != 'undefined') console.log('Adding operator '+operator);
		
		type = this.classname()+" const &";
		
		operator_div = this.add_method(0, type, 'operator'+operator, type);
		operator_div.operator = operator;
		operator_div.down('input.method_name').readOnly = true;
		
		operator_div.down('.remove_btn').remove();
			
		remove_btn = new Element('img',{
			src: 'images/icons/delete.png',
			'className': 'remove_btn'
		});
		remove_btn.observe('click',function(ev){
			this.remove_operator(ev.element().up().id)
		}.bind(this));
		operator_div.insert({'bottom': remove_btn});
		
		this.operators.push(operator_div);
		
		return operator_div;
	},
	
	remove_operator: function(operator_id) {
		if(typeof(operator_id) == 'undefined')
			return;
		
		if(typeof(console) != 'undefined') console.log('Removing operator '+$(operator_id).operator);
		
		for(i = 0; i < this.operators.size(); i++)
			if(this.operators[i].id == operator_id) {
				this.operators.splice(i,1);
				break;
			}

		this.remove_method(operator_id);
	},
	
	operatorExists: function(operator) {
		if(typeof(operator) == 'undefined')
			return this.operators.size() > 0;
		
		operatorFound = false;
			
		this.operators.each(function(operator_div) {
			if(operator_div.down('.method_name').value == 'operator'+operator)
				operatorFound = true;
		});
		
		return operatorFound;
	},
	
	copyInputRowIntoDiv: function(wrapper) {
		newRow = new Element('div');
		
		wrapper.childElements().each(function(el){
			tag = el.tagName.toLowerCase();
		
			if(el.hasClassName('copy') || el.hasClassName('nocopy') || (tag != 'input' && tag != 'select' && tag != 'label'))
				return;
			
			if((tag == 'input' || tag == 'select') && el.name.indexOf('[]') == -1)
				el.name += '[]';
			
			copy = $(el.cloneNode(true));
			copy.addClassName('copy');
			copy.removeClassName('hidden');
			if(tag == 'input') {
				if(copy.type == 'text')
					copy.value = el.defaultValue;
				else if(copy.type == 'checkbox')
					copy.checked = false;
			}
			else if(tag == 'select')
				copy.selectedIndex = 0;
			
			newRow.insert({'bottom': copy});
		});
		
		return newRow;
	}
});

document.observe("dom:loaded", function() {
	Classmaker.cpp_form = new Classmaker.CPP_Form($('CPP_Form'));
});
