'use strict';

/*
 * *******************************************************************************
 *  * Copyright (c) 2018 Edgeworx, Inc.
 *  *
 *  * This program and the accompanying materials are made available under the
 *  * terms of the Eclipse Public License v. 2.0 which is available at
 *  * http://www.eclipse.org/legal/epl-2.0
 *  *
 *  * SPDX-License-Identifier: EPL-2.0
 *  *******************************************************************************
 *
 */

var gridSize = 20;
var accTok = apwGetAccessToken();

function activateElementsDraggable(elementId) {
  var div = $('div[data-element-id=\'' + elementId + '\']');
  div.draggable({
    helper: 'original',
    opacity: 0.8,
    delay: 200,
    revert: 'invalid',
    revertDuration: 400,
    scroll: true,
    containment: 'parent',
    zIndex: 99999,
    start: function start(event, ui) {
      $('.element-toolbox').css({ 'overflow-x': '', 'overflow-y': '' });
    },
    stop: function stop(event, ui) {
      $('.element-toolbox').css({ 'overflow-x': 'scroll', 'overflow-y': 'scroll' });
    },
    drag: function drag(event, ui) {
      var topRemainder = ui.position.top % gridSize;
      var leftRemainder = ui.position.left % gridSize;

      if (ui.position.left > 0) {
        ui.position.top = ui.position.top - topRemainder;
        ui.position.left = ui.position.left - leftRemainder;
      }
    }
  });

  $('.element-canvas').css({ 'overflow-x': 'scroll', 'overflow-y': 'scroll' });
}

function activateHandlersForPublishingInterface() {
  //Set up the handlers and immediate actions
  $('.element-type-container').draggable({
    helper: 'clone',
    opacity: 0.8,
    delay: 200,
    revert: 'invalid',
    revertDuration: 400,
    scroll: true,
    zIndex: 99999,
    start: function start(event, ui) {
      $('.element-toolbox').css({ 'overflow-x': '', 'overflow-y': '' });
    },
    stop: function stop(event, ui) {
      $('.element-toolbox').css({ 'overflow-x': 'scroll', 'overflow-y': 'scroll' });
    },
    drag: function drag(event, ui) {
      var canvasX = $('.element-canvas').offset().left;

      var topRemainder = ui.position.top % gridSize;
      var leftRemainder = ui.position.left % gridSize;

      if (ui.position.left > canvasX) {
        ui.position.top = ui.position.top - topRemainder;
        ui.position.left = ui.position.left - leftRemainder;
      }
    }
  });

  $('.element-canvas').droppable({
    drop: handleElementTypeDropOnCanvas
  });

  //This is a hack to work around a scrolling issue with draggable. We will make the toolbar on the left become
  //scrollable AFTER the draggable handler has been added to the toolbar items.
  $('.element-toolbox').css({ 'overflow-x': 'scroll', 'overflow-y': 'scroll' });

  //Submit the file upload form when the button is clicked
  $('#element-icon-upload-button').click(function () {
    $('#photo_upload').submit();
  });

  //Bind the submission of the file upload form to this function
  $('#photo_upload').submit(function () {
    //alert("1");
    var curToken = apwGetAccessToken();
    $('#file-upload-access-token-holder').val(curToken);
    //alert("2");
    var formData = new FormData(this);
    //alert("3");
    //var url = "/api/v2/authoring/element/icon/upload/moduleid/" + $("#file-upload-module-id").val();
    //alert("4");
    $.ajax({
      url: $(this).attr('action'),
      type: 'POST',
      data: formData,
      dataType: 'json',
      async: true,
      success: function success(data) {

        if (data.status != 'ok') {
          Materialize.toast(data.error, 5000);
          return;
        }
        var elementId = $('#file-upload-module-id').val();
        var img = $('div[data-element-id=\'' + elementId + '\'] > img');
        var filename = data.fileName;

        img.attr('src', '/' + filename + '?' + new Date().getTime());
        img.attr('filename', filename);
        saveElementData();
      },
      cache: false,
      contentType: false,
      processData: false
    });

    //Prevent the page from refreshing
    return false;
  });

  $('#delete-confirm-modal-yes-button').click(function () {
    $('#deleteconfirmmodal').closeModal();
    var element = $('.element-container.element-selected');
    var url = fogControllerUrl + ioAuthoring.urls.deleteElement + element.attr('data-element-id') + '?t=' + accTok;
    $.ajax({
      type: 'GET',
      url: url,
      dataType: 'json',
      data: {},
      success: function success(data) {
        element.remove();
        deleteElementLayout(data.moduleId);

        var instance = $('.element-container');
        var id = instance.attr('data-element-id');
        if (id != undefined) {
          scrollToInstance(instance);
          selectElement(id);
        } else {
          $('#element-properties-name').val('');
          $('#element-properties-description').val('');
          $('#element-properties-category').val('');
          $('#element-properties-containerimage-x86').val('');
          $('#element-properties-containerimage-arm').val('');
          $('#element-properties-publisher').val('');
          $('#element-properties-diskrequired').val('');
          $('#element-properties-ramrequired').val('');
          $('#element-properties-inputinfotype').val('');
          $('#element-properties-inputinfoformat').val('');
          $('#element-properties-outputinfotype').val('');
          $('#element-properties-outputinfoformat').val('');
          $('#element-properties-configform').val('');
          $('#dockerRegistrySelect').val(1);
          $('#dockerRegistrySelect').material_select();
        }
      }
    });
  });

  $('input[type=text]').blur(function () {
    saveElementData();
  });

  $('#element-properties-configform').blur(function () {
    saveElementData();
  });

  $('#dockerRegistrySelect').change(function () {
    if ($(this).val() !== 'add') {
      saveElementData();
    } else {
      $('#dockerRegistrySelect').val(window.registry);
      $('#dockerRegistrySelect').material_select();
      checkIsPublicAddRegistryElement();
      $('#addRegistryModal').openModal();
    }
  });

  $('#addRegistryIsPublicField').change(function (event) {
    checkIsPublicAddRegistryElement(event);
  });
}

