INTERVAL=1000 ; // milliseconds . Change this value if you think the updates 
		// are too slow/fast
color=0 ;
statok=true ;
molti =1 ;
debug=false ;	


aspettando=false ;

addary = new Array();           //red
addary[0] = new Array(0,1,0);   //red green
addary[1] = new Array(-1,0,0);  //green
addary[2] = new Array(0,0,1);   //green blue
addary[3] = new Array(0,-1,0);  //blue
addary[4] = new Array(1,0,0);   //red blue
addary[5] = new Array(0,0,-1);  //red
addary[6] = new Array(255,1,1);
clrary = new Array(360);
for(i = 0; i < 6; i++)
for(j = 0; j < 60; j++) {
  clrary[60 * i + j] = new Array(3);
  for(k = 0; k < 3; k++) {
    clrary[60 * i + j][k] = addary[6][k];
    addary[6][k] += (addary[i][k] * 4);
    }
  }
zeri="000000"

colorecorre=new Array(3)

function aumenta (n) {
	molti=molti + n ;
	if (molti <=1) {
	 molti =1
	 elesmaller.setAttribute("disabled","disabled")
	} else 
		 elesmaller.removeAttribute("disabled") ;	
	wheelimma=document.getElementById("wheelimg") ;
	strisciaimma=document.getElementById("barraimg") ;
	valore=Math.floor(258*molti)+"px" ;
	strisciaimma.style.height=valore ;
	/*elewheel.style.width=valore ;
	elewheel.style.lineHeight=valore ; */
	wheelimma.style.width=valore ;
	wheelimma.style.height=valore ;
	strisciaimma.style.width=Math.floor(32*molti)+"px" ;
}
	
function calcolavalorihtml() {
 valorihtml=new Array(4) ;
 colorirgb=new Array(4) ;
 for (i=0 ; i < 4 ; i++) {
   valorihtml[i]=new Array(5) ;
   valorihtml[i][0]=document.getElementById("c"+String(i)+"0") ;
   valorihtml[i][1]=document.getElementById("c"+String(i)+"1") ;
   valorihtml[i][2]=document.getElementById("contrasto"+String(i)) ;
   valorihtml[i][3]=document.getElementById("luminosita"+String(i)) ;
   valorihtml[i][4]=document.getElementById("ratio"+String(i)) ;	
   valorihtml[i][5]=document.getElementById("esempio"+String(i)) ;
   colorirgb[i]=new Array(2)
   colorirgb[i][0]=[0,0,0]
   colorirgb[i][1]=[255,255,255]
 }
 elewheel=document.getElementById("wheel");   
 elestriscia=document.getElementById("barra");   
 elewheelimg=document.getElementById("wheelimg");   
 elestrisciaimg=document.getElementById("barraimg");   
 elesmaller=document.getElementById("bottosmaller");
 eleok=document.getElementById("ok");
 elemenu=document.getElementById("menulaterale");
 eledx=document.getElementById("dx");
 elesopra=document.getElementById("sopra");
 elealgocb=document.getElementById("algocbdifference") ;
 elealgolumi=document.getElementById("algoluminosity") ;
 elelevel=document.getElementById("level")
 eletextsize=document.getElementById("textsize")
}
function change_algo() {
	display_hide_algorows() ;
	hoverColor() ;
	visualizzaok() ;
}
		
function display_hide_algorows() {
	var show=document.all ? "block" : "table-row" ;
	for (var i=0 ; i <4 ; i++) {
		valorihtml[i][2].parentNode.parentNode.style.display=(elealgocb.checked ? show : "none") ;
		valorihtml[i][4].parentNode.parentNode.style.display=(elealgocb.checked ? "none" : show) ;
	}
}
function capture() {
 if (! document.getElementById)
 {
    alert("Sorry you need a DOM compatibile browser (Internet Explorer 6.0, Netscape 7.x or above,Opera 7.x or above,Mozilla,Konqueror ...) to use this page");
    return  ;
 }
 calcolavalorihtml();
 iniziadalto()
 disabilita()
 initcolor() ;
 elealgocb.checked=false ;
 elealgolumi.checked=true ;
 display_hide_algorows() ;
 colore(0) ;
}
function abilita() {
 elewheel.onmousemove = mouseMoved;
 elestriscia.onmousemove = mouseMovedStriscia;
}

