/**
 * Uses zoomleven and mouseposition to call nodelist.py view.
 * View returns nodes in json format, values are printed in doc element.
 */
function getNodeList(zoomlevel, mousepos){
  $.getJSON("nodelist/" + zoomlevel + "," + mousepos.lat + "," + mousepos.lon, 
    function(json){
      content = 'Wireless Leiden nodes on mouseposition:<br /><b>';
      $.each(json, function(i,json){
        content += json.fields.ssid + '<br />';
      });
      content += '</b>';
      $("#node_list").html(content);
    }
  );
}

/**
 * Right way to get url parameters?
 * http://stackoverflow.com/questions/1403888/get-url-parameter-with-jquery/1404100#1404100
 */
function getURLParameter(name) {
  return decodeURI(
    (RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
  );
}

$(document).ready(function() {
  var signallayer = '';
  var userlist = new Array();
  var nodelist = new Array();

  /**
   * Adds colourpicker for layer colour.
   * Function set in: 'colourpicker.js'
   */
  $("#colour").colorPicker();

  /**
   * Adds datepicker for start & end date
   * Function set in: 'jquery-ui-1.8.13.custom.min.js'
   */
  $("#start_date").datepicker({
    dateFormat: "dd/mm/yy",
    onSelect: function(dateValue, inst){
      $("#end_date").datepicker("option", "minDate", dateValue);
    }
  });
  $("#end_date").datepicker({
    dateFormat: "dd/mm/yy"
  });

  /**
   * Adds slider for signal strength layer.
   * Function set in: 'jquery-ui-1.8.13.custom.min.js'
   */
  function update_slider(min,max) {
      $("#sig_value").text("All AccessPoints Signal Strength: " + min + " - " + max);
      $("#signallayer font").text("All AccessPoints Signal: " + min + " - " + max);
  };

  function update_sig_slider(min,max) {
      $("#select_sig_value").text("Signal Strength: " + min + " - " + max);
  };

  $("#slider").slider({
    range: true,
    min: 0,
    max: 100,
    values: [0, 100],
    // while sliding, it changes the text above the slider to show the values realtime
    slide: function(event, sig){
      update_slider(sig.values[0], sig.values[1]);
    },
    // on slider stop, it sets a new URL with updated values and redraws the layer
    stop: function(event, sig){
      signallayer = map.getLayersByName('signallayer');
      signallayer[0].setUrl("tile/${z}/${x},${y}.png?colour=90,90,90&signaal__gte=" + sig.values[0] + "&signaal__lte=" + sig.values[1]);
      signallayer[0].redraw();
    }
  });
  $("#select_sig_slider").slider({
    range: true,
    min: 0,
    max: 100,
    values: [0,100],
    // while sliding, it changes the text above the slider to show the values realtime
    slide: function(event, sig){
      update_sig_slider(sig.values[0], sig.values[1]);
    }
  });


  function init_slider(min, max) {
    $("#slider").slider( "option", "values", [min,max] );
    signallayer = map.getLayersByName('signallayer');
    signallayer[0].setUrl("tile/${z}/${x},${y}.png?colour=90,90,90&signaal__gte=" + min + "&signaal__lte=" + max);
    signallayer[0].redraw();
    update_slider(min,max);

    $("#select_sig_slider").slider( "option", "values", [min,max] );
    update_sig_slider(min,max);
  };



  /**
   * Toggles layer visibility on checkbox use from layerswitcher.
   */
  $("#togglelayer").live('click', function(){
    layername = $(this).parents('span').attr('id');
    layer = map.getLayersByName(layername);
    if(this.checked){
      layer[0].setVisibility(true);
    }
    else{
      layer[0].setVisibility(false);
    }
  }); 

  /**
   * Toggles layer visibility per category on checkbox use from layerswitcher.
   */
  $("#togglecat").live("click", function(){
    layertype = $(this).attr('class');
    layers = new Array();
    layers = $('#' + layertype).children('span');
    if(this.checked){
      $.each(layers, function(l, layer){
        layer = map.getLayersByName(layer.id);
        layer[0].setVisibility(true);
        $(this).children('input').attr('checked', true);  
      });
    }
    else{
      $.each(layers, function(l, layer){
        layer = map.getLayersByName(layer.id);
        layer[0].setVisibility(false);
        $(this).children('input').attr('checked', false);  
      });
    }
  });

  /**
   * Removes layer from map and layerswitcher.
   */
  $("#rmvlayer").live("click", function(){
    layername = $(this).closest('span').attr('id');
    layer = map.getLayersByName(layername);
    map.removeLayer(layer[0]);
    $(this).closest('span').remove();
  });

  /**
   * Toggles text shown on website.
   * 'info' shows info text.
   * 'filter' page shows text on filters & filter options.
   */
  $("#menu_filter").click(function(){
    $("#filter").slideToggle("fast");
    $("#info").slideUp("fast");
  });
  $("#menu_info").click(function(){
    $("#filter").slideUp("fast");
    $("#info").slideToggle("fast"); 
  });
  $("#hide_parent").live("click",function(){
    parent = $(this).parent("div");
    $(parent).slideUp("fast");
  });
  


  /**
   * Toggles layerswitcher visibility.
   * On 'off', toggler shows a '+'.
   * On 'on', toggler shows a '-'.
   */
  $("#layer_switcher_toggle").click(function(){
    $("#layer_switcher").toggle();
    if($(this).text() == '+'){
      $(this).html('-');
    }
    else{
      $(this).html('+');
    }
  });

  /**
   * Toggles category visibility.
   * On 'visible', toggler shows a '^'.
   * On 'invisible', toggler shows a 'v'.
   */
  $("#cat_hide").live("click", function(){
    cat = $(this).parent('div').next('p').children('span')
    cat.toggle();
    if(cat.is(":visible")){
      //FIXME: images are getting loaded the hard way. Replace '/static/'. '{{ STATIC_URL }}' doesn't seem to work here.
      $(this).css('background-image', "url(/static/img/up.png)");
    }
    else{
      $(this).css('background-image', "url(/static/img/down.png)");
    }
  });

  /**
   * Fastest?
   * http://stackoverflow.com/questions/170986/what-is-the-best-way-to-add-options-to-a-select-from-an-array-with-jquery
   */
  $.getJSON("filters/",
    function(json) {
      $.each(json, function(i,json){
        $("#select_user").append($("<option/>").attr("value",json.gebruiker).text(json.gebruiker));
        userlist.push(json.gebruiker);
        $.each(json.meetrondje, function(m, meetrondje){
          $("#select_dataset").append($("<option/>").attr({"class":json.gebruiker, "value": json.gebruiker + "-" + meetrondje.naam}).text(meetrondje.naam));
          $.each(meetrondje.nodes, function(n, nodes){
            $("#select_node").append($("<option/>").attr({"class":json.gebruiker + "-" + meetrondje.naam, "value":nodes}).text(nodes));
            if(jQuery.inArray(nodes, nodelist)<0){
              nodelist.push(nodes);
            }
          });
        });
      });
    // Initiate the chain
    $("#select_dataset").chained("#select_user");
    $("#select_node").chained("#select_dataset");
    }
  );

  /**
   * Earlier process got all users in JSON and put them in array.
   * For each user in array, new layer is added with username as parameter.
   * Layercolour is randomized.
   * If button is pressed again, layers will be deleted.
   */
  function update_lname() {
     $("#lname").val($("#select_user option:selected").text() + " - " + $("#select_dataset option:selected").text() + " - " + $("#select_node option:selected").text());
  }
  $("#select_user").change(function(){
    update_lname();
  });
  $("#select_dataset").change(function(){
    update_lname();
  });
  $("#select_node").change(function(){
    update_lname();
  });

  $('#user_filter').click(function(){
    if(this.text=='(Add all users)'){
      $.each(userlist, function(u, user){
        colour = Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256);
        OpenLayers.Layer.OSM.Overlay = OpenLayers.Class(OpenLayers.Layer.OSM, {
          initialize: function(name, options) {
            var url = [
              "tile/${z}/${x},${y}.png?&colour=" + colour + "&meetrondje__gebruiker__naam=" + user
            ];
            options = OpenLayers.Util.extend({ numZoomLevels: 21 }, options);
            var newArguments = [name, url, options];
            OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
          },
        CLASS_NAME: "OpenLayers.Layer.Overlay"
        });
        filterlayer = new OpenLayers.Layer.OSM.Overlay(user, {isBaseLayer: false, visibility: true});
        map.addLayer(filterlayer);
        $("#user").append("<span id=\"" + user + "\"><div id='layer_switcher_colour' style='background-color:rgb(" + colour + ")' /><input type=checkbox id=togglelayer checked /><font>" + user + " </font><a id=rmvlayer>X</a><br /></span>");
      });
      $(this).text('(Del all users');
    }
    else{
      $(this).text('(Add all users)');
      $.each($('#user span'), function(s, span){
        layer = map.getLayersByName(span.id);
        map.removeLayer(layer[0]);
        $(span).remove();
      });
    }
  });

  /**
   * Earlier process got all nodes in JSON and put them in array.
   * For each node in array, new layer is added with node as parameter.
   * Layercolour is randomized.
   * If button is pressed again, layers will be deleted.
   */
  $('#node_filter').click(function(){
    if(this.text=='(Add all nodes)'){
      $.each(nodelist, function(n, node){
        colour = Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256);
        OpenLayers.Layer.OSM.Overlay = OpenLayers.Class(OpenLayers.Layer.OSM, {
          initialize: function(name, options) {
            var url = [
              "tile/${z}/${x},${y}.png?&colour=" + colour + "&accespoint__ssid=" + node
            ];
            options = OpenLayers.Util.extend({ numZoomLevels: 21 }, options);
            var newArguments = [name, url, options];
            OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
          },
        CLASS_NAME: "OpenLayers.Layer.Overlay"
        });
        nodefilterlayer = new OpenLayers.Layer.OSM.Overlay(node, {isBaseLayer: false, visibility: true});
        map.addLayer(nodefilterlayer);
        $("#node").append("<span class='node' id=\"" + node + "\"><div id='layer_switcher_colour' style='background-color:rgb(" + colour + ")' /><input type=checkbox id=togglelayer checked /><font>" + node + " </font><a id=rmvlayer>X</a><br /></span>");
      });
      $(this).text('(Del all nodes)');
    }
    else{
      $(this).text('(Add all nodes)');
      $.each($('#node span'), function(s, span){
        layer = map.getLayersByName(span.id);
        map.removeLayer(layer[0]);
        $(span).remove();
      });
    }
  });

  /**
   * Adds a new layer when clicked.
   * Filters set by user are used as layer parameters.
   * Colour is either chosen or randomized.
   * Blank parameters are ignored.
   */
  $('#add_filter').click(function(){
    // get values from elements
    user = $('#select_user option:selected').text();
    dataset = $('#select_dataset option:selected').text();
    wlnode = $('#select_node option:selected').text();
    start_date = $('#start_date').val();
    end_date = $('#end_date').val();
    colour = $("#colour").val();
    lname = $("#lname").val();

    /**
     * On HEX to RGB:
     * http://stackoverflow.com/questions/5798868/need-some-tips-with-how-to-convert-a-hexadecimal-color-value-to-a-rgb-one/5798900#5798900
     * Note that '#' comes out as '%23', so substr() starts at char 3
     */
    colour = parseInt((colour.substr(3, 2)),16) + ',' + parseInt((colour.substr(5, 2)),16) + ',' + parseInt((colour.substr(7, 2)),16);

    // some checks if values are correct, and adding them to parts of the link
    if (user == 'all') {
      user = '';
    } else {
      user='&meetrondje__gebruiker__naam='+user;
    }
    if (dataset == 'all') {
      dataset = '';
    } else {
      dataset='&meetrondje__naam='+dataset;
    }
    if (wlnode == 'all'){
      wlnode='';
    } else {
      wlnode='&accespoint__ssid='+wlnode;
    }
    if (start_date && end_date){
      sd_d=start_date.substr(0,2);
      sd_m=start_date.substr(3,2);
      sd_y=start_date.substr(6,4);

      ed_d=end_date.substr(0,2);
      ed_m=end_date.substr(3,2);
      ed_y=end_date.substr(6,4);

      start_date='&meetrondje__datum__gte=' + sd_y +'-'+ sd_m +'-'+ sd_d;
      end_date='&meetrondje__datum__lte=' + ed_y +'-'+ ed_m +'-'+ ed_d;
    }
    if (start_date && !end_date){
      sd_d=start_date.substr(0,2);
      sd_m=start_date.substr(3,2);
      sd_y=start_date.substr(6,4);
      start_date='&meetrondje__datum__gte=' + sd_y +'-'+ sd_m +'-'+ sd_d;
      end_date='';
    }
    if (!start_date && end_date){
      ed_d=end_date.substr(0,2);
      ed_m=end_date.substr(3,2);
      ed_y=end_date.substr(6,4);
      start_date='';
      end_date='&meetrondje__datum__lte=' + ed_y +'-'+ ed_m +'-'+ ed_d;
    }
    if (colour != 'NaN,NaN,NaN'){
      colour=colour;
    } else {
      colour = Math.floor(Math.random()*256)+','+Math.floor (Math.random()*256)+','+Math.floor(Math.random()*256);
    }
    if (lname == ''){
      lname= 'Custom Filter';
    }

    var min = $("#select_sig_slider").slider("values")[0];
    var max = $("#select_sig_slider").slider("values")[1];
    signal = '&signaal__gte=' + min + '&signaal__lte=' + max;

    // setting layer
    OpenLayers.Layer.OSM.Overlay = OpenLayers.Class(OpenLayers.Layer.OSM, {
      initialize: function(name, options) {
        var url = [
          "tile/${z}/${x},${y}.png?colour=" + colour + user + dataset + wlnode + start_date + end_date + signal
        ];
        options = OpenLayers.Util.extend({ numZoomLevels: 21 }, options);
        var newArguments = [name, url, options];
        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
      },

    CLASS_NAME: "OpenLayers.Layer.Overlay"
    });

    // adding layer
    filterlayer = new OpenLayers.Layer.OSM.Overlay(lname, {isBaseLayer: false, visibility: true});
    map.addLayer(filterlayer);

    $("#custom").append("<span id=\"" + lname + "\"><div id='layer_switcher_colour' style='background-color:rgb(" + colour + ")' /><input type=checkbox id=togglelayer checked /><font>" + lname + " </font><a id=rmvlayer>X</a><br /></span>");
  });
  init_heatmap();
  init_slider(35,75);
});
