import Em from 'ember';
import LlamaCell from './llama-cell';
var get = Em.get;
var observer = Em.observer;
var addObserver = Em.addObserver;
var removeObserver = Em.removeObserver;
var computed = Em.computed;
var alias = computed.alias;
var or = computed.or;
var and = computed.and;
var bool = computed.bool;
var empty = computed.empty;
var gt = computed.gt;
var ESC = 27;
var SPACE = 32;

var LlamaBodyCell = LlamaCell.extend({
	templateName: 'llama-body-cell',
	classNames: 'llama-body-cell',
	classNameBindings: ['hover', 'columnIsClickable', 'rowIsClickable', 'isClickable', 'isEmpty', 'showingSubcontent', 'isEditable'],
	attributeBindings: ['tabindex'],
	hover: false,
	height: alias('row.height'),
	columnIsClickable: alias('column.isClickable'),
	rowIsBody: gt('row.contentIndex', -1),
	rowIsClickable: and('controller.enableRowClick', 'rowIsBody'),
	isClickable: or('columnIsClickable', 'rowIsClickable'),
	showingSubcontent: bool('row.isExpanded'),
	isEmpty: empty('value'),
	isEditable: bool('column.isEditable'),

	column: null,
	row: null,

	tabindex: computed('isEditable', function () {
		var onlyFocusEditable = this.get('controller.onlyFocusEditable');
		var isEditable = this.get('isEditable');
		var index = onlyFocusEditable && !isEditable ? null : 0;
		return index;
	}),

	// only calculated once
	observedFields: computed(function () {
		var observes = this.get('column.observes');
		if (!Em.isEmpty(observes)) {
			return observes;
		}
		var id = this.get('column.name');
		return id;
	}),

	marginBottom: computed('showingSubcontent', 'row.subcontentHeight', function () {
		var isExpanded = this.get('showingSubcontent');
		if (isExpanded) {
			return this.get('row.subcontentHeight');
		}
		return null;
	}),

	didInsertElement: function () {
		this._super();
		var row = this.get('row');
		var observes = this.get('observedFields');
		addObserver(row, observes, this, 'updateValue');
	},

	willDestroyElement: function () {
		var row = this.get('row');
		var observes = this.get('observedFields');
		removeObserver(row, observes, this, 'updateValue');
		this._super();
	},

	setHeight: observer('height', function () {
		var $cell = this.$();
		if ($cell) {
			$cell.css('height', this.get('height'));
		}
	}).on('didInsertElement'),

	setMarginBottom: observer('marginBottom', function () {
		var $cell = this.$();
		if ($cell) {
			$cell.css('marginBottom', this.get('marginBottom') || 0);
		}
	}).on('didInsertElement'),

	getValue: function () {
		var id = this.get('column.name');
		var row = this.get('row');
		var value = get(row, id);
		return value;
	},

	updateValue: observer('column', function () {
		var value = this.getValue();
		this.set('value', value);
	}).on('init'),

	mouseEnter: function () {
		var row = this.get('row');
		this.get('controller').send('highlightRow', row);
	},

	mouseLeave: function () {
		this.get('controller').send('stopHighlightingRows');
	},

	click: function () {
		var controller = this.get('controller');
		var row = this.get('row');
		var column = this.get('column');
		if (this.get('isClickable')) {
			controller.sendAction('cellClick', row, column);
		}
		if (controller.get('enableRowClick')) {
			controller.sendAction('rowClick', row);
		}
	},

	focusIn: function () {
		var controller = this.get('controller');
		var row = this.get('row');
		var column = this.get('column');
		controller.send('focusCell', row, column);
		return false;
	},

	keyDown: function (e) {
		if (e.which === ESC) {
			this.$().blur();
		}
		else if (e.which === SPACE) {
			this.send('primaryAction', e);
		}
		else {
			this._super(e);
		}
	},

	actions: {
		primaryAction: function (e) {
			// cancel action by default
			e.preventDefault();
		}
	}
});

export default LlamaBodyCell;

@@ -81,77 +81,101 @@
 var 
-observer = Em.observer;%0Avar addObserver = Em.addObserver;%0Avar removeO
+set = Em.set;%0Avar defineProperty = Em.defineProperty;%0Avar deprecate = Em.deprecateFunc;%0Avar o
 bser
@@ -183,23 +183,17 @@
 er = Em.
-removeO
+o
 bserver;
@@ -1066,16 +1066,53 @@
  null,%0A%0A
+%09cell: null,%0A%09value: alias('cell'),%0A%0A
 %09tabinde
@@ -1790,373 +1790,8 @@
 ),%0A%0A
-%09didInsertElement: function () %7B%0A%09%09this._super();%0A%09%09var row = this.get('row');%0A%09%09var observes = this.get('observedFields');%0A%09%09addObserver(row, observes, this, 'updateValue');%0A%09%7D,%0A%0A%09willDestroyElement: function () %7B%0A%09%09var row = this.get('row');%0A%09%09var observes = this.get('observedFields');%0A%09%09removeObserver(row, observes, this, 'updateValue');%0A%09%09this._super();%0A%09%7D,%0A%0A
 %09set
@@ -2152,143 +2152,166 @@
 ue: 
-function () %7B%0A%09%09var id = this.get('column.name');%0A%09%09var row = this.get('row');%0A%09%09var value = get(row, id);%0A%09%09return value;%0A%09%7D,%0A%0A%09upda
+deprecate('Override %60value%60 property instead', function () %7B%7D),%0A%0A%09updateValue: deprecate('Override %60value%60 property instead', function () %7B%7D),%0A%0A%09buildCompu
 te
+d
 Valu
@@ -2329,16 +2329,21 @@
 ('column
+.name
 ', funct
@@ -2357,20 +2357,25 @@
 %7B%0A%09%09var 
-valu
+columnNam
 e = this
@@ -2382,42 +2382,101 @@
 .get
-Value();%0A%09%09this.set('value', value
+('column.name');%0A%09%09var prop = alias('row.' + columnName);%0A%09%09defineProperty(this, 'cell', prop
 );%0A%09

Define body cell `value` as a computed property