var color_attributes = new Array(
				 "backgroundColor",
				 "borderColor",
				 "borderTopColor",
				 "borderBottomColor",
				 "borderLeftColor",
				 "borderRightColor",
				 "color"
				 );


function cloneColorStyles(style) {
    var copy = new Object();
    for(i in color_attributes) {
        copy[color_attributes[i]] = style[color_attributes[i]];
    }
    return copy;
}
	
var rotateStep = 10;

var phase = 0;
var valuePhase = 0;
var valuePhaseStep = 5;
var oldStyles = new Array();

var keepitgoing;
var rainbowlabel;
var colorSwitchTimer;
var resetButton;

var transformMode = "HSV";

var HSVBox;
var HSVSlider;
var settingsPopup;
var currrentSlider;

var hsv = new Array();
var hsvDebug;

var rgbIn;
var hsv;
var rgbOut;

function rotateColor(color) {   
    rgbIn = color.match(/\d+/g);

    if(!rgbIn)
	return "rgb(0,0,0);";
    
    if(transformMode == "HSV") {
	hsv = rgb2hsv(rgbIn);
	hsv[0] -= phase;
	if(hsv[0] < 0)
	    hsv[0] += 360;
	hsv[2] = Math.abs(hsv[2]-valuePhase/100);
	rgbOut = hsv2rgb(hsv);
    }

    else if(transformMode = "RGB") {
	var weight0;
	var weight1;
	var weight2;

	if(phase < 120) {
	    weight0 = (120-phase)/120;
	    weight1 = phase/120;
	    weight2 = 0;
	}

	if(phase >= 120) {
	    weight0 = 0;
	    weight1 = (240-phase)/120;
	    weight2 = (phase-120)/120;
	}

	if(phase >= 240) {
	    weight0 = (phase-240)/120;
	    weight1 = 0;
	    weight2 = (360-phase)/120;
	}

	r = rgbIn[0];
	g = rgbIn[1];
	b = rgbIn[2];

	inversion = valuePhase * 255 / 100;

	rout = Math.abs(Math.round(r*weight0+g*weight1+b*weight2-inversion));
	gout = Math.abs(Math.round(g*weight0+b*weight1+r*weight2-inversion));
	bout = Math.abs(Math.round(b*weight0+r*weight1+g*weight2-inversion));

	rgbOut = Array(rout, gout, bout);
    }

    return "rgb("+rgbOut.join(',')+")";
}

function colorSwitcher() {
    mainStyleSheet = document.styleSheets[0];

    // IE/FF hack - cssRules is standard collection, but IE
    // doesn't it differently...
    if(mainStyleSheet.cssRules)
	rules = mainStyleSheet.cssRules;
    else if(mainStyleSheet.rules)
	rules = mainStyleSheet.rules;
    
    for(j = 0; j < mainStyleSheet.cssRules.length; j++) {
	rule = mainStyleSheet.cssRules[j];
	ruleStyle = mainStyleSheet.cssRules[j].style;
	
	if(!oldStyles[j])
	    oldStyles[j] = cloneColorStyles(ruleStyle);
	
	for(k = 0; k < color_attributes.length; k++) {
	    attr = color_attributes[k];
	    if(ruleStyle[attr])
		ruleStyle[attr] = rotateColor(oldStyles[j][attr]);
	}
    }

    keepItGoing();
}

function resetColors() {
    keepitgoing.checked = false;

    // reset phase/value phase
    phase = 0;
    valuePhase = 0;

    // IE/FF hack - cssRules is standard collection, but IE
    // doesn't it differently...
    if(mainStyleSheet.cssRules)
	    rules = mainStyleSheet.cssRules;
    else if(mainStyleSheet.rules)
	rules = mainStyleSheet.rules;
    
    for(j = 0; j < rules.length; j++) {
	rule = rules[j];
	
	if(oldStyles[j]) {
	    for(k in color_attributes) {
		rule.style[color_attributes[k]] = 
		    oldStyles[j][color_attributes[k]];
	    }
	}
    }

    if(resetButton.childNodes[0]) {
	clearTimeout(colorSwitchTimer);
	resetButton.removeChild(resetButton.childNodes[0]);
	keepItGoing();
    }

    // reset slider position
    currentSlider.style.left = "0px";
    currentSlider.style.top  = "0px";
}    

var valuePhaseDir=1;

function updateSlider(event) {
    currentSlider.style.left = Math.round(phase*264/360)+"px";
    currentSlider.style.top  = Math.round(valuePhase*264/100)+"px";
}
function colorSwitchStep(event) {
    phase += rotateStep;

    if(phase > 360)
	phase -= 360;
    if(phase < 0)
	phase += 360;

    valuePhase += valuePhaseStep*valuePhaseDir;
    if(valuePhase > 100) {
	valuePhase = 100;
	valuePhaseDir = -1;
    } if(valuePhase < 0) {
	valuePhase = 0;
	valuePhaseDir = 1;
    }
    colorSwitcher();
    updateSlider(event);
}
function keepItGoing() {
    if(keepitgoing.checked) {
	if(!resetButton.childNodes[0])
	    resetButton.appendChild(document.createTextNode("Reset please!"));

	rainbowlabel.childNodes[0].nodeValue = "DEAR GOD MAKE IT STOP";
	clearTimeout(colorSwitchTimer);
	colorSwitchTimer = setTimeout("colorSwitchStep()", 50);
    } else {
	rainbowlabel.childNodes[0].nodeValue = "What's this do?";
	clearTimeout(colorSwitchTimer);
    }
	
}
var sliding;

