/**
 * This is an abstract class representing one data line in the chart
 * 
 * @version 0.1
 * @requires OFC, Prototype
 * @author Matthias Steinböck grillen at abendstille at
 */
/* abstract */ var OFCData = Class.create({
	
	/**
	 * Initializes the Data-Object with a main-type and a sub-type.
	 * e.g. if you want to create a bar-chart
	 */
	 
	initialize: function(main, sub) {
		
		// check if type supported
		if (this.supported.indexOf(sub) == -1) {
			alert('OFC-JS-ERROR: subtype '+sub.inspect()+' is not supported by '+main+'.');
			return null;
		}
		
		// create properties
		this.mainType = main;
		this.subType = sub;
		this.number = null;
		this.values = null; // data-values
		this.colors = new Hash();
		
		// key style TODO: make accepting CSS
		this.key = '';
		this.keySize = 10;
		
		// parent chart
		this.ofc = null;
	},
	
	/**
	 * Sets the key (the data-name) and its font-size
	 * @access public
	 * @param {String} text Dataname
	 * @param {int} size Fontsize
	 * @return void
	 */
	setKey: function(text, size) {
		if (typeof size != 'undefined') {
			this.keySize = size;
		}
		this.key = text;
	},
	
	/**
	 * saves this data to the given ofc-objcet
	 * @access public
	 * @param {OFC} ofc An instance of ofc
	 * @param {int} number The datas number in the chart
	 * @return void
	 */
	addToOFC: function(/* OFC */ ofc) {
		
		// prepare param-names
		var param_name = 'values';
		
		if (this.number != null && this.number != 0) {
			param_name += '_'+this.number;
		}
		
		// set on ofc
		ofc.set(this.getFullName(), this.toData());
		
		// set value for this data
		ofc.set(param_name, this.values);
	},
	
	/**
	 * Generic converter converts another OFCData-object to this one
	 * 
	 * @param {OFCData} chart Object to copy from
	 */
	convertFrom: function(/* OFCData */ chart) {
		var colors = chart.getColors().values();
		var iter = 0;
		this.colors.each(function(pair){
			if (colors.length-1 < iter || typeof colors[iter] == 'undefined') {
				var color = OFC.defaultColors[iter];
			} else {
				var color = colors[iter];
			}
			this.colors.set(pair.key, color);
			iter++;
		}, this);
		
		this.setKey(chart.key, chart.keySize);
		
		this.values = chart.values;
	},
	
	/**
	 * removes the data from the ofc-object
	 * @access public
	 * @param {OFC} ofc An instance of ofc
	 * @return void
	 */
	removeFromOFC: function(/* OFC */ ofc) {
		// prepare param-names
		var value = 'values';
		
		if (this.number != 0) {
			value += '_'+this.number;
		}
		
		ofc.set(this.getFullName(), null);
		ofc.set(value, null);
	},
	
	/**
	 * Returns the full param name in ofc
	 * 
	 * @return {String}
	 */
	getFullName: function() {
		var name = this.mainType;
		
		if (this.subType != null) {
			name += '_'+this.subType;
		}
		
		if (this.number != 0) {
			name += '_'+this.number;
		}
		return name;
	},
	
	/**
	 * Returns the correct type of the data-object
	 * 
	 * @return {String}
	 */
	getType: function() {
		var name = this.mainType;
		
		if (this.subType != null) {
			name += '_'+this.subType;
		}
		
		return name;
	},
	
	/**
	 * Method-stub - should be overwritten
	 * Returns the full value string in ofc
	 * 
	 * @return {Aray}
	 */
	toData: function() {
		return [];
	},
	
	/**
	 * Method-stub - should be overwritten
	 * 
	 * Loads all required data from the string
	 * @param  {Array} info
	 */
	fromData: function(info) {
		return null;
	},
	
	/**
	 * Returns all colors
	 * 
	 * Returns all colors of the this OFCData
	 * @return Hash
	 */
	getColors: function() {
		return this.colors;
	},
	
	/**
	 * Method-stub - should be overwritten
	 * 
	 * Returns all required colors and their names as Hash in this form:
	 * [
	 *    internalName: "descriptive Title"
	 * ]
	 * @return Hash
	 */
	getRequiredColors: function() {
		return new Hash();
	},
	
	/**
	 * Sets all colors - use this function only in connection with
	 * getColors or getRequiredColors
	 * 
	 * Changes this objects colors
	 * @param {Hash} colors
	 */
	changeColors: function(colors) {
		this.colors = colors.clone();
	},
	
	/**
	 * Compares another OFCData-object to this for equality
	 * 
	 * @param {OFCData} other
	 * @type boolean
	 */
	equals: function(/*OFCData*/ other) {
		return this.mainType == other.mainType
			&& this.subType == other.subType
			&& this.number == other.number;
	}
});