var Model = require ('./model');
var SimpleIterator = require ('./simple-iterator');

/**
 * Interface for handle foreach operations on the model.
 **/
module.exports = new Class
({
	Extends: Vn.Param
	,Tag: 'db-calc'
	,Properties:
	{
		 model:
		 {
			type: Model
			,set: function (x)
			{
				this.link ({_model: x},
				{
					 'status-changed': this.onModelChange
					,'row-deleted-before': this.onRowDeleteBefore
					,'row-updated': this.onRowUpdate
					,'row-updated-before': this.onRowUpdateBefore
					,'row-inserted': this.onRowInsert
				});

				var set = new SimpleIterator ({model: x});
				this.link ({_set: set});
			}
			,get: function ()
			{
				return this._model;
			}
		},
		columnIndex:
		{
			type: Number
			,set: function (x)
			{
				this.reset ();
				this._columnIndex = x;
				this.onModelChange ();
			}
			,get: function ()
			{
				return this._columnIndex;
			}
		},
		columnName:
		{
			type: String
			,set: function (x)
			{
				this.reset ();
				this._columnName = x;
				this.onModelChange ();
			}
			,get: function ()
			{
				return this._columnName;
			}
		},
		func:
		{
			type: Function
			,set: function (x)
			{
				this.reset ();
				this._func = x;
				this.onModelChange ();
			}
			,get: function ()
			{
				return this._func;
			}
		}
	}
	
	,_model: null
	
	,reset: function ()
	{
		delete this._columnIndex;
		delete this._columnName;
		delete this._func;
	}

	,onModelChange: function ()
	{
		this.init ();

		if (this._model)
		{
			if (this._model.ready && this._columnName)
				this._columnIndex = this._model.getColumnIndex (this._columnName);

			var rows = this._model.numRows;

			for (var i = 0; i < rows; i++)
				this.after (i);
		}

		this.done ();
	}
	
	,onRowInsert: function (model, row)
	{
		this.after (row);
		this.done ();
	}
	
	,onRowUpdateBefore: function (model, row)
	{
		this.before (row);
	}
	
	,onRowUpdate: function (model, row)
	{
		this.after (row);
		this.done ();
	}
	
	,onRowDeleteBefore: function (model, row)
	{
		this.before (row);
		this.done ();
	}

	/**
	 * Called before each update or delete row operation.
	 * You don't need to define it if model isn't updatable.
	 *
	 * @param {integer} row The row number
	 **/
	,before: function (row) {}

	/**
	 * Called after each update or insert row operation.
	 *
	 * @param {integer} row The row number
	 **/
	,after: function (row) {}

	/**
	 * Called before each model refresh.
	 **/
	,init: function () {}

	/**
	 * Called when an operation in the model is complete.
	 **/
	,done: function () {}
});