var taskStatus = {'Stand':'Stand',
    'Table ronde':'Table-ronde',
    'Atelier':'Atelier', 
    'Concert':'Concert', 
    'Conference':'Conference', 
    'Repas':'Repas'};
var tickFormat = "%H:%M";
var margin = {
    top : 15, 
    right : 0,
    bottom : 0, 
    left : 50
};
var height = 500;
var width = 730;
var Keys = Array();
var Salles = Array();
var Areas = Array();
var Tasks = Array();


d3.json("le-prog-json",
    function(error, json) {
        if (error) return console.warn(error);
        var Keys = Object.keys(json["all"]);
        // Build set of data in memory
        for (var k = 0; k < Keys.length; k++) {
            Salles[Keys[k]] = Array();
            Areas[Keys[k]] = Array();
            Tasks[Keys[k]] = json["all"][Keys[k]];
            // Fix Json to make date objects
            Tasks[Keys[k]].forEach(function(d) {
                d.startDate = new Date(d.startDate);
                d.endDate = new Date(d.endDate);
            });

            // Build the list of Salles and Areas
            Tasks[Keys[k]].forEach(function(d) {
                Salles[Keys[k]].push( d.placeName );
                Areas[Keys[k]].push( d.status );
            } );
            Salles[Keys[k]] = d3.set(Salles[Keys[k]]).values();
            Areas[Keys[k]] = d3.set(Areas[Keys[k]]).values();
            // Create Controls to Handle user selection
            Areas[Keys[k]].forEach(function(TypeArea) {
                d3.select("#Schedule_SVG_"+Keys[k])
                    .append("input")
                    .attr("type", "checkbox")
                    .attr("name", "OptTimetable-"+Keys[k])
                    .attr("id", TypeArea+"-"+Keys[k])
                    .attr("area", TypeArea)
                    .style("float", "left")
                    .style("margin-left", "20px")
                    .style("margin-right", "3px")
                    .property("checked",true);
                
                d3.select("#Schedule_SVG_"+Keys[k])
                    .append("label")
                    .attr("for", TypeArea+"-"+Keys[k])
                    .style("float", "left")
                    .style("margin-left", "5px")
                    .text(TypeArea);
            });
            
			d3.select("#Schedule_SVG_"+Keys[k])
                    .append("br");
            
            // Create a dedicated SVG for it 
            svg = d3.select("#Schedule_SVG_"+Keys[k])
                .append("svg")
                .attr("id", "TimeTable-"+Keys[k])
                .attr("width", "100%") //width + margin.right + margin.left)
                //.attr("height", height + margin.top + margin.bottom)
                .attr("viewBox", "0 0 " + (width + margin.right + margin.left) + " " + (height + margin.top + margin.bottom) )
                .attr("preserveAspectRatio", "xMidYMid meet");
            // Add some gradient
			header(svg, Keys[k]);
			// Create axis
            svg.append("g")
                .attr("class", "xAxis axis");
             
            svg.append("g")
                .attr("class", "yAxis axis");
        
            var chart = svg.append("g")
                .attr("class", "timetable");

            HandleEvents(Keys[k]);
            displayit(json["all"][Keys[k]], Salles[Keys[k]], Keys[k]);
        }
});

