
//
// crcvrb.js
// gestione gioco interattivo 'Cruciverba *'
//

// **********************************************
//                   DATI LOCALI
// **********************************************
var Orizzontali,        // definizioni orizzontali
    Verticali,          // definizioni verticali
    Direzione,          // direzione inserimento in schema 0:orizz, 1:vert
    Primacasella,       // indice prima casella utile di inserimento
    Precedente,         // indice precedente casella utilizzata
    Attuale,            // indice casella attualmente in uso
    SchemaGiocato = new Array(NumeroRighe*NumeroColonne),
                        // schema giocato da utente
Dim=20;

// **********************************************
// FUNZIONI COMUNI, ADATTATE AL SINGOLO GIOCO
// **********************************************
function reset_schema()
// imposta strutture dati per (ri)partire con medesimo schema di gioco
{
// CODICE COMUNE
  if (Risolto || SoluzioneVista || VediSoluzione || VediInfo)
    return;

// CODICE DIPENDENTE DAL SINGOLO GIOCO
  for (i=0;i<NumeroRighe*NumeroColonne;i++)
    SchemaGiocato[i]=Esposto.charAt(i)=='*'?'*':' ';
  // inizializzazione schema giocato da utente}

// CODICE COMUNE
  vedi_schema();
}

function nuovo_schema()
// calcola parametri schema scelto e lo visualizza
{
// CODICE DIPENDENTE DAL SINGOLO GIOCO
  calcolaindici();

  Orizzontali=(get_esposto(Schema))[0][1];
  Verticali=(get_esposto(Schema))[0][2];
}

function vedi_schema()
// visualizza schema scelto
{
// CODICE DIPENDENTE DAL SINGOLO GIOCO
  ss='<div class="centertxt" id="eitdef"></div>';
  // spazio definizione

  ss+='<table align="center" cellspacing="1" cellpadding="0"'+
      'bgcolor="#000000">';
  // inizio casella

  for (i=0;i<NumeroRighe;i++)   // per ogni riga schema
  {
    ss+='<tr>';                 // inizio riga
    for (j=0;j<NumeroColonne;j++)  // per ogni colonna schema
      ss+='<td bgcolor="#ffffff"><div class="cslntrn" '+
          'onClick="cliccata('+(i*NumeroColonne+j)+'); return false;" '+
          'id="'+eittag(i*NumeroColonne+j)+'"></div></td>';
    ss+='</tr>';                // chiusura riga
  }

  ss+='</table>';
  // chiusura tabella

  document.getElementById('eitsk').innerHTML=ss;
  // inserisce codice html intero schema

  Direzione=0;
  primacasella();
  Precedente=Primacasella;
  Attuale=Primacasella;

  for (i=0;i<NumeroRighe;i++)
    for (j=0;j<NumeroColonne;j++)
    {
      if (Esposto.charAt(i*NumeroColonne+j)=='*')
        document.getElementById(eittag(i*NumeroColonne+
         j)).style.backgroundColor='#000';
      else
      {
        document.getElementById(eittag(i*NumeroColonne+j)).innerHTML='';
        document.getElementById(eittag(i*NumeroColonne+
          j)).style.backgroundColor='#fff';
      }
    }

  zooma_font(0);

  cliccata(Primacasella);
}

function cliccata(c)
// cliccato su casella
{
// CODICE DIPENDENTE DAL SINGOLO GIOCO
  if (Esposto.charAt(c)=='*')
    return;
  // se clicca su casella nera, non fa niente

  evidenzia(Attuale,'#fff','#fff');
  // toglie evidenziatura a parola precedente

  // cliccata casella giocabile:
  if ( ( (Direzione==0) && (Indicioriz[c]==-1) )
     || ( (Direzione!=0) && (Indicivert[c]==-1) )
     )
    Direzione = (Direzione+1)%2;
  // cambia direzione, se deve

  Attuale=c;
  Precedente=Attuale;
  evidenzia(Attuale,'#ff0','#ccc');
  // evidenzia nuova parola

  document.getElementById('eitdef').innerHTML=
    Direzione==0?Orizzontali[Indicioriz[c]-1]:
    Verticali[Indicivert[c]-1];
}

