/* ::: constructor - Unit ::: */
function Unit( configObject )
{
	var parsedElement = Unit.parseElement( configObject.unit );

	/* id */
	if( parsedElement.attributeType == 'idAttribute' )
	{
		var tempUnit    = parsedElement.elements[0];
		var tempTrigger;

		if( configObject.trigger.indexOf( Unit.keywords.relations['elementArray'] ) != -1 )
		{
			var tempTriggerString = configObject.trigger.replace( Unit.keywords.relations['elementArray'], '' );
			tempTrigger           = Unit.getElements( tempTriggerString, tempUnit );
		}
		else
		{
			tempTrigger = ( configObject.trigger.indexOf( Unit.keywords.relations['unit'] ) != -1 ) ? tempUnit : Unit.getElements( configObject.trigger, tempUnit, 0 );
		}

		if( tempUnit != undefined && tempTrigger != undefined )
		{
			var actionsInstance = new Actions( tempUnit, tempTrigger, configObject.actions );
		}
	}
	/* class */
	else if( parsedElement.attributeType == 'classAttribute' )
	{
		for( var i = 0; i < parsedElement.elements.length; i++ )
		{
			var tempUnit    = parsedElement.elements[i];
			var tempTrigger;

			if( configObject.trigger.indexOf( Unit.keywords.relations['elementArray'] ) != -1 )
			{
				var tempTriggerString = configObject.trigger.replace( Unit.keywords.relations['elementArray'], '' );
				tempTrigger           = Unit.getElements( tempTriggerString, tempUnit );
			}
			else
			{
				tempTrigger = ( configObject.trigger.indexOf( Unit.keywords.relations['unit'] ) != -1 ) ? tempUnit : Unit.getElements( configObject.trigger, tempUnit, 0 );
			}

			if( tempUnit != undefined && tempTrigger != undefined )
			{
				var actionsInstance = new Actions( tempUnit, tempTrigger, configObject.actions );
			}
		}
	}
	/* element */
	else if( parsedElement.attributeType == 'none' )
	{
		for( var i = 0; i < parsedElement.elements.length; i++ )
		{
			var tempUnit    = parsedElement.elements[i];
			var tempTrigger;

			if( configObject.trigger.indexOf( Unit.keywords.relations['elementArray'] ) != -1 )
			{
				var tempTriggerString = configObject.trigger.replace( Unit.keywords.relations['elementArray'], '' );
				tempTrigger           = Unit.getElements( tempTriggerString, tempUnit );
			}
			else
			{
				tempTrigger = ( configObject.trigger.indexOf( Unit.keywords.relations['unit'] ) != -1 ) ? tempUnit : Unit.getElements( configObject.trigger, tempUnit, 0 );
			}

			if( tempUnit != undefined && tempTrigger != undefined )
			{
				var actionsInstance = new Actions( tempUnit, tempTrigger, configObject.actions );
			}
		}
	}
}

/* :: keywords :: */
Unit.keywords =
{
	marks     : { idAttribute : '#', classAttribute : '.', substitution : '=' },
	relations : { unit : '@unit', trigger : '@trigger', child : '@child', noParse : '@noParse', elementArray : '@array' },
	actions   : { functionalAction : '@function', styleAction : '@style', execution : '@exec' }
};

/* class method - parseElement */
Unit.parseElement = function( elementString )
{
	var tempParsedElement = new Object();

	tempParsedElement.attributeType   = Unit.getAttributeType( elementString );
	tempParsedElement.elementString   = Unit.getElementString( elementString );
	tempParsedElement.attributeString = Unit.getAttributeString( elementString );
	tempParsedElement.elements        = Unit.getElements( elementString );

	return tempParsedElement;
}


