/*	Fma
	@author btapley
*/
/*-----------------------------------------------------------------------------------
			
		Class: Fma
		
		Put several messages into rotation with a specified area. A pseudo-random rotation presents one of a group of assets when the document loads. Assets can be optionally weighted, assigned a query to affect all links.
		
		Usage:
>		var myfma = defineArea('myfmaID')
>		myfma.provideMessage('TXT', "boo", 1);
>		myfma.provideMessage('URI', "/path/to/fma.html", 9);
>		myfma.updateArea();

-----------------------------------------------------------------------------------*/
adobe.Fma = (function() {
	
	var counter = 0,
		createMessageID = function() {
			return "fma"+counter++;
		};
	
	var area = function(id, w, h) {
		this.id = id;
		this.targetWidth = w; //not using this yet
		this.targetHeight = h; //not using this yet
		this.currMsgID = "", 
		this.msgNames = [];
		this.msgContents = {};
		this.msgContent = "";
		this.contentReadyCallbacks = [];
		this.contentReady = false;
	}
	
	area.prototype = {
/*-----------------------------------------------------------------------------------
			
		Method: provideMessage
		
		Function:
		Provide message data to internal renderer.
		
		Parameters:
		name - a constant string eg. TXT, URI, ELM
		content - string
		weight (optional) - number eg. 1-10, 1-100
		trackingID (optional) - placeholder
		
		Returned Value:
		String used to identify the message within the widget.
			
-----------------------------------------------------------------------------------*/
		provideMessage: function(type, content, weight, trackingID) { 
			
			var msgID = createMessageID();
			
			this.msgContents[msgID] = { 
				trackingID: trackingID || "",
				type: type.toLowerCase(),
				content: content
			};
			
			weight = (weight || 1);
			
			for(var i=0; i < weight; i++) {
				this.msgNames.push(msgID);
			}
			
			return msgID;
		},
/*-----------------------------------------------------------------------------------
			
		Method: removeMessage
		
		Function:
		Remove a message from rotation
		
		Parameters:
		msgID - string
		now - boolean
		
		Returned Value:
		Removed Message Object
			
-----------------------------------------------------------------------------------*/
		removeMessage: function(msgID, now) {
			
			var c = ",",
				s = "",
				copy = new Object(this.msgContents[msgID]),
				rgx = new RegExp( msgID+c ,"g");
			
			this.msgNames = ((s = (this.msgNames.join(c)+c).replace(rgx, "")).substring(0, s.length-1)).split(c);
			
			delete this.msgContents[msgID];
			
			if(now && this.currMsgID == msgID) {
				this.updateArea();
			}
			
			return copy;
		},
/*-----------------------------------------------------------------------------------
			
		Method: getMessageContent
		
		Function:
		Get the value passed in for the current selected message ID.
		
		Parameters:
		msgID - string
		
		Returned Value:
		string
			
-----------------------------------------------------------------------------------*/
		getMessageContent: function(msgID) {
			return this.msgContents[msgID || this.currMsgID].content;
		},
/*-----------------------------------------------------------------------------------
			
		Method: getMessageType
		
		Function:
		Get the value passed in for the currently selected message type.
		
		Parameters:
		msgID - string
		
		Returned Value:
		string
			
-----------------------------------------------------------------------------------*/
		getMessageType: function(msgID) {
			return this.msgContents[msgID || this.currMsgID].type;
		},
/*-----------------------------------------------------------------------------------
			
		Method: setCurrentMessageID
		
		Function:
		Set the current message id either by passing in a ID or allowing a random one to be selected. Use the returned ID to pass into <Fma.updateArea>
		
		Parameters:
		msgID(optional) - string
		
		Returned Value:
		current Message ID string 
			
-----------------------------------------------------------------------------------*/
		setCurrentMessageID: function(msgID) {
			var id = (msgID || this.msgNames[parseInt(Math.random()*this.msgNames.length, 0)]);
			return this.currMsgID = id;
		},
/*-----------------------------------------------------------------------------------
			
		Method: updateArea
		
		Function:
		Set the current message area either by passing in a ID or allowing a random one to be selected, then render the area.
		
		Parameters:
		msgID(optional) - string
		
		Returned Value:
		current Message ID string 
			
-----------------------------------------------------------------------------------*/
		updateArea: function(msgID) { 
			var id = this.setCurrentMessageID(msgID),
			content = this.getMessageContent(id),
			type = this.getMessageType(id),
			setContent = (function(text) {
				this.msgContent = text;
				this.contentReady = true;
				this.renderArea(this.id, false);
				
				for(var i = 0; i < this.contentReadyCallbacks.length; i++) {
					this.contentReadyCallbacks[i]();
				}
				
			}).bind(this);
			
			switch(type) {
				case "uri":
					
					if(!content) { setContent(content); }
					var ajax = new Ajax.Request(content, {
						method: "get", 
						parameters: "", 
						asynchronous: true,
						onComplete: function(response) { setContent(response.responseText);  }
					});
					
					break;
				case "txt":
					
					setContent(content);
					
					break;
				case "elm":
					
					var el = document.getElementById(content),
						htm = (el) ? el.innerHTML : "";
					if(this.id == content) { //To-do: create an API to save messages for gallery style rotation
						this.msgContent = htm;
					} else {
						setContent(htm);
					}					
					
					break;
			}
			
			return id;
			
		},
/*-----------------------------------------------------------------------------------
			
		Method: renderArea
		
		Function:
		Set the currentMessage either by passing in a ID or all a random one to be selected.
		
		Parameters:
		containerId(optional) - string
		replaceContainer - boolean
		
		Returned Value:
		target or rendered element
			
-----------------------------------------------------------------------------------*/
		renderArea: function(containerId, replaceContainer) {
			var el = document.getElementById(containerId);
			
			if(replaceContainer) {
				var div = adobe.Element.create("div", {id: this.id}),
					updateDiv = (function() {
						div.innerHTML = this.msgContent;
						el.parentNode.replaceChild(div, el);
					}).bind(this);
				
				if(this.contentReady) {
					updateDiv();
				} else {
					this.contentReadyCallbacks.push(updateDiv);
				}
				
				return div;
			}
			
			var updateEl = (function() {
				el.innerHTML = this.msgContent;
			}).bind(this);
			
			if(this.contentReady) { 
				updateEl();
			} else {
				this.contentReadyCallbacks.push(updateEl);
			}
			
			return el;
		}
	};
	
	return {
/*-----------------------------------------------------------------------------------
			
		Method: defineArea
		
		Function:
		Define rendering instructions for a new message container.
		
		Parameters:
		id - String identifier applied to the container when rendered. If a container with this ID already exists in the document when a render is performed, the existing container will be replaced.
		height (Optional) - Number of pixels
		width (Optional) - Number of pixels

		Usage:
>		defineArea(id, [height, width])
			
-----------------------------------------------------------------------------------*/
		defineArea: function(id, width, height) {
			return new area(id);
		}
	}

})();