function header(svg, day) {
	defs = svg.append("svg:defs");
	
	conf = defs.append("svg:linearGradient")
	    .attr("id", "BoxGradient-Conference-"+day)
	    .attr("x1", "100%")
	    .attr("y1", "0%")
	    .attr("x2", "50%")
	    .attr("y2", "100%")
	    .attr("spreadMethod", "pad");

	conf.append("svg:stop")
	    .attr("offset", "0%")
	    .attr("stop-color", "#EEE")
	    .attr("stop-opacity", 0);
	
	conf.append("svg:stop")
	    .attr("offset", "15%")
	    .attr("stop-color", "#BDF86B")
	    .attr("stop-opacity", .5);
	    
	atlier = defs.append("svg:linearGradient")
	    .attr("id", "BoxGradient-Atelier-"+day)
	    .attr("x1", "100%")
	    .attr("y1", "0%")
	    .attr("x2", "50%")
	    .attr("y2", "100%")
	    .attr("spreadMethod", "pad");

	atlier.append("svg:stop")
	    .attr("offset", "0%")
	    .attr("stop-color", "#EEE")
	    .attr("stop-opacity", 0);
	
	atlier.append("svg:stop")
	    .attr("offset", "15%")
	    .attr("stop-color", "#FF856E")
	    .attr("stop-opacity", .5);	    

	tabler = defs.append("svg:linearGradient")
	    .attr("id", "BoxGradient-Table-ronde-"+day)
	    .attr("x1", "100%")
	    .attr("y1", "0%")
	    .attr("x2", "50%")
	    .attr("y2", "100%")
	    .attr("spreadMethod", "pad");

	tabler.append("svg:stop")
	    .attr("offset", "0%")
	    .attr("stop-color", "#EEE")
	    .attr("stop-opacity", 0);
	
	tabler.append("svg:stop")
	    .attr("offset", "15%")
	    .attr("stop-color", "#B59EFF")
	    .attr("stop-opacity", .5);
	    

	undef = defs.append("svg:linearGradient")
	    .attr("id", "BoxGradient-undefined-"+day)
	    .attr("x1", "100%")
	    .attr("y1", "0%")
	    .attr("x2", "50%")
	    .attr("y2", "100%")
	    .attr("spreadMethod", "pad");

	undef.append("svg:stop")
	    .attr("offset", "0%")
	    .attr("stop-color", "#EEE")
	    .attr("stop-opacity", 0);
	
	undef.append("svg:stop")
	    .attr("offset", "15%")
	    .attr("stop-color", "#359E35")
	    .attr("stop-opacity", .5);


	// append filter element
	var filter = defs.append( 'filter' )
	    .attr( 'id', 'dropshadow-'+day ); /// !!! important - define id to reference it later
	
	// append gaussian blur to filter
	filter.append( 'feGaussianBlur' )
	      .attr( 'in', 'SourceAlpha' )
	      .attr( 'stdDeviation', 3 ) // !!! important parameter - blur
	      .attr( 'result', 'blur' );
	
	// append offset filter to result of gaussion blur filter
	filter.append( 'feOffset' )
	      .attr( 'in', 'blur' )
	      .attr( 'dx', 2 ) // !!! important parameter - x-offset
	      .attr( 'dy', 2 ) // !!! important parameter - y-offset
	      .attr( 'result', 'offsetBlur' );

	filter.append( 'feComponentTransfer' )
		  .append( 'feFuncA' )
		  .attr( "type", "linear" )
		  .attr( "slope", "0.4" );
	
	// merge result with original image
	var feMerge = filter.append( 'feMerge' );
	
	// first layer result of blur and offset
	feMerge.append( 'feMergeNode' )
	       .attr( 'in", "offsetBlur' );
	
	// original image on top
	feMerge.append( 'feMergeNode' )
	       .attr( 'in', 'SourceGraphic' );
	// end filter stuff

}


var keyFunction = function(d) {
    return d.startDate + d.placeName + d.endDate;
};

function HandleEvents(Ctrl) {
    d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")
        .data(Areas[Ctrl])
        .on("change", function(TypeData) {
            ArrayChoice = Array();
            checked = d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")[0]
                .forEach( function(v)
                    {
                    if (d3.select(v).node().checked)
                        ArrayChoice.push(v.attributes['area'].value);
                    }
               );
            area_select = Array();
            selection = Tasks[Ctrl].filter(function(v) {
                return ArrayChoice.indexOf(v.status)>=0;
            });
            if (selection.length) {
                selection.forEach(function(d)
                    { area_select.push( d.placeName ); }
                );
                area_select = d3.set(area_select).values();
                displayit(selection, area_select, Ctrl);
                d3.select("#TimeTable-"+Ctrl)[0][0].style.opacity = 1;
            } else {
                d3.select("#TimeTable-"+Ctrl)[0][0].style.opacity = 0;
            }   
        });
}


