
var Expr = require ('./expr');

/**
 * The equivalent of a SQL value.
 **/
module.exports = new Class
({
	Extends: Expr
	,Tag: 'sql-value'

	,Properties:
	{
		/**
		 * The master param.
		 **/
		param:
		{
			type: Vn.Param
			,set: function (x)
			{
				this.link ({_param: x}, {'changed': this.onParamChange});
				this.onParamChange ();
			}
			,get: function ()
			{
				return this._param;
			}
		},
		/**
		 * The value.
		 **/
		value:
		{
			type: String
			,set: function (x)
			{
				if (Vn.Value.compare (x, this._value))
					return;

				if (x instanceof Date)
					x = x.clone ();
			
				this._value = x;
		
				if (this._param && !this.paramLock)
				{
					this.paramLock = true;
					this._param.value = x;
					this.paramLock = false;
				}

				this.signalEmit ('changed');
			}
			,get: function ()
			{
				return this._value;
			}
		}
	}

	,_value: undefined
	,_param: null
	,regexp: new RegExp ('(\\\\)|\'', 'g')
	,paramLock: false

	,onParamChange: function ()
	{
		if (this.paramLock || !this._param)
			return;
	
		this.paramLock = true;
		this.value = this._param.value;
		this.paramLock = false;
	}
	
	,isReady: function ()
	{
		return this._value !== undefined;
	}
	
	,replaceFunc: function (token)
	{
		switch (token)
		{
			case '\\': return '\\\\';
			case '\'': return '\\\'';
		}
		
		return token;
	}

	,render: function (batch)
	{
		var v = this._value;
	
		switch (typeof v)
		{
			case 'number':
				return v;
			case 'boolean':
				return (v) ? 'TRUE' : 'FALSE';
			case 'string':
				return "'" + v.replace (this.regexp, this.replaceFunc) + "'";
			case 'object':
			if (v instanceof Date)
				return Vn.Date.strftime (v, '\'%Y-%m-%d\'');
			default:
				return 'NULL';
		}
	}
});
