/************alerts engine************/


/**
* @author Javier Millan
*
* Draws the complete alerts component
* This is the entry point of alerts generation.
*
* @param <alerts_data>      Contains data_products[] + data_options + data_axis
* @param <alerts_config>    Complete configuration object.
*
*/
function draw_alerts(alerts_data, alerts_config,div){
    
    //style
    var strdiv = "#"+div;
    var dv = $(strdiv);
    //setCssStyles(dv,alerts_config);
            //global css graph
    if(alerts_config.css)
            addCssClasses(dv,alerts_config.css);

    //drawing
    var options = create_alerts_options(alerts_config, alerts_data,div);
    var data = create_alerts_data(alerts_data);

    var alerts = $.plot(dv,data,options);
   // console.dir(data);
    GLOBAL_ALERTS.push(alerts);

    //font styles
   // setFontStyles(alerts_config.styles);
           //css tick labels
    if(alerts_config.css_ticks)
            addCssTicks(alerts_config.css_ticks);

    // bind events
    bindAlertEvents(dv);


    if(typeof(alerts_config.graph_config.now_select) != 'undefined' && alerts_config.graph_config.now_select){
        //highlight_now(alerts_data.options.now);
        if(alerts_data.options.now > alerts_data.options.selected_epoch)
            highlight_now(alerts_data.options.now);
        
        else
            highlight_now(alerts_data.options.selected_epoch);
    }


}


function disablePastAlerts(alerts, options){


    //var series = alerts.getData();
   // var point = series.datapoints;
}

function create_alerts_options(config,data,div){

    var options = new Object();

    //series
    var series = new Object();
    
    //gantt config
    var gantt_options = new Object();
    gantt_options.active = true;
    gantt_options.show  =true;
    gantt_options.barHeight = config.graph_config.barHeight;

    gantt_options.highlight= new Object();
    gantt_options.highlight.opacity = 0.5;

    series.gantt = gantt_options;

    if(typeof(config.graph_config.colors)!= 'undefined')
        series.colorarray  = config.graph_config.colors;

    else
        series.colorarray =  ["rgba(102,102,102,1)","yellow","orange","red","green"];

    //uanble stacked data
    series.stack = false;

    series.div = div;
    series.events = config.events;

    options.series = series;

    //hihglightcolor
    //TODO

    data.options.start_epoch = data.options.start_epoch - data.options.cell_length;
    //data.options.finish_epoch = data.options.finish_epoch + data.options.cell_length;
    //data.options.now = data.options.now - data.options.cell_length;

    var xaxis_options = create_xaxis_options_alerts(config.xaxis,data.xaxis_data,data.options);
    

    xaxis_options.min = data.options.start_epoch;
    xaxis_options.max = data.options.finish_epoch;
    options.xaxis = xaxis_options;


    //yaxis options
    var yaxis1_options = create_yaxis_alerts_options(config,data);

    yaxis2_options = new Object();
    yaxis2_options.labelWidth = config.tick_width;

    options.yaxis = yaxis1_options;
    options.y2axis = yaxis2_options;
    
    var grid = create_grid_options(config.graph_config);

   if(data.options.cell_time>0){
       //grid.markings = generate_time_markings(data.options.start_epoch,data.options.finish_epoch,data.options.cell_time,grid.color,false);
       grid.markings = generate_time_markings_alerts(data.xmarkings_data,data.options.start_epoch,data.options.finish_epoch,data.options.cell_time,grid.color,false);  
}

    options.grid = grid;

    //now time
    options.now = data.options.now;
    
    if(typeof(config.graph_config.now_shadow) != 'undefined')
        options.now_shadow = config.graph_config.now_shadow;

    else
        options.now_shadow = false;

    return options;
}


function create_yaxis_alerts_options(config,data){

    var yoptions = new Object();
    yoptions.labelWidth = config.tick_width;

    var nproducts = data.product_data.length;

    var min = 0.5;
    var max = nproducts + 0.5;

    yoptions.min = min;
    yoptions.max = max;

    if(config.yaxis.show_ticks){

        //construction of ticks --> name of product
        var tick;
        var ticks = new Array();

        for(var i=0;i<nproducts;i++){
            tick = [i+1,data.product_data[i].p_name];
            ticks.push(tick);
        }
        
        yoptions.ticks = ticks;
    }

    //no ticks -> no name of products
    else
        yoptions.ticks = [];

    return yoptions;
}