function displayit(Set_of_Task, Set_of_Area, key) {
        // Try to compute time range
        Set_of_Task.sort(function(a, b) {
            return a.startDate - b.startDate;
        });
        timeDomainStart = Set_of_Task[0].startDate;
        Set_of_Task.sort(function(a, b) {
            return a.endDate - b.endDate;
        });
        timeDomainEnd = Set_of_Task[Set_of_Task.length - 1].endDate;

        // Prepare scales
        xScale = d3.scale.ordinal()
            .domain(Set_of_Area)
            .rangeRoundBands([ 0, width ], .1);    
      
        yScale = d3.time.scale()
            .domain([ timeDomainStart, timeDomainEnd ])
            .range([ 0, height - margin.top - margin.bottom ])
            .clamp(true);    

        xAxis = d3.svg.axis()
            .scale(xScale)
            .orient("top")
            .tickSize(1);

        yAxis = d3.svg.axis()
            .scale(yScale)
            .orient("left")
            .tickFormat(d3.time.format(tickFormat))
            .tickSubdivide(true)
            .tickSize(8)
            .tickPadding(8);

        var svg = d3.select("#TimeTable-"+key);
        
        var chart = svg.select(".timetable");

        var rect = chart.selectAll("rect")
            .data(Set_of_Task, keyFunction);
        
        rect.enter()
            .insert("rect")
            .attr("rx", 5)
            .attr("ry", 5)
            .attr("filter", "url(#dropshadow-" + key + ")")
            .style("fill", function(d){
            	return "url(#BoxGradient-"+ taskStatus[d.status] + "-" + key + ")";
            })
            .attr("class", function(d){ 
                 if(taskStatus[d.status] == null)
                    { return "bar";}
                 return taskStatus[d.status];
                })
            .transition()
            .duration(750);


        rect.transition()
            .duration(750)
            .attr("x", function(d){ 
                return xScale(d.placeName || "unk");
                 })
            .attr("y", function(d){ 
                return yScale( d.startDate )+1;
                 })
            .attr("width", function(d) { 
                return xScale.rangeBand(); 
                 })
            .attr("height", function(d) { 
                return (yScale( d.endDate ) - yScale( d.startDate )-2);
                 });
        
        rect.exit()
            .transition()
            .duration(300)
            .style("opacity", 1e-6)
            .remove();

        var content = chart.selectAll("foreignObject")
            .data(Set_of_Task, keyFunction);        

        content.enter()
            .insert("foreignObject")
            .append("xhtml:div")
            .attr("class", "SvgBody")
            .html(function(d) { 
                return '<div class="EvtBox '+ taskStatus[d.status] +'"><a href="/event/'+ d.uid +
                    '">' + d.desc + '</a></div>';
                 })
            .transition()
            .duration(750);
        
        content.transition()
            .duration(750)
            .attr("x", function(d){ 
                return xScale(d.placeName || "unk");
                 })
            .attr("y", function(d){ 
                return yScale( d.startDate );
                 })
            .attr("width", function(d) { 
                return xScale.rangeBand(); 
            })
            .attr("height", function(d) { 
                return (yScale( d.endDate ) - yScale( d.startDate ));
            });
//            .attr("transform" ,"scale(1)");

        content.exit()
            .transition()
            .duration(300)
            .style("opacity", 1e-6)
            .remove();

        svg.select(".yAxis")
            .attr("transform", "translate("+ margin.left +","+ margin.top +")")
            .transition()
            .call(yAxis);
    
        svg.select(".xAxis")
            .attr("transform", "translate("+ margin.left +","+ margin.top +")")
            .transition()
            .call(xAxis);

        chart.attr("transform", "translate("+ margin.left +","+ margin.top +")");     
}