function checkIsPublicAddRegistryElement(event) {
  if (!event || event.target.checked) {
    $('#addRegistryUsernameField').attr('disabled', true);
    $('#addRegistryPasswordField').attr('disabled', true);
    $('#addRegistryEmailField').attr('disabled', true);
    $('.add-registry-non-public').css('cursor', 'no-drop');
  } else {
    $('#addRegistryUsernameField').attr('disabled', false);
    $('#addRegistryPasswordField').attr('disabled', false);
    $('#addRegistryEmailField').attr('disabled', false);
    $('.add-registry-non-public').css('cursor', 'text');
  }
};

var deleteElementLayout = function deleteElementLayout(moduleId) {
  $.ajax({
    type: 'GET',
    url: ioAuthoring.urls.deleteElementLayouts + moduleId,
    dataType: 'json',
    data: {},
    success: function success() {}
  });
};

function handleElementTypeDropOnCanvas(event, ui) {
  var canvasX = $('.element-canvas').offset().left;

  var fogX = ui.position.left;
  var fogY = ui.position.top;

  var posX = Math.floor((fogX - canvasX) / gridSize) * gridSize;
  var posY = Math.floor(fogY / gridSize) * gridSize;

  if (ui.draggable.attr('data-element-type') != undefined) {
    // fog type
    $.ajax({
      type: 'POST',
      url: fogControllerUrl + ioAuthoring.urls.createElement,
      dataType: 'json',
      data: { t: accTok },
      success: function success(result) {
        if (result.status = 'ok') {
          createElementLayouts(result.module.id, 0, 0, 0, 'images/shared/default.png').then(function (res) {
            var canvas = $('.element-canvas');
            var canvasTop = canvas.scrollTop();
            var canvasLeft = canvas.scrollLeft();

            posX += canvasLeft;
            posY += canvasTop;

            resetFields();

            var id = result.module.id;

            var name = 'New Element';

            updateElementLayoutInfo(id, posX, posY, true);

            createNewElementOnCanvas(id, name, 'images/shared/default.png', 1, posX, posY);
            selectElement(id);

            activateElementsDraggable(id);
            activateElementsClickHandler(id);

            $('.element-selected').click();
            $('#element-properties-name').val(name);
            saveElementData();
          });
        }
      }
    });
  } else {
    // element
    var id = ui.draggable.attr('data-element-id');
    var div = $('div[data-element-id=\'' + id + '\']');
    updateElementLayoutInfo(id, fogX, fogY, true);

    div.attr('data-element-layout-x', fogX);
    div.attr('data-element-layout-y', fogY);
    div.css('top', fogY);
    div.css('left', fogX);
    selectElement(id);
  }
}

var createElementLayouts = function createElementLayouts(elementKey, layoutX, layoutY, isSelected, picture) {
  return $.ajax({
    type: 'POST',
    url: ioAuthoring.urls.createElementLayouts,
    dataType: 'json',
    data: { elementKey: elementKey, layoutX: layoutX, layoutY: layoutY, isSelected: isSelected, picture: picture },
    success: function success(result) {}
  });
};

