/* canvas.js
 * copyright 2009 Dan Royer (dan@marginallyclever.com)
 * 2009-06-30 - created
 * 2009-07-02 - added fillCircle
 */
//---------------------------------------------------------------------------
function fatalerror(msg) {
  alert(msg);
  stopSystem();
}

//---------------------------------------------------------------------------
// INPUT
//---------------------------------------------------------------------------
//@TODO: change these to {x:0,y:0} ?
var canvas_top=0;
var canvas_left=0;
var mouse_old_X=0;
var mouse_old_Y=0;
var mouse_X=0;
var mouse_Y=0;
var mouse_button=0;
var mouse_state=0;
var keyboard_keys=Array(256);
var keyboard_states=Array(256);
var keyboard_names=Array(256);
var KEY_UP=0;
var KEY_DROP=1;
var KEY_DOWN=2;
var KEY_RISE=3;


//---------------------------------------------------------------------------
// found this online, url lost.  mad props to whoever did it, though.
function findOffset(obj) {
	canvas_top=0;
  canvas_left=0;

  if (obj.offsetParent) {
    do {
			canvas_left += obj.offsetLeft;
			canvas_top += obj.offsetTop;
    } while (obj = obj.offsetParent);
  }
}

  
//---------------------------------------------------------------------------
function startInput() {
  if (document.addEventListener) {  // DOM Level 2 Event Model
    document.addEventListener("mousemove", getMouseMove, true);
    document.addEventListener("mousedown", getMouseDown, true);
    document.addEventListener("mouseup", getMouseUp, true);
    document.addEventListener("keydown", getKeyboardDown, true);
    document.addEventListener("keyup", getKeyboardUp, true);
  } else if(document.attachEvent) {  // IE 5+ Event Model
    document.attachEvent("onmousemove", getMouseMove);
    document.attachEvent("onmousedown", getMouseDown);
    document.attachEvent("onmouseup", getMouseUp);
    document.attachEvent("onkeydown", getKeyboardDown);
    document.attachEvent("onkeyup", getKeyboardUp);
  } else {
    fatalerror('no capture!');
  }

  // @TODO: fill in the missing key names.
  keyboard_names[8]='backspace';
  keyboard_names[9]='tab';
  keyboard_names[13]='enter';
  keyboard_names[16]='shift';
  keyboard_names[17]='ctrl';
  keyboard_names[18]='alt';
  keyboard_names[19]='pause/break';
  keyboard_names[20]='caps lock';
  keyboard_names[27]='escape';
  keyboard_names[33]='page up';
  keyboard_names[32]='space';
  keyboard_names[34]='page down';
  keyboard_names[35]='end';
  keyboard_names[36]='home';
  keyboard_names[37]='arrow left';
  keyboard_names[38]='arrow up';
  keyboard_names[39]='arrow right';
  keyboard_names[40]='arrow down';
  keyboard_names[44]='print screen';
  keyboard_names[45]='insert';
  keyboard_names[46]='delete';
  keyboard_names[48]='0';
  keyboard_names[49]='1';
  keyboard_names[50]='2';
  keyboard_names[51]='3';
  keyboard_names[52]='4';
  keyboard_names[53]='5';
  keyboard_names[54]='6';
  keyboard_names[55]='7';
  keyboard_names[56]='8';
  keyboard_names[57]='9';
  keyboard_names[65]='a';
  keyboard_names[66]='b';
  keyboard_names[67]='c';
  keyboard_names[68]='d';
  keyboard_names[69]='e';
  keyboard_names[70]='f';
  keyboard_names[71]='g';
  keyboard_names[72]='h';
  keyboard_names[73]='i';
  keyboard_names[74]='j';
  keyboard_names[75]='k';
  keyboard_names[76]='l';
  keyboard_names[77]='m';
  keyboard_names[78]='n';
  keyboard_names[79]='o';
  keyboard_names[80]='p';
  keyboard_names[81]='q';
  keyboard_names[82]='r';
  keyboard_names[83]='s';
  keyboard_names[84]='t';
  keyboard_names[85]='u';
  keyboard_names[86]='v';
  keyboard_names[87]='w';
  keyboard_names[88]='x';
  keyboard_names[89]='y';
  keyboard_names[90]='z';
  keyboard_names[91]='left window key';
  keyboard_names[92]='right window key';
  keyboard_names[93]='select key';
  keyboard_names[96]='numpad 0';
  keyboard_names[97]='numpad 1';
  keyboard_names[98]='numpad 2';
  keyboard_names[99]='numpad 3';
  keyboard_names[100]='numpad 4';
  keyboard_names[101]='numpad 5';
  keyboard_names[102]='numpad 6';
  keyboard_names[103]='numpad 7';
  keyboard_names[104]='numpad 8';
  keyboard_names[105]='numpad 9';
  keyboard_names[106]='multiply';
  keyboard_names[107]='add';
  keyboard_names[109]='subtract';
  keyboard_names[110]='decimal point';
  keyboard_names[111]='divide';
  keyboard_names[112]='f1';
  keyboard_names[113]='f2';
  keyboard_names[114]='f3';
  keyboard_names[115]='f4';
  keyboard_names[116]='f5';
  keyboard_names[117]='f6';
  keyboard_names[118]='f7';
  keyboard_names[119]='f8';
  keyboard_names[120]='f9';
  keyboard_names[121]='f10';
  keyboard_names[122]='f11';
  keyboard_names[123]='f12';
  keyboard_names[144]='num lock';
  keyboard_names[145]='scroll lock';
  keyboard_names[182]='My Computer (multimedia keyboard)';
  keyboard_names[183]='My Calculator (multimedia keyboard)';
  keyboard_names[186]='semi-colon';
  keyboard_names[187]='equal sign';
  keyboard_names[188]='comma';
  keyboard_names[189]='dash';
  keyboard_names[190]='period';
  keyboard_names[191]='forward slash';
  keyboard_names[219]='open bracket';
  keyboard_names[220]='back slash';
  keyboard_names[221]='close braket';
  keyboard_names[222]='single quote';
}


