(function( $ )
{
	$.fn.JQStyle = function(method) 
	{
		if (!$('body').data('JQStyle_RulesMap'))
		{
			$.fn.JQStyle.methods._init();
		}
		
		if (this.JQStyle.methods[method])
		{
			this.JQStyle.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		}
		else
		{
			$.error( 'Method ' +  method + ' does not exist on jQuery.JQStyle' );
		}
		
		return this;
	};

	$.fn.JQStyle.JQStylers = 
	{
		parent : function(Selector, AttributeValue)
			{
				var Elements = $(Selector);

				//check if the elements do not already exist
				if (Elements.length == 0)
				{
					var ElementSelectorTerms = Selector.split('.');
					
					if (ElementSelectorTerms.length == 2)
					{
						var ElementType = ElementSelectorTerms[0];
						var ElementClass = ElementSelectorTerms[1];
						Elements = $('<' + ElementType + ' class="' + ElementClass + '"></' + ElementType + '>');
					}
				}

				var Container = $(AttributeValue);
				
				// Check that the parent exists and is unique
				if (Container.length == 1)
				{
					Container.append(Elements);
				}
			},
		copytoparent : function(Selector, AttributeValue)
			{
				var Elements = $(Selector);

				var Containers = $(AttributeValue);

				Elements.each(function()
				{
					var Element = $(this);
					
					Containers.each(function()
					{
						var ElementClone = Element.clone();
						$(this).append(ElementClone);
					});
				});
			},
		child : function(Selector, AttributeValue)
			{
				var Element = $(Selector);
	
				//check if the element exists 
				Element.each(function()
				{
					var content = $(this).html();
					
					$(this).html('');

					$(this).append('<'+AttributeValue+'>'+content+'</'+AttributeValue+'>');
				});
			},
		elementtype : function(Selector, AttributeValue)
			{
				var Element = $(Selector);
	
				//check if the element exists 
				Element.each(function()
				{
					var Parent = $(this).parent();
					var line = $(this).html().replace(/^\s+/,'').replace(/\s+$/,'');

					$(this).remove();
					
					Parent.append('<'+AttributeValue+'>'+line+'</'+AttributeValue+'>');
				});
			},
		contentsplit : function(Selector, AttributeValue)
			{
				var Element = $(Selector);
				
				if (AttributeValue == '\\n')
				{
					AttributeValue = '\n';
				}
	
				//check if the element exists 
				Element.each(function()
				{
					var Parent = $(this).parent();
					var contentlines = $(this).html().replace(/^\s+/,'').replace(/\s+$/,'').split(AttributeValue);
					var ElementSample = $(this);
					
					$(this).remove();
					
					$.each(contentlines, function()
					{
						var ElementClone = ElementSample.clone();
						var Text = String(this);
						
						Parent.append(ElementClone);
						ElementClone.html(Text);
					});
				});
			},
		id : function(Selector, AttributeValue)
			{
				var Element = $(Selector);

				//check if the element exists and is unique
				if (Element.length == 1)
				{
					var ElementWithID = $('#' + AttributeValue);
					
					if (ElementWithID.length == 0)
					{
						Element.attr('id', AttributeValue);
					}
				}
			}
	};
	
	$.fn.JQStyle.JQSizers = 
	{
		topmargin : function(Selector, AttributeValue)
			{
				var Element = $(Selector);
	
				//check if the element exists and is unique
				if (Element.length == 1)
				{
					if (AttributeValue == 'height')
					{
						Element.css('margin-top', Element.height());
					}
					else if (AttributeValue == '-height')
					{
						Element.css('margin-top', -Element.height());
					}
					else if (AttributeValue == 'outerHeight')
					{
						Element.css('margin-top', Element.outerHeight());
					}
					else if (AttributeValue == '-outerHeight')
					{
						Element.css('margin-top', -Element.outerHeight());
					}
				}
			},
		height : function(Selector, AttributeValue)
			{
				$(Selector).each(function()
				{
					var Element = $(this);
					
					if (AttributeValue == 'parent')
					{
						var ContainerHeight = Element.parent().height();
						var ElementDecoratorSpace = Element.outerHeight(true) - Element.height();
						
						Element.height(ContainerHeight - Element.position().top - ElementDecoratorSpace);
					}
				});
			},
		width : function(Selector, AttributeValue)
			{
				$(Selector).each(function()
				{
					var Element = $(this);
					
					if (AttributeValue == 'parent')
					{
						var ContainerWidth = Element.parent().width();
						var ElementDecoratorSpace = Element.outerWidth(true) - Element.width();
						
						Element.width(ContainerWidth - Element.position().left - ElementDecoratorSpace);
					}
				});
			},
		coincide_size : function(Selector, AttributeValue)
			{
				var Element = $(Selector);
	
				//check if the element exists and is unique
				if (Element.length == 1)
				{
					var Target = $(AttributeValue);
					
					//check if the target exists and is unique
					if (Target.length == 1)
					{
						Element.height(Target.innerHeight());
						Element.width(Target.innerWidth());
					}
				}
			},
		coincide_position : function(Selector, AttributeValue)
			{
				var Element = $(Selector);
	
				//check if the element exists and is unique
				if (Element.length == 1)
				{
					var Target = $(AttributeValue);
					
					//check if the target exists and is unique
					if (Target.length == 1)
					{
						var Coordinates = Target.offset();
						
						Element.css('position', 'absolute');
						Element.css('margin', '0px');
						Element.css('padding', '0px');
						Element.offset(Coordinates);
					}
				}
			},
		center : function(Selector, AttributeValue)
			{
				var Element = $(Selector);
	
				//check if the element exists and is unique
				if (Element.length == 1)
				{
					if (AttributeValue == 'vertical' || AttributeValue == 'both')
					{
						var Height = Element.outerHeight();
						var MarginTop = (Element.parent().height() - Height) / 2;
						
						Element.css('margin-top', MarginTop);
					}
	
					if (AttributeValue == 'horizontal' || AttributeValue == 'both')
					{
						var Width = Element.outerWidth();
						var MarginLeft = (Element.parent().width() - Width) / 2;
						
						Element.css('margin-left', MarginLeft);
					}
				}
			}
		};
	
	$.fn.JQStyle.methods = 
	{
		_init: function()
			{
				this._parseJSS();
				this._setContainment();
			},
		_parseJSS : function()
			{
				var JQLinks = new Array();
				
				$('link[type=text/jss]').each(function()
				{
					JQLinks.push($(this).attr('href'));
				});
				
				var StyleStrings = new Array();
				var JQRules = new Array();

				$.each(JQLinks, function()
				{
					var Link = String(this);
					
					$.ajax( 
					{
						url: Link,
						async: false,
						success: function(data)
						{
							StyleStrings.push(data);
						}
					});
				});

				$.each(StyleStrings, function()
				{
					var StyleString = this;	
					var JQRuleTextArray = StyleString.split('}'); 

					$.each(JQRuleTextArray, function()
					{
						var JQRuleText = this;
						var JQRuleTerms = JQRuleText.split('{');

						if (JQRuleTerms && JQRuleTerms.length == 2)
						{
							var JQAttributes = new Array();

							$.each(JQRuleTerms[1].split(';'), function()
							{
								var JQStyleTerms = this.split(':');

								if (JQStyleTerms && JQStyleTerms.length == 2)
								{
									JQAttributes.push({name:JQStyleTerms[0], value:JQStyleTerms[1]});
								}
							});

							var JQRuleItem = {selector: JQRuleTerms[0], attributes: JQAttributes};
							
							JQRules.push(JQRuleItem);
						}
					});
				});

				var JQRuleMap = new Object();
				$.each(JQRules, function()
				{
					var Attributes = new Object();
					
					$.each(this.attributes, function()
					{
						Attributes[this.name.replace(/\s/g, '')] = this.value.replace(/^\s+/,'').replace(/\s+$/,'');
					});
					
					JQRuleMap[this.selector.replace(/\s/g, '')] = Attributes; 
				});
				
				$('body').data('JQStyle_RulesMap', JQRuleMap);
				
				return JQRuleMap;
			},
		_setContainment : function()
			{
				var JQRules = $('body').data('JQStyle_RulesMap');
				var JQStylers = $.fn.JQStyle.JQStylers;

				for (Selector in JQRules)
				{
					if (JQRules.hasOwnProperty(Selector))
					{
						var Elements = $(Selector);
						var Attributes = JQRules[Selector];

						for (Attribute in Attributes)
						{
							if (JQStylers.hasOwnProperty(Attribute))
							{
								JQStylers[Attribute](Selector, Attributes[Attribute]);
							}
						}
					}
				}
			},
		adjustLayout : function()
			{
				var JQRules = $('body').data('JQStyle_RulesMap');
				var JQSizers = $.fn.JQStyle.JQSizers;

				for (Selector in JQRules)
				{
					if (JQRules.hasOwnProperty(Selector))
					{
						var Elements = $(Selector);
						var Attributes = JQRules[Selector];

						for (Attribute in Attributes)
						{
							if (JQSizers.hasOwnProperty(Attribute))
							{
								JQSizers[Attribute](Selector, Attributes[Attribute]);
							}
						}
					}
				}
			},
		setLayout : function(AttributeName, AttributeValue)
			{
				var JQSizers = $.fn.JQStyle.JQSizers;
	
				if (JQSizers.hasOwnProperty(AttributeName))
				{
					var Selector = this;
					JQSizers[AttributeName](Selector, AttributeValue);
				}
			}
	};
})(jQuery);


