import * as Models from "../ivprog_elements";
import { LocalizedStrings } from "../../services/localizedStringsService";
import * as VariableValueMenu from "./variable_value_menu";
import * as VariableValueMenuManagement from "./variable_value_menu";
import * as CommandsManagement from "../commands";
import * as GenericExpressionManagement from "./generic_expression";
import * as CodeGenerator from '../code_generator';

export function createFloatingCommand () {
  return $(
    '<div class="ui writer created_element"> <i class="ui icon small upload"></i> <span> ' +
      LocalizedStrings.getUI("text_command_write") +
      " var </span></div>"
  );
}

export function renderCommand (command, function_obj) {
  const ret = `<div class="ui writer command_container">
      <i class="ui icon small upload command_drag"></i>
      <i class="ui icon times red button_remove_command"></i>
      <span class="span_command_spec">${LocalizedStrings.getUI(
        "text_command_write"
      )}
      ( </span><div class="all_elements_write"></div> <span class="textual_expression"></span>
      <span class="close_parentheses span_command_spec">)</span>
    <img data-state="${command.newline ? "on" : "false"}" src="${
    command.newline ? "img/new_line.svg" : "img/no_new_line.svg"
  }" class="ivprog_newline_btn"/> 
    <i class="ui icon i cursor button_write_expression" style="margin-left: 3rem !important; margin-right: -1.1rem !important;"></i> 
    <i class="ui icon unlock button_alternate_expression"></i>
    </div>`;
  const el = $(ret);
  el.data("command", command);

  //renderExpression (command, function_obj, div_to_render, expression_array)

  GenericExpressionManagement.renderExpression(
    command,
    function_obj,
    el.find(".all_elements_write"),
    command.content
  );

 
  addHandlers(command, function_obj, el);

  if (command.content && command.lockexpression) {
    try {
      var text = CodeGenerator.elementExpressionCode(command.content);
      if (text) {
        $(el.find('.all_elements_write')[0]).toggle();
        $(el.find('.textual_expression')[0]).text(text);
        $(el.find('.textual_expression')[0]).toggle();
        $(el.find('.button_alternate_expression')[0]).toggleClass('unlock').toggleClass('lock');
      }
    } catch (e) {
      command.lockexpression = false;
    }
  }

  el.find('.unlock').popup({
		content : LocalizedStrings.getUI("text_lock_expression"),
		delay: {
			show: 750,
			hide: 0
		}
	});
	el.find('.lock').popup({
		content : LocalizedStrings.getUI("text_unlock_expression"),
		delay: {
			show: 750,
			hide: 0
		}
  });
  el.find('.button_write_expression').popup({
		content : LocalizedStrings.getUI("text_edit_expression"),
		delay: {
			show: 750,
			hide: 0
		}
	});

  return el;
}

function addHandlersManager (
  command,
  _function_obj,
  _writer_dom,
  item_div,
  content_element
) {
  item_div.find(".times").on("click", function () {
    for (let i = 0; i < command.content.length; i++) {
      if (command.content[i] == content_element) {
        delete command.content[i];
        command.content.splice(i, 1);

        item_div.children().off();
        item_div.off();
        item_div.fadeOut();

        if (command.content.length > 0) {
          item_div.next(".icon_add_item_to_writer").fadeOut();
        }
        break;
      }
    }
  });
}