//---------------------------------------------------------------------------
function getKeyboardDown(e) {
  if (!e) e = window.event;  // IE event model
  x=e.which;
  if(e.which>255) fatalerror("keyboard overflow ("+x+")");
  keyboard_keys[x]=1;
  keyboard_states[x]=KEY_DROP;
}


//---------------------------------------------------------------------------
function getKeyboardUp(e) {
  if (!e) e = window.event;  // IE event model
  x=e.which;
  if(e.which>255) fatalerror("keyboard overflow ("+x+")");
  keyboard_keys[x]=0;
  keyboard_states[x]=KEY_RISE;
}


//---------------------------------------------------------------------------
function getMouseDown(e) {
  if (!e) e = window.event;  // IE event model
  mouse_button=1;
  mouse_state=KEY_DROP;
}


//---------------------------------------------------------------------------
function getMouseUp(e) {
  if (!e) e = window.event;  // IE event model
  mouse_button=0;
  mouse_state=KEY_RISE;
}


//---------------------------------------------------------------------------
function getMouseMove(e) {
  if (!e) e = window.event;  // IE event model

  mouse_X = e.clientX + document.body.scrollLeft-canvas_left;
  mouse_Y = e.clientY + document.body.scrollTop-canvas_top;

  if (mouse_X < 0) mouse_X = 0;
  if (mouse_Y < 0) mouse_Y = 0;  

  return true;
}


//---------------------------------------------------------------------------
function updateInput() {
  // keyboard
  for(i=0;i<keyboard_states.length;++i) {
    switch(keyboard_states[i]) {
    case KEY_DROP: keyboard_states[i]=KEY_DOWN; break;
    case KEY_RISE: keyboard_states[i]=KEY_UP;   break;
    default: break;
    }
  }

  // mouse
  mouse_old_X=mouse_X;
  mouse_old_Y=mouse_Y;
  switch(mouse_state) {
  case KEY_DROP: mouse_state=KEY_DOWN; break;
  case KEY_RISE: mouse_state=KEY_UP;   break;
  default: break;
  }
}


