"use strict";
/* All shared functionality to go in libtoaster object.
 * This object really just helps readability since we can then have
 * a traceable namespace.
 */
var libtoaster = (function (){

  /* makeTypeahead parameters
   * elementSelector: JQuery elementSelector string
   * xhrUrl: the url to get the JSON from expects JSON in the form:
   *  { "list": [ { "name": "test", "detail" : "a test thing"  }, .... ] }
   * xhrParams: the data/parameters to pass to the getJSON url e.g.
   *  { 'type' : 'projects' } the text typed will be passed as 'search'.
   *  selectedCB: function to call once an item has been selected one
   *  arg of the item.
   */
  function _makeTypeahead (jQElement, xhrUrl, xhrParams, selectedCB) {
    if (!xhrUrl || xhrUrl.length === 0)
      throw("No url to typeahead supplied");

    var xhrReq;

    jQElement.typeahead({
        source: function(query, process){
          xhrParams.search = query;

          /* If we have a request in progress don't fire off another one*/
          if (xhrReq)
            xhrReq.abort();

          xhrReq = $.getJSON(xhrUrl, this.options.xhrParams, function(data){
            if (data.error !== "ok") {
              console.log("Error getting data from server "+data.error);
              return;
            }

            xhrReq = null;

            return process(data.results);
          });
        },
        updater: function(item) {
          var itemObj = this.$menu.find('.active').data('itemObject');
          selectedCB(itemObj);
          return item;
        },
        matcher: function(item) {
          if (!item.hasOwnProperty('name')) {
            console.log("Name property missing in data");
            return 0;
          }

          if (this.$element.val().length === 0)
            return 0;

          return 1;
        },
        highlighter: function (item) {
          /* Use jquery to escape the item name and detail */
          var current = $("<span></span>").text(item.name + ' '+item.detail);
          current = current.html();

          var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
          return current.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
            return '<strong>' + match + '</strong>'
          })
        },
        sorter: function (items) { return items; },
        xhrUrl: xhrUrl,
        xhrParams: xhrParams,
        xhrReq: xhrReq,
    });


    /* Copy of bootstrap's render func but sets selectedObject value */
    function customRenderFunc (items) {
      var that = this;

      items = $(items).map(function (i, item) {
        i = $(that.options.item).attr('data-value', item.name).data('itemObject', item);
        i.find('a').html(that.highlighter(item));
        return i[0];
      });

      items.first().addClass('active');
      this.$menu.html(items);
      return this;
    }

    jQElement.data('typeahead').render = customRenderFunc;
  }

  /*
   * url - the url of the xhr build */
  function _startABuild (url, project_id, targets, onsuccess, onfail) {

    var data = {
      project_id : project_id,
      targets : targets,
    }

    $.ajax( {
        type: "POST",
        url: url,
        data: data,
        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
        success: function (_data) {
          /* No proper reponse YOCTO #7995
          if (_data.error !== "ok") {
            console.warn(_data.error);
          } else { */
            if (onsuccess !== undefined) onsuccess(_data);
        //  }
        },
        error: function (_data) {
          console.warn("Call failed");
          console.warn(_data);
          if (onfail) onfail(data);
    } });
  }

  /* cancelABuild:
   * url: projectbuilds
   * builds_ids: space separated list of build request ids
   * onsuccess: callback for successful execution
   * onfail: callback for failed execution
   */
  function _cancelABuild(url, build_ids, onsuccess, onfail){
    $.ajax( {
        type: "POST",
        url: url,
        data: { 'buildCancel': build_ids },
        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
        success: function (_data) {
          if (_data.error !== "ok") {
            console.warn(_data.error);
          } else {
            if (onsuccess !== undefined) onsuccess(_data);
          }
        },
        error: function (_data) {
          console.warn("Call failed");
          console.warn(_data);
          if (onfail) onfail(_data);
        }
    });
  }

  /* Get a project's configuration info */
  function _getProjectInfo(url, onsuccess, onfail){
    $.ajax({
        type: "GET",
        data : { format: "json" },
        url: url,
        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
        success: function (_data) {
          if (_data.error !== "ok") {
            console.warn(_data.error);
          } else {
            if (onsuccess !== undefined) onsuccess(_data);
          }
        },
        error: function (_data) {
          console.warn(_data);
          if (onfail) onfail(_data);
        }
    });
  }

  /* Properties for data can be:
   * layerDel (csv)
   * layerAdd (csv)
   * projectName
   * projectVersion
   * machineName
   */
  function _editCurrentProject(data, onSuccess, onFail){
    $.ajax({
        type: "POST",
        url: libtoaster.ctx.projectPageUrl + "?format=json",
        data: data,
        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
        success: function (data) {
          if (data.error != "ok") {
            console.log(data.error);
            if (onFail !== undefined)
              onFail(data);
          } else {
            if (onSuccess !== undefined)
              onSuccess(data);
          }
        },
        error: function (data) {
          console.log("Call failed");
          console.log(data);
        }
    });
  }

  function _getLayerDepsForProject(url, onSuccess, onFail){
    /* Check for dependencies not in the current project */
    $.getJSON(url,
      { format: 'json' },
      function(data) {
        if (data.error != "ok") {
          console.log(data.error);
          if (onFail !== undefined)
            onFail(data);
        } else {
          var deps = {};
          /* Filter out layer dep ids which are in the
           * project already.
           */
          deps.list = data.layerdeps.list.filter(function(layerObj){
            return (data.projectlayers.lastIndexOf(layerObj.id) < 0);
          });

          onSuccess(deps);
        }
      }, function() {
        console.log("E: Failed to make request");
    });
  }

  /* parses the query string of the current window.location to an object */
  function _parseUrlParams() {
    var string = window.location.search;
    string = string.substr(1);
    var stringArray = string.split ("&");
    var obj = {};

    for (var i in stringArray) {
      var keyVal = stringArray[i].split ("=");
      obj[keyVal[0]] = keyVal[1];
    }

    return obj;
  }

  /* takes a flat object and outputs it as a query string
   * e.g. the output of dumpsUrlParams
   */
  function _dumpsUrlParams(obj) {
    var str = "?";

    for (var key in obj){
      if (!obj[key])
        continue;

      str += key+ "="+obj[key].toString();
      str += "&";
    }

    /* Maintain the current hash */
    str += window.location.hash;

    return str;
  }

  function _addRmLayer(layerObj, add, doneCb){
    if (add === true) {
      /* If adding get the deps for this layer */
      libtoaster.getLayerDepsForProject(layerObj.layerdetailurl,
        function (layers) {

        /* got result for dependencies */
        if (layers.list.length === 0){
          var editData = { layerAdd : layerObj.id };
          libtoaster.editCurrentProject(editData, function() {
            doneCb([]);
          });
          return;
        } else {
          try {
            showLayerDepsModal(layerObj, layers.list, null, null,  true, doneCb);
          }  catch (e) {
            $.getScript(libtoaster.ctx.jsUrl + "layerDepsModal.js", function(){
              showLayerDepsModal(layerObj, layers.list, null, null,  true, doneCb);
            }, function(){
              console.warn("Failed to load layerDepsModal");
            });
          }
        }
      }, null);
    } else if (add === false) {
      var editData = { layerDel : layerObj.id };

      libtoaster.editCurrentProject(editData, function () {
        doneCb([]);
      }, function () {
        console.warn ("Removing layer from project failed");
        doneCb(null);
      });
    }
  }

  function _makeLayerAddRmAlertMsg(layer, layerDepsList, add) {
    var alertMsg;

    if (layerDepsList.length > 0 && add === true) {
      alertMsg = $("<span>You have added <strong>"+(layerDepsList.length+1)+"</strong> layers to your project: <a id=\"layer-affected-name\"></a> and its dependencies </span>");

      /* Build the layer deps list */
      layerDepsList.map(function(layer, i){
        var link = $("<a></a>");

        link.attr("href", layer.layerdetailurl);
        link.text(layer.name);
        link.tooltip({title: layer.tooltip});

        if (i !== 0)
          alertMsg.append(", ");

        alertMsg.append(link);
      });
    } else if (layerDepsList.length === 0 && add === true) {
      alertMsg = $("<span>You have added <strong>1</strong> layer to your project: <a id=\"layer-affected-name\"></a></span></span>");
    } else if (add === false) {
      alertMsg = $("<span>You have deleted <strong>1</strong> layer from your project: <a id=\"layer-affected-name\"></a></span>");
    }

    alertMsg.children("#layer-affected-name").text(layer.name);
    alertMsg.children("#layer-affected-name").attr("href", layer.layerdetailurl);

    return alertMsg.html();
  }

  function _showChangeNotification(message){
    var alertMsg = $("#change-notification-msg");

    alertMsg.html(message);
    $("#change-notification, #change-notification *").fadeIn();
  }


  return {
    reload_params : reload_params,
    startABuild : _startABuild,
    cancelABuild : _cancelABuild,
    makeTypeahead : _makeTypeahead,
    getProjectInfo: _getProjectInfo,
    getLayerDepsForProject : _getLayerDepsForProject,
    editCurrentProject : _editCurrentProject,
    debug: false,
    parseUrlParams : _parseUrlParams,
    dumpsUrlParams : _dumpsUrlParams,
    addRmLayer : _addRmLayer,
    makeLayerAddRmAlertMsg : _makeLayerAddRmAlertMsg,
    showChangeNotification : _showChangeNotification,
  };
})();