function setObjectName(id, name) {
  var i = 0;
  var displayName = name;
  var tmp = document.getElementById('name-strong-' + id);
  if (tmp != undefined) $(tmp).remove();
  while (true) {
    var p = document.getElementById('display-name-' + id);
    var t = document.createTextNode(displayName);
    var s = document.createElement('strong');
    var sp = document.createElement('span');
    $(sp).attr('id', 'name-span-' + id);
    $(s).attr('id', 'name-strong-' + id);
    s.appendChild(t);
    p.appendChild(s);
    p.appendChild(sp);
    var pLeft = $(p).offset().left;
    var pHeight = $(p).outerHeight();
    var sLeft = $(sp).offset().left;
    i++;
    displayName = name.substring(0, name.length - i) + '...';
    if (sLeft - pLeft <= 148 && pHeight < 25) {
      $(sp).remove();
      break;
    }
    $(s).remove();
    $(sp).remove();
  }
  p.style.display = '';
}

function setObjectSubtitle(id, name) {
  var i = 0;
  var displayName = name;
  while (true) {
    var p = document.getElementById('subtitle-' + id);
    var t = document.createTextNode(displayName);
    var sp = document.createElement('span');
    $(sp).attr('id', 'subtitle-span-' + id);
    p.appendChild(t);
    p.appendChild(sp);
    var pLeft = $(p).offset().left;
    var pHeight = $(p).outerHeight();
    var sLeft = $(sp).offset().left;
    i++;
    displayName = name.substring(0, name.length - i) + '...';
    if (sLeft - pLeft <= 148 && pHeight < 25) {
      $(sp).remove();
      break;
    }
    $(sp).remove();
  }
  p.style.display = '';
}

function createNewElementOnCanvas(id, name, picture, isSelected, layoutX, layoutY) {
  $('#element-canvas-layout-grid').append('<div class="element-container ' + (isSelected == 1 ? 'element-selected" ' : '" ') + 'style="top:' + layoutY + 'px;left:' + layoutX + 'px;" data-element-id="' + id + '" ' + 'data-element-name="' + name + '" ' + 'data-element-layout-x="' + layoutX + '" data-element-layout-y="' + layoutY + '" data-element-selected="' + isSelected + '"> ' + '<img class="element-icon" src="/' + picture + '?' + new Date().getTime() + '" filename="' + picture + '"> ' + '<p id="display-name-' + id + '"></p> ' + '<p id = "subtitle-' + id + '" class="element-container-subtitle"></p> ' + '<div style="display:none;" class="element-loading-spinner"> <div class="sk-child sk-bounce1"></div> <div class="sk-child sk-bounce2"></div> </div> </div>');

  setObjectName(id, name);

  if (isSelected == 1) elementClickHandler(id);
}

function activateElementsClickHandler(id) {
  var div = $('div[data-element-id=\'' + id + '\']');
  div.click(function () {
    var elementId = $(this).attr('data-element-id');
    selectElement(elementId);
  });
}

function selectElement(elementId) {
  var tmp = $('div[data-element-selected="1"]');
  if (tmp != undefined) {
    tmp.attr('data-element-selected', '0');
    tmp.removeClass('element-selected');
    updateElementLayoutInfo(tmp.attr('data-element-id'), tmp.attr('data-element-layout-x'), tmp.attr('data-element-layout-y'), false);
  }
  var tmp = $('div[data-element-id=\'' + elementId + '\']');
  tmp.attr('data-element-selected', '1');
  tmp.addClass('element-selected');
  elementClickHandler(elementId);
  updateElementLayoutInfo(tmp.attr('data-element-id'), tmp.attr('data-element-layout-x'), tmp.attr('data-element-layout-y'), true);
}

function updateElementLayoutInfo(elementId, layoutX, layoutY, isSelected) {
  var img = $('div[data-element-id=\'' + elementId + '\'] > img');
  var filename = img.attr('filename');

  $.ajax({
    type: 'POST',
    url: ioAuthoring.urls.updateElementLayouts,
    dataType: 'json',
    data: {
      picture: filename,
      elementKey: elementId,
      layoutX: layoutX,
      layoutY: layoutY,
      isSelected: isSelected == true ? 1 : 0
    },
    success: function success(result) {}
  });
}

