function Barra(barra_dati)
{
   /*Private:*/

   /*Lavagna su cui Renderizzare la Barra e sue proprieta'. Si tratta di un contenitore Canvas*/
   /*Formato [obj_canvas,lunghezza,altezza,valore_max,valore]*/
   this.lavagna = barra_dati[0].getContext('2d');
   this.width = barra_dati[1];
   this.height = barra_dati[2];
   this.valore_max = barra_dati[3];
   this.valore = barra_dati[4];

   /*Contiene lo Stato Attuale della Barra*/
   /*Serve a gestire la Sincronizzazione delle varie operazioni richieste da eseguire*/
   this.StatoBarra = null;

   /*Contiene il riferimento ad un Oggetto Cubo di Rubik*/
   this.cubo = null;

   /*Contiene il riferimento alla Funzione che Implementa il Full Screen*/
   this.avvia_fullscreen = null;

   /*Contiene il riferimento ad un Oggetto Paragrafo su cui Renderizzare il Contatore delle Mosse*/
   this.box_contatore = null;

   /*Public:*/

   /*Metodo di Inizializzazione*/
   this.init = InitBarra;

   /*Metodo per Settare il Valore Attuale della Barra*/
   this.Setta_Valore = Set_Valore;

   /*Metodo per Settare il Valore Massimo che puo' assumere la Barra*/
   this.Setta_Valore_Max = Set_Valore_Max;

   /*Metodo per Settare la Larghezza della Barra*/
   this.Setta_Width = Set_Width;

   /*Metodo per Settare l'Altezza della Barra*/
   this.Setta_Height = Set_Height;

   /*Metodo di Interfaccia al Mouse*/
   /*Devono essere passate le coordinate X,Y dell'evento*/
   this.mouse_down = Barra_Mouse_DOWN;

   /*Metodo per Assegnare una Funzione che Implementi il Full Screen*/
   /*Deve essere passata una funzione che ha il compito di gestire il Full Screen del Cubo di Rubik e della Barra stessa*/
   this.assegna_fullscreen = Barra_Assegna_FullScreen;

   /*Metodo per Assegnare un Oggetto Paragrafo su cui Renderizzare il Contatore delle Mosse*/
   /*Deve essere passato un riferimento dell'Oggetto Paragrafo*/
   this.assegna_contatore = Barra_Assegna_Contatore;

   /*Metodo per la Renderizzazione*/
   this.draw = Disegna_Barra;
}

function InitBarra()
{
   /*Contiene lo Stato Attuale della Barra*/
   /*Serve a gestire la Sincronizzazione delle varie operazioni richieste da eseguire*/
   this.StatoBarra = "Libera";

   if(this.valore_max < 0) this.valore_max = 0;
}

function Set_Width(val_width)
{
   this.width = val_width;
}

function Set_Height(val_height)
{
   this.height = val_height;
}

function Set_Valore(valore)
{
   if(this.StatoBarra == "Occupata") return false;

   if(valore < 0) valore = 0;
   if(valore > this.valore_max) valore = this.valore_max;

   this.valore = Math.floor(valore);
}

function Set_Valore_Max(valore)
{
   if(this.StatoBarra == "Occupata") return false;

   if(valore < 0) valore = 0;

   this.valore_max = Math.floor(valore);
}

function Barra_Assegna_FullScreen(funzione)
{
   this.avvia_fullscreen = funzione;
}

function Barra_Assegna_Contatore(objParagrafo)
{
   this.box_contatore = objParagrafo;
}

