
function trace(text) {
  var trace=document.getElementById('trace');
  var inner=trace.innerHTML.split('<br>');
  while(inner.length>20) inner.pop();
  trace.innerHTML=text+'<br>'+inner.join('<br>');
}

function d() {
  return Math.floor(Math.random()*2);
}


var index={};
for(var tile in tiles) {
  for(var c in tile.connect) {
    var edge=tile.connect[c];
    if(typeof index[edge] != 'array') index[edge]=[];
    index[edge].push(tile);
  }
}

var getTile=function(edges) {
  var choices=[];
  for(var i=0;i<tiles.length;i++) {
    var match=true;
    for(var j in edges) {
      if(!edges[j]) continue;
      if(tiles[i][j] != edges[j]) { match=false; break; }
    }
    if(match) choices.push(tiles[i]);
  }

  return choices.length ? choices[Math.floor(Math.random()*choices.length)] : null;

}


var w=30;
var h=30;

var ncols=21;
var nrows=21;

var firstrow=0;
var firstcol=0;

var rows=[];

var tilesNode=document.getElementById('tiles');  

var above=null;
var choice;

var offsetx=0;
var offsety=0;
var offsettx=0;
var offsetty=0;

for(var i=0;i<nrows;i++) {
  var cols=[];
  var left=null;
  for(var j=0;j<ncols;j++) {
    if(i>0) above=rows[i-1][j].tile;
    cols[j]={};
    cols[j].tile=left=getTile({top:(above?above.bottom:null),left:(left?left.right:null)});
    tilesNode.appendChild(ce('div',left.imageclass,{left:(w*(j+offsettx))+'px',top:(h*(i+offsetty))+'px'}));
    cols[j].node=tilesNode.lastChild;
  }
  rows[i]=cols;
}


var mouse=false;
var mouseX=0,mouseY=0;


var left;

function recenter() {
  while(-offsety>=(offsetty+1)*h) {
    offsetty++;
    var left=null;

    var lastrow=(firstrow+nrows-1)%nrows;

    for(var c=0;c<ncols;c++) {
      var j=(c+firstcol)%ncols;
      tilesNode.removeChild(rows[firstrow][j].node);
      rows[firstrow][j].tile=left=getTile({top:rows[lastrow][j].tile.bottom,left:left?left.right:null});
      tilesNode.appendChild(ce('div',left.imageclass,{left:w*(c+offsettx)+'px',top:h*(nrows+offsetty-1)+'px'}));
      rows[firstrow][j].node=tilesNode.lastChild;
    }
    firstrow=(firstrow+1)%nrows;
  }
  

  while(offsety>(-offsetty)*h) {
    offsetty--;
    var left=null;

    var lastrow=(firstrow+nrows-1)%nrows;

    for(var c=0;c<ncols;c++) {
      var j=(c+firstcol)%ncols;
      tilesNode.removeChild(rows[lastrow][j].node);
      rows[lastrow][j].tile=left=getTile({bottom:rows[firstrow][j].tile.top,left:left?left.right:null});
      tilesNode.appendChild(ce('div',left.imageclass,{left:w*(c+offsettx)+'px',top:h*(offsetty)+'px'}));
      rows[lastrow][j].node=tilesNode.lastChild;

    }
    firstrow=(firstrow+nrows-1)%nrows;
  }


  while(offsetx>(-offsettx)*w) {
    offsettx--;
    var top=null;

    var lastcol=(firstcol+ncols-1)%ncols;

    for(var c=0;c<nrows;c++) {
      var i=(c+firstrow)%ncols;
      tilesNode.removeChild(rows[i][lastcol].node);
      rows[i][lastcol].tile=top=getTile({right:rows[i][firstcol].tile.left,top:top?top.bottom:null});
      tilesNode.appendChild(ce('div',top.imageclass,{left:w*(offsettx)+'px',top:h*(c+offsetty)+'px'}));
      rows[i][lastcol].node=tilesNode.lastChild;

    }
    firstcol=(firstcol+ncols-1)%ncols;
  }

  while(-offsetx>(offsettx+1)*w) {
    offsettx++;
    var top=null;

    var lastcol=(firstcol+ncols-1)%ncols;

    for(var c=0;c<nrows;c++) {
      var i=(c+firstrow)%ncols;
      tilesNode.removeChild(rows[i][firstcol].node);
      rows[i][firstcol].tile=top=getTile({left:rows[i][lastcol].tile.right,top:top?top.bottom:null});
      tilesNode.appendChild(ce('div',top.imageclass,{left:w*(ncols+offsettx-1)+'px',top:h*(c+offsetty)+'px'}));
      rows[i][firstcol].node=tilesNode.lastChild;

    }
    firstcol=(firstcol+1)%ncols;
  }
  
  
  

  
  /*
  if(!recenterPending) {
    recenterPending=true;
    window.setTimeout(recenter,0);
  }
  else {
    alert('recentering');
    recenterPending=false;    
  }
  */
  

}


tilesNode.onmousedown=function() {
  mouse=true;
  //status.innerHTML+='down | ';
};
document.onmouseup=function() {
  mouse=false;
  //status.innerHTML+='up | ';
};

document.onmouseover=function(evt) {
  //status.innerHTML+="over | ";
  
};

document.onmousemove=function(evt) {
  if(!evt) evt = window.event;
  
  var dx=evt.clientX-mouseX;
  var dy=evt.clientY-mouseY;

  mouseX=evt.clientX;
  mouseY=evt.clientY;
  
  if(mouse) {
    offsetx+=dx;
    offsety+=dy;

    tilesNode.style.left=offsetx+'px';
    tilesNode.style.top=offsety+'px';    
    
    recenter();
  }
  return false;
};



var status=document.getElementById('status');