function elementClickHandler(elementId) {
  var overlay = $('.element-properties-loading-overlay');
  if (overlay != undefined) overlay.css('display', 'visible');

  $.ajax({
    type: 'GET',
    url: fogControllerUrl + ioAuthoring.urls.getElementDetails + elementId + '?t=' + accTok,
    dataType: 'json',
    data: {},
    success: function success(result) {
      if (result.status = 'ok') {
        var element = result.module;

        $('#element-properties-name').val(element.name);
        $('#element-properties-description').val(element.description);
        $('#element-properties-category').val(element.category);
        $('#element-properties-containerimage-x86').val(element.elementImages.x86ContainerImage);
        $('#element-properties-containerimage-arm').val(element.elementImages.armContainerImage);
        $('#element-properties-publisher').val(element.publisher);
        $('#element-properties-diskrequired').val(element.diskRequired);
        $('#element-properties-ramrequired').val(element.ram_required);
        $('#element-properties-inputinfotype').val(element.inputInfoType);
        $('#element-properties-inputinfoformat').val(element.inputInfoFormat);
        $('#element-properties-outputinfotype').val(element.outputInfoType);
        $('#element-properties-outputinfoformat').val(element.outputInfoFormat);
        $('#element-properties-configform').val(element.config);

        $('#element-properties-configform').trigger('autoresize');
        $('#photo_upload').attr('action', ioAuthoring.urls.uploadElementIcon + elementId);
        $('#file-upload-module-id').val(elementId);

        $('#dockerRegistrySelect').val(window.registry = element.registry_id || 1);
        $('#dockerRegistrySelect').material_select();
      }
    }
  });

  if (overlay != undefined) overlay.css('display', 'none');
}

function saveElementData() {

  var element = $('div[data-element-selected="1"]');
  var elementId = element.attr('data-element-id');
  var img = $('div[data-element-id=\'' + elementId + '\'] > img');
  var filename = img.attr('filename');
  var name = $('#element-properties-name').val();

  if (name.trim() == '') {
    Materialize.toast('Element name is empty!', 1000);
    $('#element-properties-name').focus();
    return;
  }

  var description = $('#element-properties-description').val();
  var category = $('#element-properties-category').val();
  var imageX86 = $('#element-properties-containerimage-x86').val().trim();
  var imageArm = $('#element-properties-containerimage-arm').val().trim();

  var publisher = $('#element-properties-publisher').val();

  if (publisher.trim().substring(0, 7).toLowerCase() == 'iotrack') {
    Materialize.toast('Invalid Publisher!', 5000);
    $('#element-properties-publisher').focus();
    return;
  }
  var disk = $('#element-properties-diskrequired').val();
  var ram = $('#element-properties-ramrequired').val();
  var inputType = $('#element-properties-inputinfotype').val();
  var inputFormat = $('#element-properties-inputinfoformat').val();
  var outputType = $('#element-properties-outputinfotype').val();
  var outputFormat = $('#element-properties-outputinfoformat').val();
  var config = $('#element-properties-configform').val();
  if (config.trim() == '') {
    config = '{}';
    $('#element-properties-configform').val(config);
  }

  var X86_FOG_TYPE_ID = 1;
  var ARM_FOG_TYPE_ID = 2;

  var registry = $('#dockerRegistrySelect').val();

  $.ajax({
    type: 'POST',
    url: fogControllerUrl + ioAuthoring.urls.updateElement,
    dataType: 'json',
    data: {
      t: accTok,
      id: elementId,
      name: name,
      description: description,
      category: category,
      images: [{
        fogTypeId: X86_FOG_TYPE_ID,
        image: imageX86
      }, {
        fogTypeId: ARM_FOG_TYPE_ID,
        image: imageArm
      }],
      publisher: publisher,
      diskRequired: disk,
      ramRequired: ram,
      inputType: inputType,
      inputFormat: inputFormat,
      outputType: outputType,
      outputFormat: outputFormat,
      picture: filename,
      config: config,
      registry: registry
    },
    success: function success(result) {
      if (result.status = 'ok') {
        updateElementLayoutInfo(elementId, element.attr('data-element-layout-x'), element.attr('data-element-layout-y'), 1);
        element.attr('data-element-name', name);
        setObjectName(elementId, name);
        window.registry = registry;
        getRegistryList();
      }
    }
  });
}

