function random(x) {
  return Math.random()*x;
}

function randcolor() {
  return [Math.random()*255, Math.random()*255, Math.random()*255];
}

function randomSign() {
  var x = Math.random();
  if (x > 0.5)
    return 1;
  else
    return -1;
}

function getDistance(point1, point2) {
  return Math.sqrt(Math.pow(point2[0] - point1[0], 2)
                   + Math.pow(point2[1] - point1[1], 2));
}

function randomDirection() {
  var res = Math.random()*0.6*randomSign();
  if (Math.abs(res) < 0.13) {
    if (res < 0) return -0.13;
    else         return 0.13;
  }
  else return res;
}

function colorDef(color, alpha) {
  return  "rgba(" + Math.round(color[0]) + ", "
	          + Math.round(color[1]) + ", "
                  + Math.round(color[2]) + ", "
		  + alpha + ")";
}

var Text = klass.create();
Object.extend(Text, {
  drawText: function(g, text, position, opts) {
    if (text && g.mozDrawText) {
      g.save();
      g.fillStyle = "rgba(" + Math.round(opts.color[0]) + ", "
                            + Math.round(opts.color[1]) + ", "
                            + Math.round(opts.color[2]) + ", "
		            + opts.alpha + ")";
      g.mozTextStyle = Text.getTextStyle(opts);
      g.translate(position[0], position[1]);
      g.mozDrawText(text);
      g.restore();
    } else if (text & g.fillText) {
      g.save();
      g.fillStyle = "rgba(" + Math.round(opts.color[0]) + ", "
                            + Math.round(opts.color[1]) + ", "
                            + Math.round(opts.color[2]) + ", "
		            + opts.alpha + ")";
      g.mozTextStyle = Text.getTextStyle(opts);
      g.fillText(text, position[0], position[1]);
      g.restore();
    }
  },

  getTextStyle: function(opts) {
    return opts.style + ' ' + opts.size + "px " + opts.typefamily;
  },

  measureText: function(g, text, opts) {
    if (g.mozMeasureText) {
      g.save();
      g.mozTextStyle = Text.getTextStyle(opts);
      var res = g.mozMeasureText(text)
      g.restore();
      return res;
    } else if (g.measureText) {
      g.save();
      g.textStyle = Text.getTextStyle(opts);
      var res = g.measureText(text)
      g.restore();
      return res;
    } else {
      return 0;
    }
  }
});

var Scene = klass.create();
Object.extend(Scene.prototype, {
  initialize: function(canvas) {
    this.canvas = canvas;
    this.width = canvas.width;
    this.height = canvas.height;
    this.graphics = canvas.getContext('2d');
    this.children = [];
    this.graphics.translate( 0.5, 0.5 );    
    // Event.observe(this.canvas, 'mousedown',
    //     	  this.onMouseDown.bind(this));
    this.framePlay = tasklet(this.enterFrame.bind(this), 10);
  },

  removeChildren: function() {
    this.children = [];
  },

  removeChild: function(child) {
    var newlist = [];
    for (var i=0; i<this.children.length; ++i)
      if (this.children[i] != child) newlist.push(this.children[i]);
    this.children = newlist;
  },

  addChild: function(child) {
    this.children.push(child);
  },

  translateScenePosition: function(evt) {
    var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
    var scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
    var mouseX = evt.clientX - this.canvas.offsetLeft + scrollX;
    var mouseY = evt.clientY - this.canvas.offsetTop + scrollY;    
    return [mouseX, mouseY];
  },

  onEnterFrame: function() {
  },

  onExitFrame: function() {
  },

  enterFrame: function() {
    // clear scene
    try {
    // this.graphics.fillStyle = colorDef([0, 0, 0], 0.05);
    this.graphics.clearRect(0, 0, this.canvas.width, this.canvas.height);
    // this.graphics.fillRect(0, 0, this.canvas.width, this.canvas.height);

    // render top-level
    this.graphics.save();
    this.onEnterFrame();
    this.graphics.restore();

    // render children
    this.graphics.save();
    for (var i=0; i<this.children.length; ++i) {
      this.children[i].onEnterFrame();
    }
    this.graphics.restore();

    // render top-level
    this.graphics.save();
    this.onExitFrame();
    this.graphics.restore();
    } catch(e) {
      alert(e); throw e;
    }
  }
});

// vim: set sts=2 sw=2:
