// ===============================================================================================================================
// Gembusters Version 060419-1715 by uja
// --------------------------------------
// Ziel: Steine zertrümmern mit Kugeln, Gewichten, Bomben
// Zeit pro Level: 90 min
// Nachwuchs von unten: alle 5  Sekunden
// getestete Features:  19.4.2006:
// farbige Kugeln:	lassen gleichfarbige Kette zerplatzen
// Gewicht:		zerstört Spalte, endet bei Monsterstein und intakter Mauer
// Bombe:		killt Nachbarsteine, auch disgonal, Monstersteine und gelbe Mauern bleiben unberührt, rosa zerknacken
// Joker:		Feldstein, wie der Name schon sagt...
// Mauer:		Feldstein, nicht zu entfernen
// Mauer0:		kann durch Bomben spröde werden
// Mauer1:		spröde, zerplatzt mit Bombe, Gewicht
// mit diesen Features geht es bis zum 10.Level
// --------------------------------------------------------------------------------------------------------------------------------

xmax=8; ymax=12; zmax=xmax*ymax; dx=32; dy=32; zeit0=90,timetic=50;

var timrec1,timrec2,aktiv,level,spalte=0,stein=0,dropptr,zeit,i,j,k,is_over;


var bild=new Array('rosa','rot','gelb','gruen','cyan','blau');
numcolors=bild.length;

var ima=new Array(); 
ima[0]=new Image(); ima[0].src='leer.gif';
k=1;
for (i=0; i<numcolors; i++) { ima[k]=new Image(); ima[k].src='s_'+bild[i]+'.gif'; k++; }
for (i=0; i<numcolors; i++) { ima[k]=new Image(); ima[k].src='k_'+bild[i]+'.gif'; k++; }
for (i=0; i<numcolors; i++) { ima[k]=new Image(); ima[k].src='s0_'+bild[i]+'.gif'; k++; }
for (i=0; i<numcolors; i++) { ima[k]=new Image(); ima[k].src='s1_'+bild[i]+'.gif'; k++; }
for (i=0; i<numcolors; i++) { ima[k]=new Image(); ima[k].src='s2_'+bild[i]+'.gif'; k++; }
for (i=0; i<numcolors; i++) { ima[k]=new Image(); ima[k].src='s3_'+bild[i]+'.gif'; k++; }

kstart=numcolors+1;
mstart=kstart+numcolors;
mauer=k; mauer0=mauer+1; mauer1=mauer0+1; joker=mauer1+1; // Feldsteine
gewicht=joker+1; bombe=gewicht+1    // Dropsteine

ima[mauer]=new Image();   ima[mauer].src='mauer.gif';     // unkaputtbar
ima[mauer0]=new Image();  ima[mauer0].src='mauer0.gif';    // kaputtbar, nach Bombentreffer->mauer1
ima[mauer1]=new Image();  ima[mauer1].src='mauer1.gif';   // zerplatzt mit Bombe, Gewicht
ima[joker]=new Image();   ima[joker].src='s_weiss.gif';
ima[gewicht]=new Image(); ima[gewicht].src='gewicht.gif';
ima[bombe]=new Image();   ima[bombe].src='bombe.gif';

var f=new Array();
var liste=new Array();
var dropliste=new Array();
var schubliste=new Array();

function spielfeld()
{ var i,j,k=0,t='<table class="spielfeld" cellspacing=0 cellpadding=0><tr>';
  for (i=0; i<xmax; i++) 
  { t=t+'<td class="oben'+i%2+'"><a href="javascript:klick('+i+')" onmouseover="hover_in('+i+')" onmouseout="hover_out('+i+')">';
    t=t+'<img src="leer.gif" width='+dx+' height='+dy+' alt="" name="o_'+i+'" border=0><\/a><\/td>';
  }
  t=t+'<\/tr><\/table><table class="spielfeld" cellspacing=0 cellpadding=0>';
  for (j=0; j<ymax; j++)
  { t=t+'<tr>';
    for (i=0; i<xmax; i++)
    { t=t+'<td style="background-image:url(halbton'+i%2+'.gif)">';
      t=t+'<a href="javascript:klick('+i+')" onmouseover="hover_in('+i+')">';
      t=t+'<img src="leer.gif" width='+dx+' height='+dy+' alt="" name="i_'+k+'" border=0><\/a><\/td>';
      k++;
    }
    t=t+'<\/tr>';
  }
  t=t+'<\/table>';
  return t;
}

function neu(nr)
{ var i,j,k,x,y;
  aktiv=false;
  is_over=false;
  if (timrec1) clearTimeout(timrec1);
  if (timrec2) clearTimeout(timrec2);
  level=nr;
  if (mach_level(level))
  { if (spalte>=0) hover_out();
    document.form1.level.value=level;
    document.form1.punkte.value=punkte;
    document.form1.zeit.value=zeit;
    schub(); dropptr=1; neuer_stein();
    pausiert=true;
    toggle_pause();
  }
  else gameover(1);
}

