'use strict';

function round( value, precision ) {
  return parseFloat( value.toFixed( precision ) );
}

function limit( value, min, max ) {
  return Math.min( Math.max( value, min ), max );
}

function randomInt( min, max ) {
  return Math.round( min + Math.random() * ( max - min ) );
}

function RGBAColor( red, green, blue, alpha ) {
  this.red   = red   || 0;
  this.green = green || 0;
  this.blue  = blue  || 0;
  this.alpha = alpha || 0.0;
}

RGBAColor.prototype.css = function( totalAlpha ) {
  if ( typeof totalAlpha === 'undefined' ) {
    totalAlpha = 1;
  }

  return 'rgba(' +
    Math.round( limit( this.red,   0, 255 ) ) + ', ' +
    Math.round( limit( this.green, 0, 255 ) ) + ', ' +
    Math.round( limit( this.blue,  0, 255 ) ) + ', ' +
    round( this.alpha / totalAlpha, 2 ) +
  ')';
};

function HSLAColor( hue, saturation, lightness, alpha ) {
  this.hue        = hue        || 0;
  this.saturation = saturation || 0.0;
  this.lightness  = lightness  || 0.0;
  this.alpha      = alpha      || 0.0;
}

HSLAColor.prototype.css = function( totalAlpha ) {
  if ( typeof totalAlpha === 'undefined' ) {
    totalAlpha = 1;
  }

  return 'hsla(' +
    Math.round( limit( this.hue, 0, 360 ) ) + ', ' +
    this.saturation.toFixed(0) + '%, ' +
    this.lightness.toFixed(0)  + '%, ' +
    round( this.alpha / totalAlpha, 2 ) +
  ')';
};

function ColorStop( color, position ) {
  this.color    = color || new RGBAColor();
  this.position = position || null;
}

ColorStop.prototype.css = function( totalAlpha ) {
  return this.color.css( totalAlpha ) + ( this.position ? ' ' + this.position : '' );
};

/**
 * Gradient.
 */
function Gradient() {
  this.colorStops = [];
}

Gradient.prototype.maxAlpha = function() {
  return Math.max.apply( this, this.colorStops.map(function( colorStop ) {
    return colorStop.color.alpha;
  }));
};

Gradient.prototype.colorStopsString = function( totalAlpha ) {
  return this.colorStops.map(function( colorStop ) {
    return colorStop.css( totalAlpha );
  }).join( ', ' );
};

/**
 * LinearGradient.
 */
function LinearGradient() {
  Gradient.call( this );
  this.angle = '';
}

LinearGradient.prototype = new Gradient();
LinearGradient.prototype.constructor = LinearGradient;

LinearGradient.prototype.css = function( totalAlpha ) {
  return 'linear-gradient(' +
    ( this.angle ? this.angle + ', ' : '' ) +
    this.colorStopsString( totalAlpha ) +
  ')';
};

/**
 * RadialGradient.
 */
function RadialGradient() {
  Gradient.call( this );
  this.position = '';
  this.angle = '';
  this.shape = '';
  this.size = '';
}

RadialGradient.prototype = new Gradient();
RadialGradient.prototype.constructor = RadialGradient;

RadialGradient.prototype.css = function( totalAlpha ) {
  return 'radial-gradient(' +
    ( this.position ? this.position + ', ' : '' ) +
    ( this.shape ? this.shape + ', ' : '' ) +
    this.colorStopsString( totalAlpha ) +
  ')';
};

/**
 * Background.
 */

function Background() {
  this.gradients = [];
}

Background.prototype.css = function() {
  var totalAlpha = this.gradients.reduce(function( previousValue, gradient ) {
    return previousValue + gradient.maxAlpha();
  }, 0 );

  return this.gradients.map(function( gradient ) {
    return gradient.css( totalAlpha );
  }).join( ', ' );
};



@@ -8,16 +8,81 @@
 rict';%0A%0A
+var RAD_TO_DEG = 180 / Math.PI,%0A    DEG_TO_RAD = Math.PI / 180;%0A%0A
 function
@@ -860,32 +860,204 @@
  ) +%0A  ')';%0A%7D;%0A%0A
+function RGBColor( red, green, blue ) %7B%0A  RGBAColor.call( this, red, green, blue, 1 );%0A%7D%0A%0ARGBColor.prototype = new RGBAColor();%0ARGBColor.prototype.constructor = RGBColor;%0A%0A
 function HSLACol
@@ -1571,36 +1571,225 @@
 a, 2 ) +%0A  ')';%0A
-
 %7D;%0A%0A
+function HSLColor( hue, saturation, lightness ) %7B%0A  HSLAColor.call( this, hue, saturation, lightness );%0A%7D%0A%0AHSLColor.prototype = new HSLAColor();%0AHSLColor.prototype.constructor = HSLColor;%0A%0A
 function ColorSt

Add RGBColor and HSLColor classes to background-gradient.