//  MN is the namespace where our utility functions live.
var MN = {
  
  // Server-side Agnosticism
  urls: {
    'page.create'     : '',
    'note.create'     : '',
    'note.edit_title' : '',
    'note.edit_body'  : '',
    'note.move'       : '',
    'note.resize'     : '',
    'note.delete'     : '',
    'relation.create' : '',
    'relation.delete' : ''
  },

  // Object Mapping
  cache: { 
    note     : [ ],
    relation : [ ]
  },

  // Given an element, extract its ActiveRecord object id based on the string
  // found in the element's id field.
  id: function(element) {
    var idx = element.id.split('.');
    return idx[1];
  },

  // How much has the page scrolled?
  // - credit: http://www.quirksmode.org/viewport/compatibility.html
  // - I needed these coordinates so that I could create a new note
  //   with sane coordinates.
  getScrollingOffsets: function(xo, yo) {
    var x, y;
    if (!xo) {
      xo = 0;
    }
    if (!yo) {
      yo = 0;
    }
    Position.prepare();
    x = Position.deltaX;
    y = Position.deltaY;
    return { x: x + xo, y: y + yo };
  },

  // Figure out how the lines intersect (if at all).
  // http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/
  getLineIntersection: function(line1, line2) {
    var x1 = line1[0].x;
    var y1 = line1[0].y;
    var x2 = line1[1].x;
    var y2 = line1[1].y;
    var x3 = line2[0].x;
    var y3 = line2[0].y;
    var x4 = line2[1].x;
    var y4 = line2[1].y;

    // eventual return values
    var x            = null;
    var y            = null;
    var isParallel   = false;
    var isCoincident = false;

    // crunch
    var denominator  = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
    var numeratorA   = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
    var numeratorB   = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
    var ua           = numeratorA / denominator;
    var ub           = numeratorB / denominator;

    // analyse
    if (denominator == 0) {
      isParallel = true;
      if (numeratorA == 0 && numeratorB == 0) {
        isCoincident = true;
      }
    } else {
      x = x1 + ua * (x2 - x1);
      y = y1 + ua * (y2 - y1);
    }

    // it's like magic...
    return {
      x              : x,
      y              : y,
      isParallel     : isParallel,
      isCoincident   : isCoincident,
      isIntersecting : (
        (  (ua >= 0) )
        && (ua <= 1) 
        && (ub >= 0) 
        && (ub <= 1) 
        && (!isParallel) 
        && (x != null)
      )
    };
  }

};