function neuer_stein()  
{ stein=dropliste[dropptr]; dropptr++; if (dropptr>dropliste[0]) dropptr=1;
  convert(); aktiv=true; hover_in(spalte); 
}

function messi(t)       { document.form1.messi.value=t; }
function zeige_feld(nr) { document.images['i_'+nr].src=ima[f[nr]].src; }
function hover_in(nr)   { if (aktiv) { hover_out(); document.images['o_'+nr].src=ima[stein].src; spalte=nr; } else hover_out(); }
function hover_out()    { document.images['o_'+spalte].src=ima[0].src; }
function levelup()      { alert('Level '+level+' geschafft!'); neu(level+1); }


function klick(nr)
{ if (aktiv) if (f[nr]==0)
  { aktiv=false;
    hover_out(nr);
    document.images['i_'+nr].src=ima[stein].src;
    timrec2=setTimeout('droppen('+nr+')',timetic);
  }
}

function droppen(nr)
{ var k=nr+xmax;
  if ((k<zmax) && (f[k]==0))
  { document.images['i_'+nr].src=ima[0].src;
    document.images['i_'+k].src=ima[stein].src;
    timrec2=setTimeout('droppen('+k+')',timetic);
  }
  else // bei den ersten Zweigen aktiv schalten erst nach Ablauf der Animation
  { if (stein==bombe) { zeige_feld(nr); bomba1(nr); }
    else if (stein==gewicht) { zeige_feld(nr); kill_spalte(nr%xmax); }
    else if (stein>=kstart)
    { f[nr]=stein-kstart+1;
      get_kette(nr);
      if (liste[0]>1) punkten(); else { zeige_feld(nr); neuer_stein(); }
    }
    else { f[nr]=stein; zeige_feld(nr); neuer_stein(); }
  }
}

// ==================================================================================================
// Fill-Algo rechtwinkliges System, einfaches Kreuz - braucht _listen.js, arbeitet auf liste()
// liste ist global, dadurch wird das Ganze erheblich schneller
// --------------------------------------------------------------------------------------------------
function get_kette(nr)
{ var i,p0,p1=0; 
  liste[0]=1; liste[1]=nr;
  while (p1<liste[0]) { p0=p1+1; p1=liste[0]; for (i=p0; i<=p1; i++) check_nachbarn(liste[i]); }
}

function check_nachbarn(nr) // N,O,S,W
{ var k;
  if (nr%xmax>0)      { k=nr-1;    if (f[k]>0) if (passt(k)) add_liste(k,liste); }
  if (nr%xmax<xmax-1) { k=nr+1;    if (f[k]>0) if (passt(k)) add_liste(k,liste); }
  if (nr>=xmax)       { k=nr-xmax; if (f[k]>0) if (passt(k)) add_liste(k,liste); }
  if (nr<zmax-xmax)   { k=nr+xmax; if (f[k]>0) if (passt(k)) add_liste(k,liste); }
}

function passt(nr)
{ var flag,farbe0=f[liste[1]],farbe1=f[nr];
  if (farbe1==mauer) flag=false;
  else if (farbe1==mauer0) flag=false;
  else if (farbe1==mauer1) flag=false;
  else if (farbe1==joker) flag=true;
  else if (farbe0-1==(farbe1-1)%numcolors) flag=true;
  else flag=false;
  return flag;
}

// =====================================================================================================================
// bildet aus 4 kleinen Steinen einen Monsterstein - dabei finden keine Umordnungen statt - Einmal Moster, immer Monster
// ----------------------------------------------------------------------------------------------------------------------
function convert()
{ var i,j,k;
  for (j=0; j<ymax-1; j++) for (i=0; i<xmax-1; i++) 
  { k=i+j*xmax;
    if ((f[k]>0) && (f[k]<=numcolors)) if ((f[k+1]==f[k]) && (f[k+xmax]==f[k]) && (f[k+xmax+1]==f[k]))
    { f[k]=f[k]+2*numcolors; f[k+1]=f[k]+numcolors; f[k+xmax]=f[k]+2*numcolors; f[k+xmax+1]=f[k]+3*numcolors;
      document.images['i_'+k].src=ima[f[k]].src; 
      document.images['i_'+(k+1)].src=ima[f[k+1]].src; 
      document.images['i_'+(k+xmax)].src=ima[f[k+xmax]].src; 
      document.images['i_'+(k+xmax+1)].src=ima[f[k+xmax+1]].src; 
    }
  }
}

// ===================================================================================================
// killt einfache Steine und Joker, stoppt bei intakter Mauer und Monstersteinen
// ---------------------------------------------------------------------------------------------------
function kill_spalte(nr)
{ var i,k;
  liste[0]=0; i=0; 
  while (i<ymax) 
  { k=nr+i*xmax; 
    if (f[k]>0) { if ((f[k]<=numcolors) || (f[k]==joker) || (f[k]==mauer1)) add_liste(k,liste); else i=ymax; }
    i++; 
  }
  timrec2=setTimeout('loeschen()',timetic);
}

