/*
 * ColourJS 1.0 - JavaScript Colour Manipulation
 * Copyright (C) 2008  Sid Roberts (http://www.sidroberts.co.uk/)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Version: 1.0
 * Released: 2008-04-05 11:21:25 +0000 (Wed, 05 Apr 2008)
 * Get the latest version at http://www.sidroberts.co.uk/tag/colourjs/
 */


var ColorJS = ColourJS = function(val, format) {
	if(typeof val != 'object') switch(format)
	{
		case 'hex':
			// Get rid of all whitespace.
			val = val.replace(/\s/g, '');

			// This chunk takes the value and tries to fix it, giving a 6 digit hex without the hash (#).
			if(val.length == 3) { val = val.substr(0, 1) + val.substr(0, 1) + val.substr(1, 1) + val.substr(1, 1) + val.substr(2, 1) + val.substr(2, 1); }
			else if(val.length == 4 && val.substr(0, 1) == '#') { val = val.substr(1, 1) + val.substr(1, 1) + val.substr(2, 1) + val.substr(2, 1) + val.substr(3, 1) + val.substr(3, 1); }
			else if(val.length == 6) { val = val; }
			else if(val.length == 7 && val.substr(0, 1) == '#') { val = val.substr(1, 6); }
			else { return false; }

			// Every letter must be between A-F or 0-9 so if it isn't, let's just bail out...
			if(/[A-F0-9]/i.test(val) == false) { return false; }

			// Scale of Hex to RGB
			var scale = [];
			scale['F'] = 15;	scale['B'] = 11;	scale['7'] =  7;	scale['3'] =  3;
			scale['E'] = 14;	scale['A'] = 10;	scale['6'] =  6;	scale['2'] =  2;
			scale['D'] = 13;	scale['9'] =  9;	scale['5'] =  5;	scale['1'] =  1;
			scale['C'] = 12;	scale['8'] =  8;	scale['4'] =  4;	scale['0'] =  0;

			// CAPS LOCK!
			val = val.toUpperCase();

			val = {
				r: (scale[val.substr(0, 1)] * 16) + scale[val.substr(1, 1)],
				g: (scale[val.substr(2, 1)] * 16) + scale[val.substr(3, 1)],
				b: (scale[val.substr(4, 1)] * 16) + scale[val.substr(5, 1)]
			};

			break;
		case 'rgb':
			// Remove labels, brackets and whitespace. Then split it into an array.
			val = val.replace(/(rgb)|\(|\s|\)/gi, '').split(',');
			val = {
				r: !isNaN(val[0]) ? (val[0] < 0 ? 0 : (val[0] > 255 ? 255 : val[0])) : (val[0].indexOf('%') ? val[0].replace(/%/g, '') / 100 * 255 : 0),
				g: !isNaN(val[1]) ? (val[1] < 0 ? 0 : (val[1] > 255 ? 255 : val[1])) : (val[1].indexOf('%') ? val[1].replace(/%/g, '') / 100 * 255 : 0),
				b: !isNaN(val[2]) ? (val[2] < 0 ? 0 : (val[2] > 255 ? 255 : val[2])) : (val[2].indexOf('%') ? val[2].replace(/%/g, '') / 100 * 255 : 0)
			};

			break;
		// Try and auto-detect if no format was given.
		default:
			if(/(#)/i.test(val)) { return ColourJS(val, 'hex'); }
			else if(/(rgb)/i.test(val)) { return ColourJS(val, 'rgb'); }

			return false;
			break;
	}

	return {
/*
	CHANNELS:

	Red (r), green (g) and blue (b). To return just these channels, use the END function .toObject().
*/
		r: val.r,
		g: val.g,
		b: val.b,

/*
	MAIN FUNCTIONS:

	All functions must end:
>			return this;
	...to keep the chain going.
*/
		invert: function() {
			this.r = 255 - this.r,
			this.g = 255 - this.g,
			this.b = 255 - this.b

			return this;
		},

/*
	END FUNCTIONS:

	These functions return workable data and gets rid of the ColourJS Object. Once one of these functions is run, the chain ends. Also, anything they output must be rounded up to the nearest integer.
*/
		toRGB: function() {
			return 'rgb(' + Math.round(this.r) + ', ' + Math.round(this.g) + ', ' + Math.round(this.b) + ')';
		},
		toHex: function() {
			this.r = Math.round(this.r);
			this.g = Math.round(this.g);
			this.b = Math.round(this.b);

			// Scale of RGB to Hex.
			var scale = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];

			for(var i in this)
			{
				var a = Math.floor(this[i] / 16);
				var b = ((this[i] / 16) - a) * 16;

				this[i] = scale[a] + scale[b];
			}

			return '#' + this.r + this.g + this.b;
		},
		toObject: function() {
			return {
				r: Math.round(this.r),
				g: Math.round(this.g),
				b: Math.round(this.b)
			};
		}
	};
};