/* class method - getAttributeType */
Unit.getAttributeType = function( elementString )
{
	var tempValue;

	if( elementString.indexOf( Unit.keywords.marks['idAttribute'] ) != -1 )
	{
		tempValue = 'idAttribute';
	}
	else if( elementString.indexOf( Unit.keywords.marks['classAttribute'] ) != -1 )
	{
		tempValue = 'classAttribute';
	}
	else
	{
		tempValue = 'none';
	}

	return tempValue;
}

/* class method - getElementString */
Unit.getElementString = function( elementString )
{
	var tempValue;
	var tempMark;

	if( Unit.getAttributeType( elementString ) != 'none' )
	{
		tempMark  = Unit.keywords.marks[Unit.getAttributeType( elementString )];
		tempValue = elementString.substring( 0, elementString.indexOf( tempMark ) );
	}
	else
	{
		tempValue = elementString;
	}

	return tempValue;
}

/* class method - getAttributeString */
Unit.getAttributeString = function( elementString )
{
	var tempValue;
	var tempMark;
	var startPoint;
	var endPoint;

	if( Unit.getAttributeType( elementString ) != 'none' )
	{
		tempMark   = Unit.keywords.marks[Unit.getAttributeType( elementString )];
		startPoint = elementString.indexOf( tempMark ) + 1;
		endPoint   = elementString.length;
		tempValue  = elementString.substring( startPoint, endPoint );
	}
	else
	{
		tempValue = '';
	}

	return tempValue;
}

/* class method - getElements */
Unit.getElements = function( elementSring, parentElement, index )
{
	var tempElements = new Array();

	if( Unit.getAttributeType( elementSring ) == 'idAttribute' )
	{
		tempElements[0] = document.getElementById( Unit.getAttributeString( elementSring ) );

		if( index != undefined )
		{
			return tempElements[index];
		}
		else
		{
			return tempElements;
		}
	}
	else if( Unit.getAttributeType( elementSring ) == 'classAttribute' )
	{
		var tempElementString = Unit.getElementString( elementSring );
		var tempClassString   = Unit.getAttributeString( elementSring );

		var elements = ( parentElement ) ? parentElement.getElementsByTagName( tempElementString ) : document.getElementsByTagName( tempElementString ) ;

		if( elements.length != 0 )
		{
			for( var i = 0; i < elements.length; i++ )
			{
				if( elements[i].className.indexOf( ' ' ) != -1 )
				{
					var valueArray  = elements[i].className.split( ' ' );
					var valueLength = valueArray.length;

					for( var j = 0; j < valueLength;  j++ )
					{
						if( valueArray[j] == tempClassString )
						{
							tempElements.push( elements[i] );
						}
					}
				}
				else
				{
					if( elements[i].className == tempClassString )
					{
						tempElements.push( elements[i] );
					}
				}
			}
		}
		if( index != undefined )
		{
			return tempElements[index];
		}
		else
		{
			return tempElements;
		}
	}
	else if( Unit.getAttributeType( elementSring ) == 'none' )
	{
		var elements = ( parentElement ) ? parentElement.getElementsByTagName( elementSring ) : document.getElementsByTagName( elementSring );
		if( elements.length != 0 )
		{
			for( var i = 0; i < elements.length; i++ )
			{
				tempElements.push( elements[i] );
			}
		}
		if( index != undefined )
		{
			return tempElements[index];
		}
		else
		{
			return tempElements;
		}
	}
}



/* ::: constructor - Actions ::: */
function Actions( unitElement, triggerElement, actions )
{
	this.unitElement    = unitElement;
	this.triggerElement = triggerElement;
	this.actions        = actions;

	this.init();
}

/* method - init  */
Actions.prototype.init = function()
{
	this.setActions();
}

