﻿if (typeof(Tangora) == 'undefined') var Tangora = {};
Tangora.CalculationLibrary = new CalculationLibrary();

function CalculationLibrary()
{
    this._decimalSign = ",";
    this._thousandSeparator = ".";
    this._expressions = [];    
    this._resolvers = [];
    
    this.removeFormatting = function(value)
    {   
        var isValue = typeof(value) == 'object';          
        value = new String(value);
        if (value.indexOf(this._decimalSign)>-1)
        {
            value = value.replace(this._decimalSign, '|');
        }
        if (isValue)
        {
            value = value.replace('.', '|');
        }
        var re = new RegExp('\\' + this._thousandSeparator, 'gi');
        value = value.replace(re, '');
        value = value.replace('|', '.');
        return this.toNumber(value);        
    }           
    
    this.toNumber = function(value)
    {
        return parseFloat(value,10);
    }
    
    this.addResolver = function(name, callback)
    {
        this._resolvers[name] = callback;
    }
    
    this.addExpression = function(name, expr)
    {
        this._expressions[name] = expr;
    }
    
    this.execExpression = function(name, args)
    {        
        var expr = this._expressions[name];
        var re = new RegExp("\{.*?\}", "");
        var mf = null;
        var realExpr = expr;
        mf = re.exec(expr);
        while (mf)
        {
            if (args && typeof(args[mf])!='undefined')
            {
                realExpr = realExpr.replace(mf, args[mf]);            
            }
            else
            {
                var sMf = mf[0];
                var defValue = 0;
                if (mf[0].indexOf(',')>-1)
                {
                    sMf = mf[0].split(',')[0] + '}';
                    defValue = new Number(this.removeFormatting(mf[0].split(',')[1]).replace('}',''));
                }
                var value = 0;
                try
                {
                    var resolver = this._resolvers[sMf];
                    if (resolver) value = this.removeFormatting(resolver());
                    else value = this.removeFormatting(this.execExpression(sMf.replace('{','').replace('}','')));
                    if (isNaN(value)) value = defValue;
                }
                catch(e)
                {
                    value = defValue;
                }
                realExpr = realExpr.replace(mf, value);
            }
            var rc = realExpr;//RegExp.rightContext;            
            mf = re.exec(rc);
        }
        return new Number(eval(realExpr));        
    }
}