text: /*
  ---
  
  name: Element.Style
  
  description: Contains methods for interacting with the styles of Elements in a fashionable way.
  
  license: MIT-style license.
  
  requires: Element
  
  provides: Element.Style
  
  ...
  */
  
  Element.Properties.styles = {set: function(styles){
  	this.setStyles(styles);
  }};
  
  Element.Properties.opacity = {
  
  	set: function(opacity, novisibility){
  		if (!novisibility){
  			if (opacity == 0){
  				if (this.style.visibility != 'hidden') this.style.visibility = 'hidden';
  			} else {
  				if (this.style.visibility != 'visible') this.style.visibility = 'visible';
  			}
  		}
  		if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1;
  		if (Browser.Engine.trident) this.style.filter = (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')';
  		this.style.opacity = opacity;
  		this.store('opacity', opacity);
  	},
  
  	get: function(){
  		return this.retrieve('opacity', 1);
  	}
  
  };
  
  Element.implement({
  
  	setOpacity: function(value){
  		return this.set('opacity', value, true);
  	},
  
  	getOpacity: function(){
  		return this.get('opacity');
  	},
  
  	setStyle: function(property, value){
  		switch (property){
  			case 'opacity': return this.set('opacity', parseFloat(value));
  			case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat';
  		}
  		property = property.camelCase();
  		if ($type(value) != 'string'){
  			var map = (Element.Styles.get(property) || '@').split(' ');
  			value = $splat(value).map(function(val, i){
  				if (!map[i]) return '';
  				return ($type(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
  			}).join(' ');
  		} else if (value == String(Number(value))){
  			value = Math.round(value);
  		}
  		this.style[property] = value;
  		return this;
  	},
  
  	getStyle: function(property){
  		switch (property){
  			case 'opacity': return this.get('opacity');
  			case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat';
  		}
  		property = property.camelCase();
  		var result = this.style[property];
  		if (!$chk(result)){
  			result = [];
  			for (var style in Element.ShortStyles){
  				if (property != style) continue;
  				for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s));
  				return result.join(' ');
  			}
  			result = this.getComputedStyle(property);
  		}
  		if (result){
  			result = String(result);
  			var color = result.match(/rgba?\([\d\s,]+\)/);
  			if (color) result = result.replace(color[0], color[0].rgbToHex());
  		}
  		if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(result, 10)))){
  			if (property.test(/^(height|width)$/)){
  				var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
  				values.each(function(value){
  					size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
  				}, this);
  				return this['offset' + property.capitalize()] - size + 'px';
  			}
  			if ((Browser.Engine.presto) && String(result).test('px')) return result;
  			if (property.test(/(border(.+)Width|margin|padding)/)) return '0px';
  		}
  		return result;
  	},
  
  	setStyles: function(styles){
  		for (var style in styles) this.setStyle(style, styles[style]);
  		return this;
  	},
  
  	getStyles: function(){
  		var result = {};
  		Array.flatten(arguments).each(function(key){
  			result[key] = this.getStyle(key);
  		}, this);
  		return result;
  	}
  
  });
  
  Element.Styles = new Hash({
  	left: '@px', top: '@px', bottom: '@px', right: '@px',
  	width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
  	backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
  	fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
  	margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
  	borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
  	zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
  });
  
  Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};
  
  ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
  	var Short = Element.ShortStyles;
  	var All = Element.Styles;
  	['margin', 'padding'].each(function(style){
  		var sd = style + direction;
  		Short[style][sd] = All[sd] = '@px';
  	});
  	var bd = 'border' + direction;
  	Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
  	var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
  	Short[bd] = {};
  	Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
  	Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
  	Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
  });
  