function Barra_Mouse_DOWN(posX,posY)
{
   if(posX > this.width || posY > this.height || posX < 0 || posY < 0) return false;

   var valore;

   if(posX > this.width*16/100 && posX < this.width*69/100 && posY > this.height*30/100 && posY < this.height*70/100  && this.cubo.coda_tipo == "Risoluzione")
   {
      /*Zona di Avanzamento*/
      if(this.cubo.StatoAnimazioneCoda == "Stop") return false;

      valore = Math.floor(this.valore_max*(posX-this.width*16/100)/(this.width*53/100));
      this.Setta_Valore(valore);

      this.StatoBarra = "Occupata";

      if(this.cubo.StatoAnimazioneCoda == "Fermo")
      {
         this.cubo.coda_setta_mossa_attuale(valore);
         this.draw();
         this.cubo.rigenera_sottocubi();
         this.cubo.draw();
         this.StatoBarra = "Libera";
      }
   }

   if(posX > this.width*10/100 && posX < this.width*15/100 && this.cubo.coda_tipo == "Risoluzione")
   {
      switch(this.cubo.StatoAnimazioneCoda)
      {
         case "Fermo": if(this.cubo.StatoCubo == "Libero")
                       {
                          this.cubo.StatoAnimazioneCoda = "Play";
                          this.draw();
                          this.cubo.esegui_coda_mosse();
                       }
                       break;
         case "Play": this.cubo.StatoAnimazioneCoda = "Fermo";
                      this.draw();
      }
   }

   if(posX > 0 && posX < this.width*5/100 && this.cubo.coda_tipo == "Risoluzione")
   {
      if(this.cubo.StatoAnimazioneCoda == "Fermo" && this.cubo.StatoCubo == "Libero")
      {
         if(this.valore-1 < 0) return false;

         this.Setta_Valore(this.valore-1);
         this.draw();

         this.cubo.coda_mossa_attuale--;

         var vettAsse = [0,0,0];
         vettAsse[this.cubo.coda_mosse[this.valore][0]] = 1;

         this.cubo.SetNormale_SetBlocchi(vettAsse);
         this.cubo.Set_Blocco(this.cubo.coda_mosse[this.valore][1]);
         switch(this.cubo.coda_mosse[this.valore][2])
         {
            case 0: this.cubo.ruota_blocco_down(); break;
            case 1: this.cubo.ruota_blocco_up(); break;
            case 2: this.cubo.ruota_blocco_double();
         }
      }
   }

   if(posX > this.width*5/100 && posX < this.width*10/100 && this.cubo.coda_tipo == "Risoluzione")
   {
      if(this.cubo.StatoAnimazioneCoda == "Fermo" && this.cubo.StatoCubo == "Libero")
      {
         if(this.valore+1 > this.valore_max) return false;

         this.Setta_Valore(this.valore+1);
         this.draw();

         this.cubo.coda_mossa_attuale++;

         var vettAsse = [0,0,0];
         vettAsse[this.cubo.coda_mosse[this.valore-1][0]] = 1;

         this.cubo.SetNormale_SetBlocchi(vettAsse);
         this.cubo.Set_Blocco(this.cubo.coda_mosse[this.valore-1][1]);

         switch(this.cubo.coda_mosse[this.valore-1][2])
         {
            case 0: this.cubo.ruota_blocco_up(); break;
            case 1: this.cubo.ruota_blocco_down(); break;
            case 2: this.cubo.ruota_blocco_double();
         }
      }
   }

   if(posX > this.width*95/100 && posX < this.width*100/100)
   {
      if(this.avvia_fullscreen != null) this.avvia_fullscreen();
   }
}