function stop() {
	  document.getElementById("bottonefore").style.backgroundImage="none" ;
	  document.getElementById("bottoneback").style.backgroundImage="none" ;
	  disabilita();
	 }
function disabilita() {
 elewheel.onmousemove =null ;
 elestriscia.onmousemove=null;
}
function inverti() {
	foreprima=valorihtml[0][0].value ;
	backprima=valorihtml[0][1].value ;
	settacolor(backprima,true) ;
	settacolor(foreprima,false);
}
function cambiacolore(n) {
	visualizzaok();
	colore(n);
}
function colore (n) {
	color=n ;
	if (n==0) {
	  document.getElementById("bottonefore").style.backgroundImage="url('wheelfile/tondo.png')" ;
	  document.getElementById("bottoneback").style.backgroundImage="none" ;
	}
	else {
	  document.getElementById("bottonefore").style.backgroundImage="none" ;
	  document.getElementById("bottoneback").style.backgroundImage="url('wheelfile/tondo.png')" ;
	}
	abilita();
}


function mouseMovedStriscia(e) {
 if (document.all) {
  y =  Math.round(event.offsetY / molti) ;
 }
 else  
  y = (e.pageY -elestrisciaimg.offsetTop-1) / molti  ;
 y=clampasottosopra(y,0,255);
 colorirgb[0][color][0]= colorirgb[0][color][1]= colorirgb[0][color][2]=y
 hoverColor();
 return false;
}
function mouseMoved(e) {
 if (document.all) {
  x = 4 * event.offsetX /molti ;
  y = 4 * event.offsetY /molti;
 }
 else  {
  x = 4 * (e.pageX - elewheelimg.offsetLeft) /molti;
  y = 4 * (e.pageY -2 -elewheelimg.offsetTop ) /molti ;
 }

 sx = x - 512;
 sy = y - 512;
 qx = (sx < 0)?0:1;
 qy = (sy < 0)?0:1;
 q = 2 * qy + qx;
 quad = new Array(-180,360,180,0);
 xa = Math.abs(sx);
 ya = Math.abs(sy);
 d = ya * 45 / xa;
 if(ya > xa) d = 90 - (xa * 45 / ya);
 deg = Math.floor(Math.abs(quad[q] - d));
 sx = Math.abs(x - 512);
 sy = Math.abs(y - 512);
 r = Math.sqrt((sx * sx) + (sy * sy));
 if(x == 512 & y == 512) {colorirgb[0][color] = new Array(0,0,0);}
 else {
   for(i = 0; i < 3; i++) {
     r2 = clrary[deg][i] * r / 256;
     if(r > 256) r2 += Math.floor(r - 256);
     if(r2 > 255) r2 = 255;
     colorirgb[0][color][i]=Math.floor(r2);
   }
 }	
 hoverColor();
 return false;
}
function dargb(colore) {
	n=0 ;
	for (i=0 ; i<3 ; i++) {
	     n = 256 * n + colore[i];
	}	
	c=n.toString(16)
	return zeri.substring(0,6-c.length)+c ;
}
	
function initcolor() {
	Normalized=new Array(2) ;
	L=new Array(2) ;
	Srgb=new Array(2) ;
	for(var i=0 ; i<2 ; i++) {
		Normalized[i]=new Array(3) ;
		Srgb[i]=new Array(3) ;
	}
	settacolor("#000",true);
	settacolor("#fff",false) ;

}

function checkcolore(stringa) {
	var i ;
	espre= /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;
	if (espre.test(stringa)) {
	    return stringa
	} else
	  return "#000" ;
	}
function settaforecheck(fore) {
	fore=checkcolore(fore)
	settacolor(fore,true);
	colore(1);
}
function settacolor(stringa,foreground) {
	oldcolor=color ;
	indice=Number(!foreground)
	dahex(colorirgb[0][indice],stringa) ;
	
	color=indice;
	hoverColor() ;
	visualizzaok() ;
	color=oldcolor ;
}
function settabackcheck(backgr) {
	backgr=checkcolore(backgr)
	settacolor(backgr,false);
	colore(0);
}