/* keep this in the global scope for compatability */
function reload_params(params) {
    var uri = window.location.href;
    var splitlist = uri.split("?");
    var url = splitlist[0];
    var parameters = splitlist[1];
    // deserialize the call parameters
    var cparams = [];
    if(parameters)
      cparams = parameters.split("&");

    var nparams = {};
    for (var i = 0; i < cparams.length; i++) {
        var temp = cparams[i].split("=");
        nparams[temp[0]] = temp[1];
    }
    // update parameter values
    for (i in params) {
        nparams[encodeURIComponent(i)] = encodeURIComponent(params[i]);
    }
    // serialize the structure
    var callparams = [];
    for (i in nparams) {
        callparams.push(i+"="+nparams[i]);
    }
    window.location.href = url+"?"+callparams.join('&');
}


/* Things that happen for all pages */
$(document).ready(function() {

  var ajaxLoadingTimer;

  /* If we don't have a console object which might be the case in some
     * browsers, no-op it to avoid undefined errors.
     */
    if (!window.console) {
      window.console = {};
      window.console.warn = function() {};
      window.console.error = function() {};
    }

    /*
     * PrettyPrint plugin.
     *
     */
    // Init
    prettyPrint();

    // Prevent invalid links from jumping page scroll
    $('a[href=#]').click(function() {
        return false;
    });


    /* START TODO Delete this section now redundant */
    /* Belen's additions */

    // turn Edit columns dropdown into a multiselect menu
    $('.dropdown-menu input, .dropdown-menu label').click(function(e) {
        e.stopPropagation();
    });

    // enable popovers in any table cells that contain an anchor with the
    // .btn class applied, and make sure popovers work on click, are mutually
    // exclusive and they close when your click outside their area

    $('html').click(function(){
        $('td > a.btn').popover('hide');
    });

    $('td > a.btn').popover({
        html:true,
        placement:'left',
        container:'body',
        trigger:'manual'
    }).click(function(e){
        $('td > a.btn').not(this).popover('hide');
        // ideally we would use 'toggle' here
        // but it seems buggy in our Bootstrap version
        $(this).popover('show');
        e.stopPropagation();
    });

    // enable tooltips for applied filters
    $('th a.btn-primary').tooltip({container:'body', html:true, placement:'bottom', delay:{hide:1500}});

    // hide applied filter tooltip when you click on the filter button
    $('th a.btn-primary').click(function () {
        $('.tooltip').hide();
    });

    // enable help information tooltip
    $(".get-help").tooltip({container:'body', html:true, delay:{show:300}});

    // show help bubble only on hover inside tables
    $(".hover-help").css("visibility","hidden");
    $("th, td").hover(function () {
        $(this).find(".hover-help").css("visibility","visible");
    });
    $("th, td").mouseleave(function () {
        $(this).find(".hover-help").css("visibility","hidden");
    });

    /* END TODO Delete this section now redundant */

    // show task type and outcome in task details pages
    $(".task-info").tooltip({ container: 'body', html: true, delay: {show: 200}, placement: 'right' });

    // initialise the tooltips for the icon-pencil icons
    $(".icon-pencil").tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" });

    // initialise the tooltips for the download icons
    $(".icon-download-alt").tooltip({ container: 'body', html: true, delay: { show: 200 } });

    // initialise popover for debug information
    $(".icon-info-sign").popover( { placement: 'bottom', html: true, container: 'body' });

    // linking directly to tabs
    $(function(){
          var hash = window.location.hash;
          $('ul.nav a[href="' + hash + '"]').tab('show');

          $('.nav-tabs a').click(function () {
            $(this).tab('show');
            $('body').scrollTop();
          });
    });

    // toggle for long content (variables, python stack trace, etc)
    $('.full, .full-hide').hide();
    $('.full-show').click(function(){
        $('.full').slideDown(function(){
            $('.full-hide').show();
        });
        $(this).hide();
    });
    $('.full-hide').click(function(){
        $(this).hide();
        $('.full').slideUp(function(){
            $('.full-show').show();
        });
    });

    //toggle the errors and warnings sections
    $('.show-errors').click(function() {
        $('#collapse-errors').addClass('in');
    });
    $('.toggle-errors').click(function() {
        $('#collapse-errors').toggleClass('in');
    });
    $('.show-warnings').click(function() {
        $('#collapse-warnings').addClass('in');
    });
    $('.toggle-warnings').click(function() {
        $('#collapse-warnings').toggleClass('in');
    });
    $('.show-exceptions').click(function() {
        $('#collapse-exceptions').addClass('in');
    });
    $('.toggle-exceptions').click(function() {
        $('#collapse-exceptions').toggleClass('in');
    });


    $("#hide-alert").click(function(){
      $(this).parent().fadeOut();
    });

    //show warnings section when requested from the previous page
    if (location.href.search('#warnings') > -1) {
        $('#collapse-warnings').addClass('in');
    }

    /* Show the loading notification if nothing has happend after 1.5
     * seconds
     */
    $(document).bind("ajaxStart", function(){
      if (ajaxLoadingTimer)
        window.clearTimeout(ajaxLoadingTimer);

      ajaxLoadingTimer = window.setTimeout(function() {
        $("#loading-notification").fadeIn();
      }, 1200);
    });

    $(document).bind("ajaxStop", function(){
      if (ajaxLoadingTimer)
        window.clearTimeout(ajaxLoadingTimer);

      $("#loading-notification").fadeOut();
    });

    $(document).ajaxError(function(event, jqxhr, settings, errMsg){
      if (errMsg === 'abort')
        return;

      console.warn("Problem with xhr call");
      console.warn(errMsg);
      console.warn(jqxhr.responseText);
    });

    function check_for_duplicate_ids () {
      /* warn about duplicate element ids */
      var ids = {};
      $("[id]").each(function() {
        if (this.id && ids[this.id]) {
          console.warn('Duplicate element id #'+this.id);
        }
        ids[this.id] = true;
      });
    }

    if (libtoaster.debug) {
      check_for_duplicate_ids();
    } else {
      /* Debug is false so supress warnings by overriding the functions */
      window.console.warn = function () {};
      window.console.error = function () {};
   }
});
