/* RGB <-> HSV */

function RGBtoHSV(R, G, B){
  R=R*1;
  G=G*1;
  B=B*1;
  minVal=Math.min(Math.min(R, G), B);
  V=Math.max(Math.max(R, G), B);
  Delta=V-minVal;

  // Calculate saturation: saturation is 0 if r, g and b are all 0
  if (V==0.0){
    S=0.0;
  }else{
    S=Delta / V;
  }
  if (S==0.0){
    H=0.0;    // Achromatic: When s = 0, h is undefined but who cares
  }else{       // Chromatic
    if (R==V){ // between yellow and magenta [degrees]
      H=60.0*(G-B)/Delta;
    }else{
      if (G==V){ // between cyan and yellow
        H=120.0+60.0*(B-R)/Delta;
      }else{ // between magenta and cyan
        H=240.0+60.0*(R-G)/Delta;
      }
    }
  }
  if (H<0.0) H=H+360.0;
  // return a list of values as an rgb object would not be sensible
  return new Array(H,S*100,V*100);
}

function HSVtoRGB(H, S, V){
  H=H*1;
  S=S/100;
  V=V/100;
  if (S==0.0){   // color is on black-and-white center line
    R=V;          // achromatic: shades of gray
    G=V;          // supposedly invalid for h=0 but who cares
    B=V;
  }else{ // chromatic color
   if (H==360.0){// 360 degrees same as 0 degrees
      hTemp=0.0;
   }else{
      hTemp=H;
   }
    hTemp=hTemp/60.0;   // h is now in [0,6)
    
    fi=Math.floor(hTemp);  // largest integer <= h
    fr=hTemp-fi;          // fractional part of h 
    p=V*(1.0-S);
    q=V*(1.0-(S*fr));
    t=V*(1.0-(S*(1.0-fr)));

    if(fi==0){
        R = V;
        G = t;
        B = p;
    }else if(fi==1){
        R = q;
        G = V;
        B = p;
    }else if(fi==2){
        R = p;
        G = V;
        B = t;
    }else if(fi==3){
        R = p;
        G = q;
        B = V;
    }else if(fi==4){
        R = t;
        G = p;
        B = V;
    }else{
        R = V;
        G = p;
        B = q;
    }
  }
  return new Array(R*255,G*255,B*255);
}

function hex2rgb(hex){
	if(hex.charAt(0)=='#'){
		hex=hex.substring(1,hex.length-1);
	}
	if(hex.length == 3){
		hex=hex.charAt(0)+hex.charAt(0)+hex.charAt(1)+hex.charAt(1)+hex.charAt(2)+hex.charAt(2);
	}
	hex=hex.toUpperCase();
	r=hex2dec(hex.substring(0,2));
	g=hex2dec(hex.substring(2,2));
	b=hex2dec(hex.substring(4,2));
	return new Array(r,g,b);
}

function hex2dec(hex){
	chars='0123456789ABCDEF';
	p=0;t=0;
	for(i=hex.length-1;i>-1;i--){
		t+=chars.indexOf(hex.charAt(i)) * Math.pow(16,p++);
	}
	return t;
}

function dec2hex(dec){
	chars='0123456789ABCDEF';
	hex='';
	p=Math.pow(16,Math.floor(Math.log(dec)/Math.log(16)));
	for(;p>.0625;p/=16){
		n=Math.floor(dec/p);
		hex+=chars.charAt(n);	
		dec-=n*p;
	}
	return hex;
}
function rgb2hex(r,g,b){
	hex='#'+pad(dec2hex(Math.floor(r)),2)
		+pad(dec2hex(Math.floor(g)),2)
		+pad(dec2hex(Math.floor(b)),2);
	return hex;	
}
function pad(what,by){
	z=by-what.length;
	for(i=0;i<z;i++){
		what = '0'+what;
	}
	return what;
}