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() {
		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) + "'";
		default:
			if (v instanceof Date)
				return Vn.Date.strftime(fixTz(v), '\'%Y-%m-%d\'');
			else
				return 'NULL';
		}
	}
});

function fixTz(date) {
	var  midDay = new Date(date.getTime());
	midDay.setHours(12, 0, 0, 0);

	// TODO: Read time zone from db configuration
	var tz = {timeZone: 'Europe/Madrid'};
	return new Date(midDay.toLocaleString('en-US', tz));
}