function Disegna_Barra()
{
   var avanzamento = (this.valore_max == 0)?0:(this.valore/this.valore_max);

   /*Disegno Sfondo Barra*/
   this.lavagna.fillStyle = "#6495ED";
   this.lavagna.fillRect(0, 0, this.width, this.height);

   /*Disegno Pulsante Indietro*/
   this.lavagna.fillStyle = "#FFFFFF";
   this.lavagna.beginPath();
   this.lavagna.moveTo(this.width*3.5/100,this.height*20/100);
   this.lavagna.lineTo(this.width*2.6/100,this.height*50/100);
   this.lavagna.lineTo(this.width*3.5/100,this.height*80/100);
   this.lavagna.fill();
   this.lavagna.beginPath();
   this.lavagna.moveTo(this.width*2.4/100,this.height*20/100);
   this.lavagna.lineTo(this.width*1.5/100,this.height*50/100);
   this.lavagna.lineTo(this.width*2.4/100,this.height*80/100);
   this.lavagna.fill();

   /*Disegno Pulsante Avanti*/
   this.lavagna.fillStyle = "#FFFFFF";
   this.lavagna.beginPath();
   this.lavagna.moveTo(this.width*6.5/100,this.height*20/100);
   this.lavagna.lineTo(this.width*7.4/100,this.height*50/100);
   this.lavagna.lineTo(this.width*6.5/100,this.height*80/100);
   this.lavagna.fill();
   this.lavagna.beginPath();
   this.lavagna.moveTo(this.width*7.6/100,this.height*20/100);
   this.lavagna.lineTo(this.width*8.5/100,this.height*50/100);
   this.lavagna.lineTo(this.width*7.6/100,this.height*80/100);
   this.lavagna.fill();

   if((this.cubo.StatoAnimazioneCoda != "Play" && this.cubo.coda_tipo == null) || (this.cubo.StatoAnimazioneCoda == "Fermo" && this.cubo.coda_tipo == "Risoluzione") || this.cubo.coda_tipo == "Mescolamento")
   {
      /*Disegno Pulsante Play*/
      this.lavagna.fillStyle = "#FFFFFF";
      this.lavagna.beginPath();
      this.lavagna.moveTo(this.width*11.5/100,this.height*20/100);
      this.lavagna.lineTo(this.width*13.5/100,this.height*50/100);
      this.lavagna.lineTo(this.width*11.5/100,this.height*80/100);
      this.lavagna.fill();
   }
   else
   {
      /*Disegno Pulsante Fermo*/
      this.lavagna.fillStyle = "#FFFFFF";
      this.lavagna.fillRect(this.width*11.4/100,this.height*20/100,this.width*0.8/100,this.height*60/100);
      this.lavagna.fillRect(this.width*12.7/100,this.height*20/100,this.width*0.8/100,this.height*60/100);
   }

   /*Disegno Avanzamento*/
   this.lavagna.fillStyle = "#0099DD";
   this.lavagna.fillRect(this.width*16/100, this.height*30/100, this.width*53/100, this.height*40/100);

   /*Disegno Avanzamento Attuale*/
   this.lavagna.fillStyle = "#0000DD";
   this.lavagna.fillRect(this.width*16/100, this.height*30/100, this.width*53/100*avanzamento, this.height*40/100);

   /*Disegno Bordino Avanzamento*/
   this.lavagna.strokeStyle = "#000000";
   this.lavagna.strokeRect(this.width*16/100, this.height*30/100, this.width*53/100, this.height*40/100);

   /*Disegno Contatore*/
   this.lavagna.fillStyle = "#6495ED";
   this.lavagna.fillRect(this.width*70/100, 0, this.width*25/100, this.height);

   /*Disegno Pulsante FullScreen*/
   this.lavagna.fillStyle = "#FFFFFF";
   this.lavagna.fillRect(this.width*96/100, this.height*20/100, this.width*3/100, this.height*60/100);
   this.lavagna.fillStyle = "#000000";
   this.lavagna.fillRect(this.width*96.1/100, this.height*22/100, this.width*1.8/100, this.height*30/100);

   /*Disegno Bordino Barra*/
   this.lavagna.strokeStyle = "#000000";
   this.lavagna.strokeRect(0, 0, this.width, this.height);

   /*Scrivo il "valore_attuale/valore_massimo" nell'Oggetto Paragrafo che viene utilizzato come Contatore di Mosse*/
   if(this.box_contatore != null)
   {
      if(this.box_contatore.hasChildNodes()) this.box_contatore.removeChild(this.box_contatore.firstChild)

      var testo = document.createTextNode(this.valore + "/" + this.valore_max);
      this.box_contatore.appendChild(testo);
   }

   /*Disegno Linee di Separazione tra Pulsanti*/
   this.lavagna.fillStyle = "#000000";
   this.lavagna.fillRect(this.width*5/100, 0, 1, this.height);
   this.lavagna.fillRect(this.width*10/100, 0, 1, this.height);
   this.lavagna.fillRect(this.width*15/100, 0, 1, this.height);
   this.lavagna.fillRect(this.width*70/100, 0, 1, this.height);
   this.lavagna.fillRect(this.width*95/100, 0, 1, this.height);
}