// TODO: This.
(function(){

var
  keys = {
    mod       : ['cmd', 'ctrl'],
    mash      : ['cmd', 'alt', 'ctrl'],
    mashShift : ['cmd', 'alt', 'ctrl', 'shift']
  },
  padding = 4;

// Maximize & partially maximize

api.bind('C', keys.mod, function(){
  Window.focusedWindow().center();
});

api.bind('C', keys.mash, function(){
  Window.focusedWindow().center(true);
});

// Cols

api.bind('[', keys.mod, function(){
  Window.focusedWindow().toLeftHalf();
});

api.bind(']', keys.mod, function(){
  Window.focusedWindow().toRightHalf();
});

// Cycle through halves

api.bind('[', keys.mash, function(){
  Window.focusedWindow().cycleLeft();
});

api.bind(']', keys.mash, function(){
  Window.focusedWindow().cycleRight();
});

// Halves

api.bind('/', keys.mod, function(){
  Window.focusedWindow().chopY();
});

api.bind('/', keys.mash, function(){
  Window.focusedWindow().chopY(true);
});

// Nudges

api.bind('up', keys.mod, function(){
  Window.focusedWindow().nudge('north');
});

api.bind('right', keys.mod, function(){
  Window.focusedWindow().nudge('east');
});

api.bind('down', keys.mod, function(){
  Window.focusedWindow().nudge('south');
});

api.bind('left', keys.mod, function(){
  Window.focusedWindow().nudge('west');
});

// Resize

api.bind('up', keys.mashShift, function(){
  Window.focusedWindow().resize('north');
});

api.bind('right', keys.mashShift, function(){
  Window.focusedWindow().resize('east');
});

api.bind('down', keys.mashShift, function(){
  Window.focusedWindow().resize('south');
});

api.bind('left', keys.mashShift, function(){
  Window.focusedWindow().resize('west');
});

// Throws

api.bind('up', keys.mash, function(){
  Window.focusedWindow().throwTo('north');
});

api.bind('right', keys.mash, function(){
  Window.focusedWindow().throwTo('east');
});

api.bind('down', keys.mash, function(){
  Window.focusedWindow().throwTo('south');
});

api.bind('left', keys.mash, function(){
  Window.focusedWindow().throwTo('west');
});

Window.prototype.getGrid = function(x, y, width, height) {

  var screen = this.cachedScreen || this.setScreen(this.screen().frameWithoutDockOrMenu());

  return {
    x:      Math.round(x * screen.width)       + padding    + screen.x,
    y:      Math.round(y * screen.height)      + padding    + screen.y,
    width:  Math.round(width * screen.width)   - 2*padding,
    height: Math.round(height * screen.height) - 2*padding
  };

};

Window.prototype.toGrid = function(x, y, width, height) {
  var rect = this.getGrid(x, y, width, height);
  this.setFrame(rect);

  this.deleteScreen();

  return this;
};

Window.prototype.getQuadrant = function(){

  var screen = this.cachedScreen || this.setScreen(this.screen().frameWithoutDockOrMenu());
  var window = this.frame();

  var screenHaflWidth  = Math.round(screen.width * 0.5);
  var screenHaflHeight = Math.round(screen.height * 0.5);

  if ( (window.x + window.width / 2) <= screenHaflWidth
    && (window.y + window.height / 2) <= screenHaflHeight ) {
    // this.toQuadrant(1);
    return 1;
  }
  if ( (window.x + window.width / 2) >= screenHaflWidth
    && (window.y + window.height / 2) <= screenHaflHeight ) {
    // this.toQuadrant(2);
    return 2;
  }
  if ( (window.x + window.width / 2) <= screenHaflWidth
    && (window.y + window.height / 2) >= screenHaflHeight ) {
    // this.toQuadrant(3);
    return 3;
  }
  if ( (window.x + window.width / 2) >= screenHaflWidth
    && (window.y + window.height / 2) >= screenHaflHeight ) {
    // this.toQuadrant(4);
    return 4;
  }

};

Window.prototype.nextQuadrant = function() {

  var toQuadrant = this.getQuadrant() === 4 ? 1 : this.getQuadrant() + 1;
  return this.toQuadrant(toQuadrant);

};

Window.prototype.prevQuadrant = function() {

  var toQuadrant = this.getQuadrant() === 1 ? 4 : this.getQuadrant() - 1;
  return this.toQuadrant(toQuadrant);

};

Window.prototype.toQuadrant = function(quadrant) {

  if (quadrant === 1) this.toGrid(0, 0, 0.5, 0.5);
  if (quadrant === 2) this.toGrid(0.5, 0, 0.5, 0.5);
  if (quadrant === 3) this.toGrid(0, 0.5, 0.5, 0.5);
  if (quadrant === 4) this.toGrid(0.5, 0.5, 0.5, 0.5);

  return this;

};

Window.prototype.setScreen = function(screen) {
  return this.cachedScreen = screen;
};

Window.prototype.deleteScreen = function() {
  delete this.cachedScreen;
};

Window.prototype.throwTo = function(keyword) {

  var screen = this.cachedScreen || this.setScreen(this.screen().frameWithoutDockOrMenu());
  var window = this.frame();

  var target = { x: window.x, y: window.y };

  if (keyword === 'north') target.y = screen.y + padding;
  if (keyword === 'east') target.x = screen.width - (window.width + padding) + screen.x;
  if (keyword === 'south') target.y = screen.height - (window.height + padding) + screen.y;
  if (keyword === 'west') target.x = screen.x + padding;

  this.setTopLeft(target);
  this.deleteScreen();

  return this;
}

Window.prototype.nudge = function(keyword) {

  var screen = this.cachedScreen || this.setScreen(this.screen().frameWithoutDockOrMenu());
  var window = this.frame();

  var nudgeX = Math.round(screen.width * 0.1),
      nudgeY = Math.round(screen.height * 0.1);

  var target = { x: window.x, y: window.y };

  if (keyword === 'north') target.y = window.y - nudgeY;
  if (keyword === 'east') target.x = window.x + nudgeX;
  if (keyword === 'south') target.y = window.y + nudgeY;
  if (keyword === 'west') target.x = window.x - nudgeX;

  this.setTopLeft(target);
  this.deleteScreen();

  return this;
}

Window.prototype.resize = function(keyword) {

  var screen = this.cachedScreen || this.setScreen(this.screen().frameWithoutDockOrMenu());
  var window = this.frame();

  var nudgeWidth = Math.round(screen.width * 0.1),
      nudgeHeight = Math.round(screen.height * 0.1);

  var target = { height: window.height, width: window.width };

  if (keyword === 'north') target.height = window.height - nudgeHeight;
  if (keyword === 'east') target.width = window.width + nudgeWidth;
  if (keyword === 'south') target.height = window.height + nudgeHeight;
  if (keyword === 'west') target.width = window.width - nudgeWidth;

  this.setSize(target);
  this.deleteScreen();

  return this;
}

Window.prototype.toLeftHalf = function() {
  return this.toGrid(0, 0, 0.5, 1);
}

Window.prototype.toRightHalf = function() {
  return this.toGrid(0.5, 0, 0.5, 1);
}

Window.prototype.chopY = function(fromBottom) {

  var screen = this.screen().frameWithoutDockOrMenu();
  var window = this.frame();

  if (fromBottom) {

    window.y = Math.round((window.height + (padding * 2)) / 2) + screen.y + padding;

    this.setTopLeft(window);

  }

  window.height = Math.round(window.height / 2) - padding;

  this.setSize(window);

  return this;
}

Window.prototype.cycleLeft = function(){
  return this.prevQuadrant();
};

Window.prototype.cycleRight = function(){
  return this.nextQuadrant();
};

Window.prototype.center = function(full){

  if (full) return this.maximize();

  return this.toGrid(0.1, 0.1, 0.8, 0.8);

};

})();