function resetFields() {
  $('#element-properties-name').val('');
  $('#element-properties-description').val('');
  $('#element-properties-category').val('');
  $('#element-properties-containerimage-x86').val('');
  $('#element-properties-containerimage-arm').val('');
  $('#element-properties-publisher').val('');
  $('#element-properties-diskrequired').val('0');
  $('#element-properties-ramrequired').val('0');
  $('#element-properties-inputinfotype').val('');
  $('#element-properties-inputinfoformat').val('');
  $('#element-properties-outputinfotype').val('');
  $('#element-properties-outputinfoformat').val('');
  $('#element-properties-configform').val('');

  $('#file-upload-module-id').val(0);

  $('#dockerRegistrySelect').val(1);
  $('#dockerRegistrySelect').material_select();
}

function scrollToInstance(instance) {
  var canvas = $('.element-canvas');

  var canvasTop = canvas.scrollTop();
  var canvasLeft = canvas.scrollLeft();

  var elementTop = instance.attr('data-element-layout-y');
  var elementLeft = instance.attr('data-element-layout-x');

  if ((elementTop < canvasTop || elementTop > canvas[0].offsetHeight) && (elementLeft < canvasLeft || elementLeft > canvas[0].offsetWidth)) canvas.animate({ scrollTop: Math.max(elementTop - 50, 0), scrollLeft: Math.max(elementLeft - 50, 0) }, 'slow');else if (elementTop < canvasTop || elementTop > canvas[0].offsetHeight) canvas.animate({ scrollTop: Math.max(elementTop - 50, 0) }, 'slow');else if (elementLeft < canvasLeft || elementLeft > canvas[0].offsetWidth) canvas.animate({ scrollLeft: Math.max(elementLeft - 50, 0) }, 'slow');
}

function addRegistry() {
  var url = $('#addRegistryUrlField').val();
  var isPublic = $('#addRegistryIsPublicField')[0].checked;
  var username = $('#addRegistryUsernameField').val();
  var password = $('#addRegistryPasswordField').val();
  var email = $('#addRegistryEmailField').val();

  if (url === '') {
    return Materialize.toast('URl can\'t be empty', 3000);
  }

  var data = {
    url: url,
    isPublic: isPublic
  };

  if (!isPublic) {
    if (username === '') {
      return Materialize.toast('Username can\'t be empty', 3000);
    } else if (password === '') {
      return Materialize.toast('Password can\'t be empty', 3000);
    } else if (email === '') {
      return Materialize.toast('E-mail can\'t be empty', 3000);
    } else {
      data.username = username;
      data.password = password;
      data.email = email;
    }
  }

  $.post(fogControllerUrl + ioAuthoring.urls.addRegistry + '?t=' + accTok, data, function (response) {
    $('#addRegistryModal').closeModal();
    clearAddRegistryModal();
  });
}

function clearAddRegistryModal() {
  $('#addRegistryUrlField').val('');
  $('#addRegistryUsernameField').val('');
  $('#addRegistryPasswordField').val('');
  $('#addRegistryEmailField').val('');
  $('#addRegistryIsPublicField').val('on');
}

function onImportMicroserviceClick() {
  var element = $('#element-instance-properties-import-microservice');
  if (element.val() !== '') {
    $('#importMicroservice').closeModal();
    var url = ioAuthoring.urls.importMicroservice + '?t=' + accTok + '&url=' + element.val();
    $.get(url, function (data) {
      importMicroservice(data);
    });

    element.val('');
  } else {
    Materialize.toast('Enter the link of the imported microservice\n.', 5000);
  }
}

function importMicroservice(json) {
  var imagePath = json.versionList[0].icon;
  $.ajax({
    type: 'POST',
    url: fogControllerUrl + ioAuthoring.urls.createElement,
    dataType: 'json',
    data: {
      t: accTok,
      name: json.name,
      description: json.versionList[0].description,
      category: json.versionList[0].category,
      images: json.versionList[0].platformList && json.versionList[0].platformList.map(function (element) {
        return {
          fogTypeId: element.imageType,
          image: element.image
        };
      }),
      publisher: json.versionList[0].publisher,
      diskRequired: json.versionList[0].systemRequirements[0],
      ramRequired: json.versionList[0].systemRequirements[1],
      inputType: json.versionList[0].inputExample,
      inputFormat: json.versionList[0].inputExample,
      outputType: json.versionList[0].outputExample,
      outputFormat: json.versionList[0].outputExample,
      picture: json.versionList[0].icon,
      config: json.versionList[0].configuration
    },
    success: function success(result) {
      if (result.status === 'ok') {
        createElementLayouts(result.module.id, 0, 0, 0, imagePath || 'images/shared/default.png');
        catalogLoading();
      }
    }
  });
}