function inkeys(e)
// gestore pressione tasti
{
// CODICE DIPENDENTE DAL SINGOLO GIOCO
  if (Risolto || SoluzioneVista || VediSoluzione || VediInfo)
    return;

  if (!e)
    e=window.event;

  if (e.keyCode==13)
  // invio = cambia direzione
  {
    if ( ( (Direzione==0) && (Indicivert[Attuale]!=-1) )
       || ( (Direzione!=0) && (Indicioriz[Attuale]!=-1) )
       )
    {
      evidenzia(Attuale,'#fff','#fff');
      Direzione = (Direzione+1)%2;
      // cambia direzione, se puo'
      evidenzia(Attuale,'#ff0','#ccc');
      document.getElementById('eitdef').innerHTML=
        Direzione==0?Orizzontali[Indicioriz[Attuale]-1]:
                     Verticali[Indicivert[Attuale]-1];
    }
    return false;
  }

  if (Risolto || VediSoluzione)
    return false;
  // non accetta altro input da tastiera se schema risolto o in visualizzazione
  // Accetta solo cambiamento direzione (invio) per permettere
  // all'utente di girellare per lo schema risolto

  x=Attuale%NumeroColonne;
  y=Math.floor(Attuale/NumeroColonne);
  // acquisisce coordinate casella attuale

  if (e.keyCode==27) // se escape (cancella carattere)
  {
    document.getElementById(eittag(Attuale)).innerHTML='';
    // cancella comunque carattere

    if (Direzione==0) // se direzione orizzontale
    {
      if (x>0)
      {
        if (Esposto.charAt(Attuale-1)!='*')
        // se puo' indietreggiare
        {
          Precedente=Attuale;
          SchemaGiocato[Attuale]='';
          Attuale--;
          evidenzia(Attuale,'#ff0','#ccc');
          // indietreggia ed evidenzia nuova casella
        }
      }
    }
    else              // altrimenti direzione verticale
    {
      if (y>0)
      {
        if (Esposto.charAt(Attuale-NumeroColonne)!='*')
        // se puo' indietreggiare
        {
          Precedente=Attuale;
          SchemaGiocato[Attuale]='';
          Attuale-=NumeroColonne;
          evidenzia(Attuale,'#ff0','#ccc');
          // indietreggia ed evidenzia nuova casella
        }
      }
    }
  }

  c=String.fromCharCode(e.keyCode);
  if (c<'A'||c>'Z')
    return;
  // non accetta input da tastiera diversi da invio, escape (gia' visti)
  // e caratteri alfabetici

  c=c.toUpperCase();

  document.getElementById(eittag(Attuale)).innerHTML=c;
  SchemaGiocato[Attuale]=c;
  // inserisce comunque carattere appena digitato

  if (Direzione==0) // se direzione orizzontale
  {
    if (x<(NumeroColonne-1))
    {
      if (Esposto.charAt(Attuale+1)!='*')
      // se puo' avanzare
      {
        Precedente=Attuale;
        Attuale++;
        evidenzia(Attuale,'#ff0','#ccc');
        // avanza ed evidenzia nuova casella
      }
    }
  }
  else              // altrimenti direzione verticale
  {
    if (y<(NumeroRighe-1))
    {
      if (Esposto.charAt(Attuale+NumeroColonne)!='*')
      // se puo' avanzare
      {
        Precedente=Attuale;
        Attuale+=NumeroColonne;
        evidenzia(Attuale,'#ff0','#ccc');
        // avanza ed evidenzia nuova casella
      }
    }
  }

  controlla();
  // richiama controllo soluzione parziale costruita da utente
}

function controlla()
// controlla soluzione parziale costruita da utente
{
// CODICE DIPENDENTE DAL SINGOLO GIOCO
  diverso=false;
  i=0;
  while (!diverso && (i<(NumeroRighe*NumeroColonne)))
    if (Esposto.charAt(i).toLowerCase()!=
          SchemaGiocato[i].toLowerCase())
      diverso=true;
    else
      i++;

  if (i==NumeroRighe*NumeroColonne)
  // se caratteri corrispondono tutti
  {
    Risolto=true;
    stopTimer();
    // gioco risolto
    vediApplauso();
    // richiama animazione sfinge Kidi che applaude
    // confirm("Ottimo!");
  }
}