function processa(n) {
	  shex=dargb(colorirgb[n][color])
	  if (shex.charAt(0)==shex.charAt(1) && shex.charAt(2)==shex.charAt(3) && shex.charAt(4)==shex.charAt(5)) {
	  	  shex=shex.charAt(0)+shex.charAt(2)+shex.charAt(4) ;
	  }
	  shex="#"+shex ;
	  if (color==1) {
		valorihtml[n][5].style.backgroundColor = shex;
          }
	  else {
		valorihtml[n][5].style.color = shex;
	  }
          valorihtml[n][color].value=shex ;
	  if (elealgocb.checked) {
	  contra=calcolacontrasto(colorirgb[n][0],colorirgb[n][1]) ;
	  okcontra= contra>500 ;
	  valorihtml[n][2].value=contra+ (okcontra ? " ok" : "") ;
	  lumi=calcolalum(colorirgb[n][0],colorirgb[n][1]) ;
	  oklumi=lumi >125;
       	  valorihtml[n][3].value=lumi+ (oklumi ? " ok" : "") ;
	  /*if (color==1) {		
		valorihtml[n][5].style.backgroundColor =stringahex;
	  }	
 	  else {
		valorihtml[n][5].style.color = stringahex;
          } */
	  return oklumi && okcontra ;
	 } else {
	   ratio=Math.round(calcolaratio(colorirgb[n][0],colorirgb[n][1]) *10) / 10 ;
	   if (elelevel.selectedIndex==0) {
	   	   if (eletextsize.selectedIndex==0) {
	   	   	   target=4.5
	   	   } else {
	   	   	   target=3
	   	   }
	   } else {
	   	    if (eletextsize.selectedIndex==0) {
	   	   	   target=7
	   	   } else {
	   	   	   target=4.5
	   	   }
	   }
	     	   
	   okratio=ratio >=target ;
	   valorihtml[n][4].value=ratio+":1"+ (okratio ? " ok" : "") ;
	   return okratio ;
	 }
}

function visualizzaok() {
	window.clearTimeout(timerId) ;
        aspettando=false ;
	updatecolori()
	statok=processa(0) 
        statok=processa(1)&& statok  ;
	statok=processa(2) && statok;
	statok= processa(3) && statok;
	if (statok) {
		eleok.style.visibility="visible"
	}
	else {
		eleok.style.visibility="hidden" ;
	}
}

function hoverColor() {
	var i,risu ;
	statok=processa(0) ; 
	if (!aspettando)
	{
		timerId=window.setTimeout(visualizzaok,INTERVAL) ;
		aspettando=true ;
	}

}
function dahex(arra ,stringa) {
	if(stringa.length==4) {
		stringa="#"+stringa.charAt(1)+stringa.charAt(1)+stringa.charAt(2)+stringa.charAt(2)+stringa.charAt(3)+stringa.charAt(3) ;
	}
		
	arra[0]=parseInt(stringa.substr(1,2),16) ;
	arra[1]=parseInt(stringa.substr(3,2),16) ;
	arra[2]=parseInt(stringa.substr(5,2),16) ;
}

function calcolacontrasto(colora,colorb)
{
	var contra ;
	contra=Math.abs(colora[0]-colorb[0])+Math.abs(colora[1]-colorb[1])+Math.abs(colora[2]-colorb[2]) ;
	return contra
}
function calcolaratio(colora,colorb) {
	Srgb[0][0]=colora[0]/255 ;
	Srgb[0][1]=colora[1]/255 ;
	Srgb[0][2]=colora[2]/255 ;
	Srgb[1][0]=colorb[0]/255 ;
	Srgb[1][1]=colorb[1]/255 ;
	Srgb[1][2]=colorb[2]/255 ;
	for (var i=0 ; i<2 ; i++) {
		for (var j=0 ; j<3; j++) {
			var x=Srgb[i][j] ;
			Normalized[i][j]=x <=0.03928 ?
					x /12.92 :
					Math.pow(((x+0.055)/1.055),2.4) ;
		}
		L[i]=0.2126*Normalized[i][0]+
			0.7152*Normalized[i][1]+
			0.0722*Normalized[i][2] ;
	}
	if (L[1] > L[0]) {
		var temp=L[0] ;
		L[0]=L[1] ;
		L[1]=temp ;
	}
	return (L[0]+0.05)/(L[1]+0.05) ;
}
function calcolalum(colora ,colorb)
{
	luma1=(299*colora[0]+587*colora[1]+114*colora[2])/1000
	luma2=(299*colorb[0]+587*colorb[1]+114*colorb[2])/1000
	delta=Math.round(Math.abs(luma1-luma2)) ;
	return delta ;
}