// ===================================================================================================
// killt einfache Nachbarsteine, auch diagonale,  und Joker sowie kaputte Steine, knackt rosa Gestein
// ---------------------------------------------------------------------------------------------------
function bomba1(nr)
{ var i,j,k,x0=nr%xmax-1,y0=Math.floor(nr/xmax)-1,x1=x0+2,y1=y0+2;
  if (x0<0) x0=0; else if (x1>xmax-1) x1=xmax-1;
  if (y0<0) y0=0; else if (y1>ymax-1) y1=ymax-1;
  liste[0]=0;
  for (j=y0; j<=y1; j++) for (i=x0; i<=x1; i++)
  { k=i+j*xmax;
    if (f[k]>0)
    { if ((f[k]<=numcolors) || (f[k]==joker) || (f[k]==mauer1)) add_liste(k,liste);
      else if (f[k]==mauer0) { f[k]=mauer1; zeige_feld(k); }
    }
  }
  timrec2=setTimeout('loeschen()',timetic);
}

// ===================================================================================================

function punkten()
{ var i,j,k,sum=0;
  for (i=1; i<=liste[0]; i++) sum=sum+i;                                                              // Bonus für lange Ketten
  for (i=1; i<=liste[0]; i++) if ((f[liste[i]]>=mstart) && (f[liste[i]]<mstart+numcolors)) sum=sum+100; // Bonus Monsterstein
  punkte=punkte+sum;
  document.form1.punkte.value=punkte;
  timrec2=setTimeout('loeschen()',timetic);
}

function loeschen()
{ var i,k;
  for (i=1; i<=liste[0]; i++) { k=liste[i]; f[k]=0; zeige_feld(k); }
  timrec2=setTimeout('absturz()',timetic);
}

function absturz()
{ var i,j,k,gedroppt=false;
  for (i=0; i<zmax-xmax; i++) if (f[i]>0)
  { if ((f[i]<=numcolors) && (f[i+xmax]==0)) { f[i+xmax]=f[i]; f[i]=0; zeige_feld(i); zeige_feld(i+xmax); gedroppt=true; }
    else if ((f[i]>2*numcolors) && (f[i]<=3*numcolors)) // Monstersteine Start
    { if ((f[i+2*xmax]==0) && (f[i+2*xmax+1]==0))
      { f[i+2*xmax]=f[i+xmax]; f[i+xmax]=f[i]; f[i]=0;
        f[i+2*xmax+1]=f[i+xmax+1]; f[i+xmax+1]=f[i+1]; f[i+1]=0;
        zeige_feld(i); zeige_feld(i+1); zeige_feld(i+xmax); zeige_feld(i+xmax+1); zeige_feld(i+2*xmax); zeige_feld(i+2*xmax+1);
        gedroppt=true;
      }
    }
    else if ((f[i]>=mauer) && (f[i+xmax]==0)) { f[i+xmax]=f[i]; f[i]=0; zeige_feld(i); zeige_feld(i+xmax); gedroppt=true; }
  }
  if (gedroppt) timrec2=setTimeout('absturz()',timetic); else neuer_stein();
}

// ===============================================================================================================================

function schub()
{ var i,over=false;
  var v=new Array();
  if (aktiv)
  { if (zeit%5<1)
    { for (i=0; i<xmax; i++)
      { v[i]=schubliste[Math.floor(schubliste[0]*Math.random())%schubliste[0]+1];
        if (f[i]>0) over=true;
      }
      for (i=0; i<zmax-xmax; i++) f[i]=f[i+xmax];
      for (i=0; i<xmax; i++) f[zmax-i-1]=v[i];
      convert();
      for (i=0; i<zmax; i++) zeige_feld(i);
    }
    zeit--;
    document.form1.zeit.value=zeit;
    if (zeit<1) levelup(); else if (over) gameover(0); else timrec1=setTimeout('schub()',1000);
  }
  else timrec1=setTimeout('schub()',50);  // Programm "busy", Überschneidungen vermeidem
}

function gameover(nr)
{ aktiv=false;
  is_over=true;
  if (timrec1) clearTimeout(timrec1);
  if (timrec2) clearTimeout(timrec2);
  switch (nr)
  { case 1: alert('Mehr Levels hamma nich!\nGammelover!'); break;
    default: alert("Die Steine sind oben angestoßen!\nGammelover!");
  }
  eintrag('form1');
}

// ===================================================================0
var pausiert=false;
function toggle_pause()
{ var i;
  if (!is_over)
  {
  if (pausiert)
  { document.getElementById('pause').firstChild.nodeValue='Pause'; 
    for (i=0; i<zmax; i++) zeige_feld(i);
    pausiert=false;
    aktiv=true;
  }
  else
  { document.getElementById('pause').firstChild.nodeValue='weiter'; 
    for (i=0; i<zmax; i++) document.images['i_'+i].src=ima[0].src;
    pausiert=true;
    aktiv=false;
  }
  }
}