function soluzione()
// visualizza soluzione
{
  if (VediInfo)
    return;

  SoluzioneVista=true;
  VediSoluzione=!VediSoluzione;

// CODICE DIPENDENTE DAL SINGOLO GIOCO
  for (i=0;i<NumeroRighe;i++)
    for (j=0;j<NumeroColonne;j++)
    {
      if (VediSoluzione)
        c=Esposto.charAt(i*NumeroColonne+j).toUpperCase();
      else
        c=SchemaGiocato[i*NumeroColonne+j];
      if (Esposto.charAt(i*NumeroColonne+j)!='*')
        document.getElementById(eittag(i*NumeroColonne+j)).innerHTML=c;
    }

  stopTimer();
}

// -------------------------------
// INIZIO CODICE LOCALE AGGIUNTIVO
// -------------------------------
// CODICE DIPENDENTE DAL SINGOLO GIOCO

var Indicioriz = new Array(NumeroRighe*NumeroColonne),
    Indicivert = new Array(NumeroRighe*NumeroColonne);

document.onkeydown=inkeys;
// aggancia gestore pressione tasti alla pagina

function colora(d,s)
// colora d
{
  document.getElementById(eittag(d)).style.backgroundColor=s;
}

function evidenzia(d,c1,c2)
// evidenzia d
{
  i=d;

  x=i%NumeroColonne;
  y=Math.floor(i/NumeroColonne);

  if (Direzione==0)
  {
    while (x>=0 && Esposto.charAt(y*NumeroColonne+x)!='*')
      x--;
    x++;
  }
  else
    {
      while (y>=0 && Esposto.charAt(y*NumeroColonne+x)!='*')
        y--;
        y++;
    }

  while (x<NumeroColonne && y<NumeroRighe &&
         Esposto.charAt(y*NumeroColonne+x)!='*')
  {
    if ((y*NumeroColonne+x)==d)
      colora(y*NumeroColonne+x,c1);
    else
      colora(y*NumeroColonne+x,c2);

    if (Direzione==0)
      x++;
    else
      y++;
  }
}

function calcolaindici()
// associa ad ogni casella indici definizioni e visualizza
{
  for (i=0;i<NumeroRighe*NumeroColonne;i++)
  {
    Indicioriz[i] = -1;
    Indicivert[i] = -1;
  }
  // inizializzazione matrici indici

  ind = 0;
  // inizializzazione indice definizioni orizzontali

  for (i=0;i<NumeroRighe;i++)
    for (j=0;j<NumeroColonne;)
      if ( (Esposto.charAt(i*NumeroColonne+j)=='*') ||
           (j==(NumeroColonne-1))    ||
           ( (j<(NumeroColonne-1))&&
              (Esposto.charAt(i*NumeroColonne+j)!='*'
              && Esposto.charAt(i*NumeroColonne+j+1)=='*') )
         )
        j++;
      else
      {
        ind++;
        while ( (Esposto.charAt(i*NumeroColonne+j)!='*') &&
                (j<NumeroColonne) )
        {
          Indicioriz[i*NumeroColonne+j]=ind;
          j++;
          if (j>=NumeroColonne)
            break;
        }
      }

  ind = 0;
  // inizializzazione indice definizioni verticali

  for (i=0;i<NumeroRighe;i++)
    for (j=0;j<NumeroColonne;j++)
      if (Indicivert[i*NumeroColonne+j]==-1)
        if (Esposto.charAt(i*NumeroColonne+j)=='*' || 
            (Esposto.charAt(i*NumeroColonne+j)!='*' && 
             ((i==(NumeroRighe-1)) || (i<(NumeroRighe-1) &&
             Esposto.charAt((i+1)*NumeroColonne+j)=='*'))
            )
           )
          Indicivert[i*NumeroColonne+j]=-1;
        else
        {
          k=i;
          ind++;
          while (Esposto.charAt(k*NumeroColonne+j)!='*' &&
                 (k<NumeroRighe))
          {
            Indicivert[k*NumeroColonne+j]=ind;
            k++;
            if (k>=NumeroRighe)
              break;
          }
        }
}

function primacasella()
// individua prima casella utile
{
  y=0;
  trovato=0;
  while (y<NumeroRighe && trovato==0)
  {
    x=0;
    while (x<NumeroColonne && trovato==0)
    {
      if (Indicioriz[y*NumeroColonne+x]!=-1
          && Indicivert[y*NumeroColonne+x]!=-1)
      {
        Primacasella=y*NumeroColonne+x;
        trovato=1;
      }
      else
        x++;
    }
  }

  if (trovato==0)
  {
    alert('Schema non valido!');
    // segnala schema incongruente
    Risolto=true;
    // e poi blocca interazione con utente
  }
}