//---------------------------------------------------------------------------
// GRAPHICS
//---------------------------------------------------------------------------
var width=0;
var height=0;
var ctx=null;
var keep_going=null;
var FPS=30;
var FPS_DT=Math.floor(1000/FPS);

function startSystem(target,_width,_height) {
  width=_width;
  height=_height;
  var canvas = document.getElementById(target);
  if (canvas.getContext){
    ctx = canvas.getContext('2d');

    findOffset(canvas);
    startInput();
    startGame();

    keep_going=setTimeout('doFrame()',FPS);
  } else {
    // canvas-unsupported code here
    alert("Sorry, this browser does not support the HTML 5 Canvas element.");
  }
}


//---------------------------------------------------------------------------
function doFrame() {
  then=new Date();
  drawFrame();
  now=new Date();

  ms=now.getTime()-then.getTime();
  x=FPS_DT-(ms%FPS_DT);
  keep_going=setTimeout('doFrame()',x);
}


//---------------------------------------------------------------------------
function stopSystem() {
  if(keep_going) {
    keep_going=stopTimeout(keep_going);
  }
}


//---------------------------------------------------------------------------
// where r,g,b =[0...1.0] and a=[0...1]
function setColor(r,g,b,a) {
  r=Math.floor(r*255.0);
  g=Math.floor(g*255.0);
  b=Math.floor(b*255.0);
  ctx.strokeStyle='rgba('+r+','+g+','+b+','+a+')';
  ctx.fillStyle='rgba('+r+','+g+','+b+','+a+')';
}


//---------------------------------------------------------------------------
// where r,g,b =[0...1.0]
function setColor(r,g,b) {
  r=Math.floor(r*255.0);
  g=Math.floor(g*255.0);
  b=Math.floor(b*255.0);
  ctx.strokeStyle='rgb('+r+','+g+','+b+')';
  ctx.fillStyle='rgb('+r+','+g+','+b+')';
}


//---------------------------------------------------------------------------
// does not check if the line is within the bounds of the rendering context.
function drawLine(x1,y1,x2,y2) {
  ctx.beginPath();
  ctx.moveTo(x1,y1);
  ctx.lineTo(x2,y2);
  ctx.stroke();                                    
}


//---------------------------------------------------------------------------
function drawCircle(x,y,radius) {
  ctx.beginPath();
  ctx.arc(x,y,radius,0,Math.PI*2,true);
  ctx.stroke();
}


//---------------------------------------------------------------------------
function fillCircle(x,y,radius) {
  ctx.beginPath();
  ctx.arc(x,y,radius,0,Math.PI*2,true);
  ctx.fill();
}


//---------------------------------------------------------------------------
function drawLineTest() {
  setColor(Math.ceil(Math.random()*255),
           Math.ceil(Math.random()*255),
           Math.ceil(Math.random()*255),1);
  drawLine(Math.random()*width,Math.random()*height,
           Math.random()*width,Math.random()*height);
  setColor(255,255,255,1);
  // white square
  drawLine(width*0.25,height*0.25, width*0.75,height*0.25);
  drawLine(width*0.25,height*0.75, width*0.75,height*0.75);
  drawLine(width*0.25,height*0.25, width*0.25,height*0.75);
  drawLine(width*0.75,height*0.25, width*0.75,height*0.75);
}


//---------------------------------------------------------------------------
function clearBackground(r,g,b,a) {
  // background
  setColor(r,g,b,a);
  ctx.fillRect(0,0,width,height);
}


//---------------------------------------------------------------------------
// AUDIO
//---------------------------------------------------------------------------
function playSound(id) {
  x=document.getElementById(id);
  if(x) x.Play();
}