function beginSlide(event) {
    // turn off auto-run if it's running
    if(keepitgoing.checked) {
	keepitgoing.checked = false;
	clearTimeout(colorSwitchTimer);
    }
    sliding = true;
    origin = findPos(HSVBox);
    hsvDebug = "";

    slideX = origin[0]+20;
    slideY = origin[1]+20;
}
function endSlide(event) {
    sliding = false;
}

function doSlide(event) {
    if(window.event) event = window.event;

    if(sliding) {
	if(!resetButton.childNodes[0])
	    resetButton.appendChild(document.createTextNode("Reset please!"));

	left = currentSlider.style.left;
	top  = currentSlider.style.top;

	positionX = event.clientX;
	offset = positionX - slideX;

	if(offset < 0)
	    offset = 0;
	else if(offset > 272)
	    offset = 272;

	phase = 360*offset/272;

	position = Math.min(offset, 264);
	left = position+ "px";

	positionY = event.clientY;
	offset = positionY - slideY;
	
	if(offset < 0) 
	    offset = 0;
	else if(offset > 272)
	    offset = 272;

	valuePhase = Math.round(Math.min(offset/256*100,100.0));
	position = Math.min(offset, 264);
	top = position + "px";

	colorSwitcher();

	currentSlider.style.left = left;
	currentSlider.style.top  = top;
    }
}

function doJumpSlide(event) {
    beginSlide(event);
    doSlide(event);
}
function findPos(obj) {
    var curleft = curtop = 0;
    if (obj.offsetParent) {
	curleft = obj.offsetLeft;
	curtop = obj.offsetTop;
	while (obj = obj.offsetParent) {
	    curleft += obj.offsetLeft;
	    curtop += obj.offsetTop;
	}
    }

    curleft -= window.scrollX;
    curtop  -= window.scrollY;
    
    return new Array(curleft,curtop);
}

function togglePopupWindow(event) {
    if(!transformPopup.style.display ||
       transformPopup.style.display == "none") {
	transformPopup.style.display = "block";
	settingsPopup.childNodes[0].nodeValue = "Alright I'm done...";
    } else {
	transformPopup.style.display = "none";
	settingsPopup.childNodes[0].nodeValue = "Let me do that again...";
    }
}
function setRGBMode() {
    transformMode = "RGB";
    currentSlider = RGBSlider;
    HSVBox.style.zIndex = 3;
    RGBBox.style.zIndes = 4;
    HSVBox.onmousedown = 0;
    RGBBox.onmousedown = doJumpSlide;
    RGBBox.childNodes[1].style.fontWeight="bold";
    HSVBox.childNodes[1].style.fontWeight="normal";
}
function setHSVMode()  {
    transformMode = "HSV";
    currentSlider = HSVSlider;
    HSVBox.style.zIndex = 4;
    RGBBox.style.zIndes = 3;
    HSVBox.onmousedown = doJumpSlide;
    RGBBox.onmousedown = 0;
    HSVBox.childNodes[1].style.fontWeight="bold";
    RGBBox.childNodes[1].style.fontWeight="normal";
}
function setRotateStep(event) {
    var  val = stepBoxX.value.match(/-?\d+/);

    if(!val) val = 5;
    else if(val < -40) val = -40;
    else if(val > 40) val = 40;
    
    rotateStep = val;
    stepBoxX.value = val;
}
function setVPhaseStep(event) {
    var val = stepBoxY.value.match(/-?\d+/);

    if(!val) val = 5;
    else if(val < -30) val = -30;
    else if(val > 30) val = 30;
    
    valuePhaseStep = val;
    stepBoxY.value = val;
}

window.onload = function() {
    sliding = false;
    rainbowlabel = document.getElementById("rainbowlabel");

    settingsPopup = document.getElementById("popuplink");

    transformPopup = document.getElementById("popupwindow");

    popupClose = document.getElementById("popupclose");

    popupClose.onmousedown = togglePopupWindow;

    HSVBox = document.getElementById("hsvtransform");
    HSVSlider = document.getElementById("hsvslider");

    RGBBox = document.getElementById("rgbtransform");
    RGBSlider = document.getElementById("rgbslider");

    stepBoxX = document.getElementById("xstep");
    stepBoxY = document.getElementById("ystep");

    stepBoxX.value = rotateStep;
    stepBoxY.value = valuePhaseStep;

    stepBoxX.onblur = setRotateStep;
    stepBoxY.onblur = setVPhaseStep;

    document.onmouseup = endSlide;
    document.onmousemove = doSlide;

    settingsPopup.onmousedown = togglePopupWindow;

    HSVSlider.onmousedown = beginSlide;
    HSVSlider.onmouseup   = endSlide;
    HSVSlider.onmousemove = doSlide;

    currentSlider = HSVSlider;

    HSVBox.onmousedown = doJumpSlide;

    RGBSlider.onmousedown = beginSlide;
    RGBSlider.onmouseup   = endSlide;
    RGBSlider.onmousemove = doSlide;

    HSVBox.childNodes[1].onmousedown = setHSVMode;
    RGBBox.childNodes[1].onmousedown = setRGBMode;

    resetButton = document.getElementById("reset");
    resetButton.onclick = resetColors;

    keepitgoing = document.getElementById("keepitgoing");
    keepitgoing.onclick = keepItGoing;
    keepItGoing();

}