/* method - setActions  */
Actions.prototype.setActions = function()
{
	for( var i = 0; i < this.actions.length; i++ )
	{
		var tempTargetElements = this.getTargetElements( this.actions[i].target );
		var tempEventType      = this.actions[i].eventType;
		var tempAction         = this.getAction( this.actions[i].action, tempTargetElements );

		if( this.triggerElement.length == undefined )
		{
			this.setEvent( this.triggerElement, tempEventType, tempAction );
		}
		else if( this.triggerElement.length != undefined )
		{
			for( var j = 0; j < this.triggerElement.length; j++ )
			{
				this.setEvent( this.triggerElement[j], tempEventType, tempAction );
			}
		}
	}
}

/* method - getTargetElements  */
Actions.prototype.getTargetElements = function( targetString )
{
	var tempElementString;
	var tempTargetElements = new Array();

	if( targetString.indexOf( Unit.keywords.relations['child'] ) != -1 )
	{
		tempElementString  = targetString.substring( 0, targetString.indexOf( Unit.keywords.relations['child'] ) );
		tempTargetElements = Unit.getElements( tempElementString, this.unitElement );
	}
	else if( targetString.indexOf( Unit.keywords.relations['trigger'] ) != -1 )
	{
		if( this.triggerElement.length == undefined )
		{
			tempTargetElements.push( this.triggerElement );
		}
		else if( this.triggerElement.length != undefined )
		{
			for( var i = 0; i < this.triggerElement.length; i++ )
			{
				tempTargetElements.push( this.triggerElement[i] );
			}
		}
	}
	else if( targetString.indexOf( Unit.keywords.relations['unit'] ) != -1 )
	{
		tempTargetElements.push( this.unitElement );
	}
	else if( targetString.indexOf( Unit.keywords.relations['noParse'] ) != -1 )
	{
		var tempTarget = targetString.substring( 0, targetString.indexOf( Unit.keywords.relations['noParse'] ) );
		tempTargetElements.push( tempTarget );
	}
	else
	{
		tempTargetElements = Unit.getElements( targetString );
	}

	return tempTargetElements;
}

/* method - getAction  */
Actions.prototype.getAction = function( actionString, actionTargets )
{
	var action;

	if( actionString.indexOf( Unit.keywords.actions['styleAction'] ) != -1 )
	{
		action = this.getStyleAction( actionString, actionTargets );
	}
	else if( actionString.indexOf( Unit.keywords.actions['functionalAction'] ) != -1 )
	{
		action = this.getFunctionalAction( actionString, actionTargets );
	}

	return action;
}

/* method - getStyleAction  */
Actions.prototype.getStyleAction = function( actionString, actionTargets )
{
	var tempStyleAction;
	var tempProperty = actionString.substring( 0, actionString.indexOf( Unit.keywords.marks['substitution'] ) );
	var tempValue    = actionString.substring( actionString.indexOf( Unit.keywords.marks['substitution'] ) + 1, actionString.indexOf( Unit.keywords.actions['styleAction'] ) );

	tempStyleAction = function()
	{
		for( var i = 0; i < actionTargets.length; i++ )
		{
			actionTargets[i].style[tempProperty] = tempValue;
		}
	}

	return tempStyleAction;
}

/* method - getFunctionalAction  */
Actions.prototype.getFunctionalAction = function( actionString, actionTargets )
{
	var tempFunctionalAction;
	var tempActionValue    = actionString.substring( 0, actionString.indexOf( Unit.keywords.actions['functionalAction'] ) );
	var tempAction         = Actions[tempActionValue];

	tempFunctionalAction = function()
	{
		tempAction( actionTargets );
	}

	return tempFunctionalAction;
}

/* method - setEvent  */
Actions.prototype.setEvent = function( trigger, eventType, action )
{
	if( eventType.indexOf( Unit.keywords.actions['execution'] ) != -1 )
	{
		action();
	}
	else
	{
		if( !trigger )
		{
			return false;
		}
		if( trigger.addEventListener )
		{
			trigger.addEventListener( eventType, action, false );
		}
		else if( trigger.attachEvent )
		{
			trigger.attachEvent( 'on'+eventType, action );
		}
		else
		{
			return false;
		}
	}

	return true;
}