function create_alerts_data(data){

    var d = new Array();


    var nproducts = data.product_data.length;
    var ndata;

    var p_values;
    var epoch;
    var value;

    var cell;
    var serie;

    var p_object;
       //delete the first tick line (is not necessary for alerts)
    //iteration for products
    for(var i=0;i<nproducts;i++){

        serie = new Array();

        //take values
        p_values = data.product_data[i].p_data;
        ndata = p_values.length;

        //construction of cell objects [start_epoch,end_epoch,"",value]
        for(var j=0;j<ndata;j++){

            //console.log("arriba:" + p_values[j][0]*1000+" valor:"+p_values[j][1]);
            p_values[j][0] = p_values[j][0]*1000 - data.product_data[i].alert_length;
            //p_values[j][0] = p_values[j][0]*1000;
            //console.log("trans:" + p_values[j][0]+" valor:"+p_values[j][1]);
            //format to milliepoch
            epoch = p_values[j][0];
            value = p_values[j][1];

            //alert(alerts_data.options.alert_length);
            cell = [epoch,i+1, epoch+data.product_data[i].alert_length, "A",1,value];
            serie.push(cell);
        }

        //creation of the object with data and the rest of parameters
        p_object = new Object();
        p_object.ident = data.product_data[i].p_id;
        p_object.hv = data.product_data[i].p_hv;
        p_object.now = data.options.now;
        p_object.data = serie;
        p_object.highlightColor="rgba(0,255,0,1)";
        p_object.alert_length = data.product_data[i].alert_length;

        d.push(p_object);
    }
    return d;
}


function generate_time_markings_alerts(xmarkings_data,init_time,finish_time,separation,color,realsim){
    var markings = new Array();
    var marking;
    var tmp_time;

    
    //markings defined
    if(xmarkings_data){
        for(var i =0; i< xmarkings_data.length;i++){
            marking = {color: color, lineWidth: 1, xaxis: {from: xmarkings_data[i]*1000, to: xmarkings_data[i]*1000}};
            markings.push(marking);
        }
    }

    //markings undefined; auto-computing
    else if(separation>0){
        for(tmp_time = init_time; tmp_time < finish_time; tmp_time += separation){
            marking = {color: color, lineWidth: 1, xaxis: {from: tmp_time, to: tmp_time}};
            markings.push(marking);
        }

        markings.shift();
    }

    //measured - simulated line
    if(realsim){
        if(realsim.show){
        var middle = init_time + (finish_time - init_time )/2;
        marking = {color: realsim.color, lineWidth: realsim.width, xaxis: {from: middle, to: middle}};
        markings.push(marking);
        }
    }

    return markings;
}