function addHandlers (command, function_obj, writer_dom) {

  $(writer_dom.find('.textual_expression')[0]).toggle();

  writer_dom.find('.button_write_expression').on('click', function() {

		window.expressionEdition = true;
		window.inputExpression = null;
		
		var afterWhichElement;
		var lockButton = $(writer_dom.find('.button_alternate_expression')[0]);
		var editButton = $(this);

		afterWhichElement = writer_dom.find('.all_elements_write');

		if (command.lockexpression) {
			afterWhichElement = writer_dom.find('.textual_expression');
		}

		var text = "";
		if (command.content) {
			if (command.content.length == 1 && command.content[0].content == null && !command.content[0].function_called) {
				text = "";
			} else {
				try {
					text = CodeGenerator.elementExpressionCode(command.content);
				} catch(ex) {
					text = "";
				}
			}
		}

		var ok_button = $('<i class="ui icon check circle expression-edit-confirm"></i>');
		var cancel_button = $('<i class="ui icon undo expression-edit-cancel"></i>');
		var input = $('<input type="text" spellcheck="false" autocomplete="off" class="input-expression-field" >');
		input.val(text);

		input.focusout(function(evt) {
			ok_button.click();
			evt.preventDefault();
			return true;
		});
		
		input.keyup(function(evt) {
			if (evt.keyCode == 27) { // esc
				cancel_button.click();
			} 
			if (evt.keyCode == 13) { // enter
				ok_button.click();
			}
		});

		ok_button.click(function() {
			var parsed = null;
			parsed = GenericExpressionManagement.expressionParserToVisual(input.val(), function_obj, input);
			if (parsed) {
				window.expressionEdition = false;
				command.content = parsed;
				renderAlgorithm();
			}
		});

		cancel_button.mousedown(function(evt) {
			var parsed = GenericExpressionManagement.expressionParserToVisual(text, function_obj, input);
			if (parsed) {
				window.expressionEdition = false;
				command.content = parsed;
				renderAlgorithm();
			}
		});

		input.insertAfter(afterWhichElement);
		input.focus();
		cancel_button.insertAfter(input);
		ok_button.insertAfter(input);
		var len = text.length; 
		input[0].setSelectionRange(len, len); 

		afterWhichElement.css('display', 'none');
		lockButton.css('display', 'none');
		editButton.css('display', 'none');

		ok_button.popup({
			content : LocalizedStrings.getUI("text_edit_expression_confirm"),
			delay: {
				show: 750,
				hide: 0
			}
		});
		cancel_button.popup({
			content : LocalizedStrings.getUI("text_edit_expression_cancel"),
			delay: {
				show: 750,
				hide: 0
			}
		});
	});

	
	writer_dom.find('.button_alternate_expression').on('click', function() {
		if (command.content) {
      var text = CodeGenerator.elementExpressionCode(command.content);
			if (text) {
				$(writer_dom.find('.all_elements_write')[0]).toggle();
				$(writer_dom.find('.textual_expression')[0]).text(text);
				$(writer_dom.find('.textual_expression')[0]).toggle();
				$(this).toggleClass('unlock').toggleClass('lock');
				command.lockexpression = !command.lockexpression;
      }
      
      if (command.lockexpression) {
				writer_dom.find('.lock').popup({
					content : LocalizedStrings.getUI("text_unlock_expression"),
					delay: {
						show: 750,
						hide: 0
					}
				});
			} else {
				writer_dom.find('.unlock').popup({
					content : LocalizedStrings.getUI("text_lock_expression"),
					delay: {
						show: 750,
						hide: 0
					}
				});
			}
		}
	});

  writer_dom.find(".button_remove_command").on("click", function () {
    if (CommandsManagement.removeCommand(command, function_obj, writer_dom)) {
      writer_dom.fadeOut(400, function () {
        writer_dom.remove();
      });
    }
  });

  Sortable.create(writer_dom.find(".all_elements_write")[0], {
    handle: ".ellipsis",
    animation: 100,
    ghostClass: "ghost",
    group: "writer_" + Math.floor(Math.random() * 10000000),
    draggable: ".div_parent_handler",
    onEnd: function (evt) {
      command.content.splice(
        evt.newIndex,
        0,
        command.content.splice(evt.oldIndex, 1)[0]
      );

      writer_dom.empty();
      writer_dom.replaceWith(renderCommand(command, function_obj));
    },
  });
  // Attach event handles for the newline button
  const newlineBtn = writer_dom.find(".ivprog_newline_btn");
  newlineBtn.on("click", function () {
    const state = this.dataset.state;
    if (state === "on") {
      this.dataset.state = "off";
      command.newline = false;
      this.setAttribute("src", "img/no_new_line.svg");
    } else {
      this.dataset.state = "on";
      command.newline = true;
      this.setAttribute("src", "img/new_line.svg");
    }
    writer_dom.data("command", command);
    setPopup(newlineBtn, command.newline);
  });
  // Attach jquery popup
  setPopup(newlineBtn, command.newline);
}

