/*
 * rch@201704240914
 * Este script es una copia de la unidad pascal ugraficador. 
 * El propósito es tener una forma de graficar directamente en el navegador
 * para que los programas de pascal puedan simplemente exportar las series
 * de datos e indicar lo necesario para graficarlo, pero que sea en el navegador
 * en donde se procede a dibujar. Esto tendría que hacer mucho más rápido
 * la transmisión de datos.
 * 
 * 
 */

var dt_19700101 = 25569; // Días desde el inicio de los DateTime a 1/1/1970

// standard colors
var clBlack = "$000000";
var clMaroon = "$000080";
var clGreen = "$008000";
var clOlive = "$008080";
var clNavy = "$800000";
var clPurple = "$800080";
var clTeal = "$808000";
var clGray = "$808080";
var clSilver = "$C0C0C0";
var clRed = "$0000FF";
var clLime = "$00FF00";
var clYellow = "$00FFFF";
var clBlue = "$FF0000";
var clFuchsia = "$FF00FF";
var clAqua = "$FFFF00";
var clLtGray = "$C0C0C0"; // clSilver alias
var clDkGray = "$808080"; // clGray alias
var clWhite = "$FFFFFF";

var StandardColorsCount = 16;

// extended colors
var clMoneyGreen = "$C0DCC0";
var clSkyBlue = "$F0CAA6";
var clCream = "$F0FBFF";
var clMedGray = "$A4A0A0";

var ExtendedColorCount = 4;
// special colors
var clNone = "$1FFFFFFF";
var clDefault = "$20000000";


var TColoresPaleta = new Array(
        clBlack
        , clMaroon
        , clGreen
        , clOlive
        , clNavy
        , clPurple
        , clTeal
        , clGray
        , clSilver
        , clRed
        , clLime
        , clYellow
        , clBlue
        , clFuchsia
        , clAqua);


var TNombreColores = new Array(
        'Negro'
        , 'Marrón'
        , 'Verde'
        , 'Oliva'
        , 'Azul marino'
        , 'Púrpura'
        , 'Verde azulado'
        , 'Gris'
        , 'Plata'
        , 'Rojo'
        , 'Lima'
        , 'Amarillo'
        , 'Azul'
        , 'Fusia'
        , 'Agua');


var TNombreMarcador = new Array('Circulo', 'Cuadro', 'Rombo', 'Cruz', 'X');

// Tipos de eje
var TDE_Real = 0;
var TDE_Entero = 1;
var TDE_Fecha = 2;

// Formatos numéricos
var ffGeneral = 0;
var ffExponent = 1;
var ffFixed = 2;
var ffNumber = 3;
var ffCurrency = 4;


var Create_TEjeGrafico = function (titulo_) {

    var res = new {
        titulo: titulo_,
        v_min_real: 0.0, v_max_real: 0.0, // valores extremos de las series.
        v_min_forzado: 0.0, v_max_forzado: 0.0, // valores fijados forzados.
        v_min_auto: 0.0, v_max_auto: 0.0, // valores calculados automáticamente.
        v_min_activo: 0.0, v_max_activo: 0.0, // valores activos, auto o forzado según corresponda
        flg_min_auto: true, flg_max_auto: true, // indica se usa el automático o el forzado,
        flg_espacio_inf: true,
        v0: 0.0, // posición primera linea de la grilla
        dv: 0.0, // ancho de la divición
        nDivs: 10, // cantida de divisiones de la grilla

        nDivs_forzado: 0,
        flg_ndivs_auto: true,
        flg_mostrar_lineas: true,
        flg_etiquetaX: true,
        // Por defecto
        tipoDato: TDE_Real, // TDE_Real, TDE_Entero, TDE_Fecha,
        FloatFormat: ffGeneral, // (ffGeneral, ffExponent, ffFixed, ffNumber, ffCurrency);
        FloatFormat_NDigitos: 12,
        FloatFormat_NDecimales: 2,
        DateFormatStr: 'yyyy/mm/dd hh:mm', // Ej: 'yyyy/mm/dd hh:mm'

        // en min_val, max_val deben ingresar los extremos REALES
        // y son devueltos los aplicables
        Calcular: function (param) {
            this.v_min_real = param.min_val;
            this.v_max_real = param.max_val;
            this.v_min_auto = param.min_val;
            this.v_max_auto = param.max_val;

            var ao = new {v_min_auto: this.v_min_auto, v_max_auto: this.v_max_auto, dv: this.dv};

            if (this.flg_min_auto && this.flg_max_auto) {
                Escala125N(ao, 1);
            } else {
                Escala125N(ao, nDivs, 0);
            }

            this.v_min_auto = ao.v_min_auto;
            this.v_max_auto = ao.v_max_auto;
            this.dv = ao.dv;


            if (!this.flg_ndivs_auto) {
                this.nDivs = this.nDivs_forzado;
            }

            if (this.flg_min_auto) {
                this.v_min_activo = this.v_min_auto;
            } else {
                this.v_min_activo = this.v_min_forzado;
            }

            if (this.flg_max_auto) {
                this.v_max_activo = this.v_max_auto;
            } else {
                this.v_max_activo = this.v_max_forzado;
            }
            this.v0 = this.v_min_activo;
            this.dv = (this.v_max_activo - this.v_min_activo) / this.nDivs;

            param.min_val = this.v_min_activo;
            param.max_val = this.v_max_activo;
        },
        // Calcula los valores automáticos en base
        Forzar_vmin: function (v_min) {
            this.v_min_forzado = v_min;
            this.flg_min_auto = false;
        },
        Forzar_vmax: function (v_max) {
            this.v_max_forzado = v_max;
            this.flg_max_auto = false;
        },
        Forzar_ndivs: function (ndivs) {
            this.ndivs_forzado = ndivs;
            this.flg_ndivs_auto = false;
        },
        Librar_vmin: function () {
            this.flg_min_auto = true;
        },
        Librar_vmax: function () {
            this.flg_max_auto = true;
        },
        Liberar_ndivs: function () {
            this.flg_ndivs_auto = true;
        },
        // retorna la etiqueta k con el formato correspondiente
        label_str: function (k) {
            var s = '';
            var x_v = this.x_v = this.v0 + k * this.dv;
            switch (this.tipoDato) {
                case TDE_Fecha:
                    s = DateTimeToString(x_v, DateFormatStr);
                    break;
                case TDE_Entero:
                    s = ''+Math.round(x_v);
                    break;
                default:
                    s = FloatToStrF(x_v, FloatFormat, FloatFormat_NDigitos, FloatFormat_NDecimales);
            }
            return s;
        }
    };
    return res;
};