DEUTERANOPIA=0
PROTANOPIA=1
TRITANOPIA=2

rgb2lms=new Array(9)
rgb2lms[0] = 0.05059983;
rgb2lms[1] = 0.08585369;
rgb2lms[2] = 0.00952420;

rgb2lms[3] = 0.01893033;
rgb2lms[4] = 0.08925308;
rgb2lms[5] = 0.01370054;

rgb2lms[6] = 0.00292202;
rgb2lms[7] = 0.00975732;
rgb2lms[8] = 0.07145979;

gammaRGB= 2.1;

function ColorBlind(deficiency) {
	this.gammalut=new Array(256)
	for (i=0 ; i < 256 ; i++) {
		this.gammalut[i]=Math.pow(i,1.0/gammaRGB)
	}		
	this.deficiency=deficiency
	anchor=new Array(12)
	anchor_e=new Array(3)
        anchor[0] = 0.08008;  anchor[1]  = 0.1579;    anchor[2]  = 0.5897;
	anchor[3] = 0.1284;   anchor[4]  = 0.2237;    anchor[5]  = 0.3636;
	anchor[6] = 0.9856;   anchor[7]  = 0.7325;    anchor[8]  = 0.001079;
	anchor[9] = 0.0914;   anchor[10] = 0.007009;  anchor[11] = 0.0;
	this.anchor=anchor
	
	lms2rgb=new Array(9)


	lms2rgb[0] =  30.830854;
	lms2rgb[1] = -29.832659;
	lms2rgb[2] =   1.610474;

	lms2rgb[3] =  -6.481468;
	lms2rgb[4] =  17.715578;
	lms2rgb[5] =  -2.532642;

	lms2rgb[6] =  -0.375690;
	lms2rgb[7] =  -1.199062;
	lms2rgb[8] =  14.273846;

	this.rgb2lms=rgb2lms ;
	this.lms2rgb=lms2rgb ;
	this.gammaRGB=gammaRGB ;
	anchor_e[0]=rgb2lms[0] + rgb2lms[1] + rgb2lms[2];
	anchor_e[1] =rgb2lms[3] + rgb2lms[4] + rgb2lms[5];
        anchor_e[2] =rgb2lms[6] + rgb2lms[7] + rgb2lms[8];
	switch(deficiency) {
	case DEUTERANOPIA:
	   this.a1 = anchor_e[1] * anchor[8] - anchor_e[2] * anchor[7];
	   this.b1 = anchor_e[2] * anchor[6] - anchor_e[0] * anchor[8];
	   this.c1 = anchor_e[0] * anchor[7] - anchor_e[1] * anchor[6];
	   this.a2 = anchor_e[1] * anchor[2] - anchor_e[2] * anchor[1];
	   this.b2 = anchor_e[2] * anchor[0] - anchor_e[0] * anchor[2];
	   this.c2 = anchor_e[0] * anchor[1] - anchor_e[1] * anchor[0];
	   this.inflection = (anchor_e[2] / anchor_e[0]);
	   break ;
	case PROTANOPIA:
	   this.a1 = anchor_e[1] * anchor[8] - anchor_e[2] * anchor[7];
	   this.b1 = anchor_e[2] * anchor[6] - anchor_e[0] * anchor[8];
	   this.c1 = anchor_e[0] * anchor[7] - anchor_e[1] * anchor[6];
	   this.a2 = anchor_e[1] * anchor[2] - anchor_e[2] * anchor[1];
	   this.b2 = anchor_e[2] * anchor[0] - anchor_e[0] * anchor[2];
	   this.c2 = anchor_e[0] * anchor[1] - anchor_e[1] * anchor[0];
	   this.inflection = (anchor_e[2] / anchor_e[1]);
	   break ;
	case TRITANOPIA:
	   this.a1 = anchor_e[1] * anchor[11] - anchor_e[2] * anchor[10];
	   this.b1 = anchor_e[2] * anchor[9]  - anchor_e[0] * anchor[11];
	   this.c1 = anchor_e[0] * anchor[10] - anchor_e[1] * anchor[9];
	   this.a2 = anchor_e[1] * anchor[5]  - anchor_e[2] * anchor[4];
	   this.b2 = anchor_e[2] * anchor[3]  - anchor_e[0] * anchor[5];
	   this.c2 = anchor_e[0] * anchor[4]  - anchor_e[1] * anchor[3];
	   this.inflection = (anchor_e[1] / anchor_e[0]);
	   break;
	default :
	   alert("problems : see script") ;
	   break ;
	}
	this.converti = convedalto ;
	
}