function setPopup (element, state) {
  if (element.popup("exists")) {
    element.popup("destroy");
  }
  const content = state
    ? LocalizedStrings.getUI("write_command_newline_on")
    : LocalizedStrings.getUI("write_command_newline_off");
  element.popup({
    content: content,
    delay: {
      show: 750,
      hide: 0,
    },
  });
}

function _addHandlerIconAdd (
  dom_object,
  command,
  function_obj,
  insert_after = false,
  after_which = null
) {
  const icon_add_item = $(
    '<i class="ui icon plus square outline icon_add_item_to_writer"></i> '
  );
  if (!insert_after) {
    dom_object.append(icon_add_item);
  } else {
    icon_add_item.insertAfter(after_which);
  }

  icon_add_item.on("click", function (_event) {
    const div_parent_with_handler = $(
      '<div class="div_parent_handler" style="display:none;"></div>'
    );
    const new_div_item = $('<div class="var_value_menu_div"></div>');
    div_parent_with_handler.append(
      $('<i class="ui icon ellipsis vertical inverted handler"></i>')
    );
    div_parent_with_handler.append(new_div_item);
    div_parent_with_handler.append(
      $('<i class="white inverted icon times handler"></i>')
    );
    div_parent_with_handler.insertAfter(icon_add_item);

    const new_related_menu = new Models.VariableValueMenu(
      VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
      null,
      null,
      null,
      true
    );

    VariableValueMenu.renderMenu(
      command,
      new_related_menu,
      new_div_item,
      function_obj
    );

    addHandlerIconAdd(
      dom_object,
      command,
      function_obj,
      true,
      div_parent_with_handler
    );

    addHandlersManager(
      command,
      function_obj,
      dom_object,
      div_parent_with_handler,
      new_related_menu
    );
    let pos = 1;
    dom_object.find(".icon_add_item_to_writer").each(function () {
      if ($(this).get(0) === icon_add_item.get(0)) {
        command.content.splice(pos, 0, new_related_menu);
      } else {
        pos++;
      }
    });
    if (command.content.length == 1) {
      icon_add_item.remove();
    }
    div_parent_with_handler.fadeIn();
  });
}

export function addContent (
  command,
  _ref_object,
  dom_object,
  _menu_var_or_value,
  function_obj,
  _ref_object_content
) {
  if (dom_object.hasClass("var_value_menu_div")) {
    const icon_add_item = $(
      '<i class="ui icon plus square outline icon_add_item_to_writer"></i> '
    );
    icon_add_item.insertAfter(dom_object);

    icon_add_item.on("click", function (_event) {
      const div_parent_with_handler = $(
        '<div class="div_parent_handler"></div>'
      );
      div_parent_with_handler.append(
        $('<i class="ui icon ellipsis vertical inverted handler"></i>')
      );
      div_parent_with_handler.append(new_div_item);
      div_parent_with_handler.append(
        $('<i class="white inverted icon times handler"></i>')
      );

      div_parent_with_handler.insertAfter(icon_add_item);
      const new_related_menu = new Models.VariableValueMenu(
        VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
        null,
        null,
        null,
        true
      );

      VariableValueMenu.renderMenu(
        command,
        new_related_menu,
        new_div_item,
        function_obj
      );

      addHandlersManager(
        command,
        function_obj,
        dom_object,
        div_parent_with_handler,
        new_related_menu
      );

      command.content.push(new_related_menu);

      if (command.content.length == 1) {
        icon_add_item.remove();
      }
    });
  }
}