function Escala125N(param, MODO) { // x1, x2, dx, N, MODO
    var m = 0;
    var aux = 0;
    var n1 = 0;
    var n2 = 0;
    var k = 0;
    var j = 0;
    var temp = new Array( ); //   array[1..3] of NReal;
    var a = new Array(); //   array[1..3] of integer;
    var expo = 0;

    if (param.x1 > param.x2) { // hay que ayudar a los tontos
        this.aux = param.x1;
        param.x1 = param.x2;
        param.x2 = this.aux;
    }

    if ((param.x2 - param.x1) < 1E-32) {
        param.x2 = param.x1 + 1E-8;
    }

    aux = Math.log10(param.x2 - param.x1);

    temp[1] = Math.log10(param.N);
    temp[2] = Math.log10(2 * param.N);
    temp[3] = Math.log10(5 * param.N);

    if (MODO === 1) {
        m = 1e30;
        j = 0;
        for (k = 1; k <= 3; k++) {
            a[k] = IntSup(aux - temp[k]);
            if ((temp[k] + a[k]) < m)
            {
                m = temp[k] + a[k];
                j = k;
            }
        }
    } else {
        m = -1e30;
        j = 0;
        for (k = 1; k <= 3; k++)
        {
            a[k] = IntInf(aux - temp[k]);
            if ((temp[k] + a[k]) > m)
            {
                m = temp[k] + a[k];
                j = k;
            }
        }
    }

    if (j === 3) {
        dx = 5;
    } else {
        dx = j;
    }
    expo = a[j];
    aux = Math.pow(10, expo) * dx;
    if (MODO === 1)
    {
        n1 = Math.floor(param.x1 / aux);
        n2 = Math.ceil(param.x2 / aux);
    } else {
        n1 = Math.ceil(param.x1 / aux);
        n2 = Math.floor(param.x2 / aux);
    }
    param.N = n2 - n1;
    param.x1 = n1 * aux;
    param.x2 = n2 * aux;
    param.dx = aux;
}

function DateTimeToString(dt, DateFormatStr) {
    var d1 = new Date((dt - dt_19700101) * 24 * 3600 * 1000);
    var dd = d1.getDate();
    var mm = (d1.getMonth() + 1);
    var yyyy = d1.getFullYear();
    var hh = d1.getHours();
    var s = new String( DateFormatStr );
    s = s.replace('dd', dd);
    s = s.replace('mm', mm);
    s = s.replace('yyyy', yyyy );
    s = s.replace( 'hh', hh );   
    return s;
}

function FloatToStrF( x_v, FloatFormat, FloatFormat_NDigitos, FloatFormat_NDecimales){
/*
var ffGeneral = 0;
var ffExponent = 1;
var ffFixed = 2;
var ffNumber = 3;
var ffCurrency = 4;
*/

  return ''+x_v;
}