function convedalto(red,green,blue) {

	switch (this.deficiency) {
	case DEUTERANOPIA :
            tmp = divisiosenzazero(blue,red);
            if (tmp < this.inflection)
	       green = -(this.a1 * red + this.c1 * blue) / this.b1;
            else
               green = -(this.a2 * red + this.c2 * blue) / this.b2;
            break;
	case PROTANOPIA :
            tmp = divisiosenzazero(blue,green);
            if (tmp < this.inflection)
              red = -(this.b1 * green + this.c1 * blue) / this.a1;
            else
              red = -(this.b2 * green + this.c2 * blue) / this.a2;
            break;
	case TRITANOPIA :
            tmp = divisiosenzazero(green,red);
            if (tmp < this.inflection)
              blue = -(this.a1 * red + this.b1 * green) / this.c1;
            else
              blue = -(this.a2 * red + this.b2 * green) / this.c2;
            break;
	default:
	 alert("problems : see script");
	 break
       } 
        redOld   = red;
        greenOld = green;
	
        red   = redOld * this.lms2rgb[0] + greenOld * this.lms2rgb[1] + blue * this.lms2rgb[2];	
        green = redOld * this.lms2rgb[3] + greenOld * this.lms2rgb[4] + blue * this.lms2rgb[5];
        blue  = redOld * this.lms2rgb[6] + greenOld * this.lms2rgb[7] + blue * this.lms2rgb[8];

	red=clampasotto(red,0)
	green=clampasotto(green,0)
	blue=clampasotto(blue,0) 
	    
        /* Apply gamma to go back to non-linear intensities */
        red   = lut_lookup(red,this.gammalut);
        green = lut_lookup(green, this.gammalut);
        blue  = lut_lookup(blue,  this.gammalut);
	return [red,green,blue] ; 
}
function lut_lookup(value,lut)
{
  offset = 127;
  step   = 64;

  while (step)
    {
      if (lut[offset] > value)
        {
          offset -= step;
        }
      else
        {
          if (lut[offset + 1] > value)
            return offset;

          offset += step;
        }

      step /= 2;
    }

  /*  the algorithm above can't reach 255  */
  if (offset == 254 && lut[255] < value)
    return 255;

  return offset;
}	

function check(s,red,green,blue) {
	if (debug) {
	  alert(s+red+" "+green+" "+blue);
	}
}
function clampasotto(f,start) {
	if (f < start) {
	  return start ;
	} else
	return f ;
}
function clampasottosopra(f,start,end) {
	if (f<start) {
	  return start ;
	}	
	else if (f>end) {
	  return end ;
	}
	else {
		return	 Math.round(f) ;
	}
}
	
function iniziadalto() {
	colorblindness=new Array(3)
	colorblindness[0]=new ColorBlind(DEUTERANOPIA)
	colorblindness[1]=new ColorBlind(PROTANOPIA)
	colorblindness[2]=new ColorBlind(TRITANOPIA)
	

}
	
function updatecolori() {
	red=colorirgb[0][color][0]
	green=colorirgb[0][color][1]
	blue=colorirgb[0][color][2]
	check("prima",red,green,blue)
	red   = colorblindness[0].gammalut[red];
        green = colorblindness[0].gammalut[green];
        blue  = colorblindness[0].gammalut[blue];
	redOld   = red;
        greenOld = green;
        red   = redOld * rgb2lms[0] + greenOld * rgb2lms[1] + blue * rgb2lms[2];
        green = redOld * rgb2lms[3] + greenOld * rgb2lms[4] + blue * rgb2lms[5];
        blue  = redOld * rgb2lms[6] + greenOld * rgb2lms[7] + blue * rgb2lms[8];
	colorirgb[1][color]=colorblindness[0].converti(red,green,blue)
	colorirgb[2][color]=colorblindness[1].converti(red,green,blue)
	colorirgb[3][color]=colorblindness[2].converti(red,green,blue)
}
	
function divisiosenzazero(num,deno) {
	if (num==0)
	  return 0.0
	else
	  return num/deno + 0.0
}