/**
* @author Javier Millan
* Creates an x-axis options object
*
* @param <xaxis_options>
* @param <xaxis_ticks>
* @param <time_options>
*
*/
function create_xaxis_options_alerts(xaxis_options,xaxis_ticks,time_options){

	var xaxis = new Object();
	xaxis.mode = "time";
	xaxis.timeFormat = xaxis_options.time_format;
	xaxis.min = time_options.start_epoch;
	xaxis.max = time_options.finish_epoch;
        var align_epoch;


	if(xaxis_ticks){
            //comprove if the ticks have to been showed
            if(xaxis_options.show_ticks){

                    if(time_options.period=='WEEKLY')
                        align_epoch = 43200000;

                    else
                        align_epoch = 0;


                    xaxis.ticks = xaxis_ticks.slice(0);
                    align_axis(xaxis.ticks,align_epoch);
            }

            else
                    xaxis.ticks = [];

        }

	return xaxis;
}

 /**
  * load the triangles that indicate today and last observation
  * @param {object} alerts_data is the data of the alerts
  * @param {object} alerts_config is the configuration of the alerts
  */
    function load_triangles(alerts_data,alerts_config){

        //check if we have to draw triangles and return if not
           if (!alerts_config.graph_config.triangles)
                return;
        //generate the divs 
         generateTriangleDiv();
         //now calculate positions data about triangles
         var triangle_data= obtainTrianglePositions(alerts_data.options.cell_length);

         var now=alerts_data.options.now_epoch;
        //now see if which specifical triangles must be drawn 
          if (alerts_data.options.prevision_triangle)
             draw_triangle('triangleLastObservation',alerts_data.options.last_observation,"#6D990C",alerts_data,triangle_data);
          if (alerts_data.options.now_triangle)
             draw_triangle('triangleToday',now,"#934CA0",alerts_data,triangle_data);  

    }
  
  /**
   * Simply generate the divs and appends to the alerts bar
   */
    function generateTriangleDiv(){
        
        $("#alerts_bar").append("<div id='triangleLastObservation' class='triangle triangle-last-observation relative'></div>");
        $("#alerts_bar").append("<div id='triangleToday' class='triangle triangle-now relative'></div>");
     
    }
    
    /**
     * Stablish initial position and cell separator of triangles depending on the cell length
     * @param {int} cell_length is the lenght of cells in milliepoch
     * @return {object} the initial position and separation between two cells. Values are ints but indicates percentatges
     */
    function obtainTrianglePositions(cell_length){
       
       var triangle_info=new Object();
       //switch the cell_lenght, and for each case determine initial position and separation between cells
           switch(cell_length){

                case 21600000:
                    triangle_info.initial_pos=12.83;
                    triangle_info.length=24;
                    break;
                case 43200000:
                    triangle_info.initial_pos=25.66;
                    triangle_info.length=48;
                    break;
                case 86400000:
                   triangle_info.initial_pos=51.32;
                    triangle_info.length=96;
                    break;
                case 600000:
                    triangle_info.initial_pos=3.25;
                    triangle_info.length=3.93;
                    break;
                case 360000:
                    triangle_info.initial_pos=2.5;
                    triangle_info.length=2.358;
                    break;
                case 300000:
                    triangle_info.initial_pos=2.2;
                    triangle_info.length=1.965;
                    break;
                case 900000:
                    triangle_info.initial_pos=4.4;
                    triangle_info.length=5.895;
                    break;
                default:
                    triangle_info.initial_pos=3.25;
                    triangle_info.length=3.93;
                    break;    

            }
        
        return triangle_info;
        
    }

/**
  * draw a canvas triangle
  * @param {string} div is the div where pain the triangle
  * @param {int} maxEpoch is the maximum epoch where the triangle is placed
  * @param {string} color is the color of the triangle
  * @param {object} alerts_data is the data of the alerts
  * @param {object} triangle_data is positon data about triangles
  */
   function draw_triangle(div, maxEpoch, color, alerts_data,triangle_data){

    var cdiv = $('#'+div);
    var canvas = construCanvas(cdiv);

        if (canvas.getContext){
            var context = canvas.getContext("2d");
            var width = canvas.width - 11;
            var height = canvas.height - 6;
            var padding = 3;
            context.fillStyle = color;
            context.strokeStyle = "white";
            // Draw a path
            context.beginPath();
            context.moveTo(padding + width/2, height - padding);
            context.lineTo(padding + width, padding );
            context.lineTo(padding, padding);
            context.closePath();
            // Fill the path
            context.fill();
            context.stroke();
            offset_triangle(div, maxEpoch, alerts_data,triangle_data);
        }
   }

/**
 * calculate the offset of the triangle depending on the maxEpoch stablished
 * @param {string} div is the div where the triangle is setted
 * @param {int} maxEpoch is the maximum epoch where the triangle is placed
 * @param {object} alerts_data is the data of the alerts
 * @param {object} triangle_data is positon data about triangles
 */
   function offset_triangle(div, maxEpoch, alerts_data,triangle_data){

    // calculate position: (epoch_triangle - start_epoch / cell_length)  
    var position = ((maxEpoch - alerts_data.options.start_epoch) / (alerts_data.options.cell_length) ) - 1; 
    
    //calculate left position: initialPosition + (separation_length * positions)
    var left= triangle_data.initial_pos + (triangle_data.length *  position);
    //finally move the triangle
    $('#'+div).css("left",left+"%")
   
   }
