فهرست منبع

Fix merge conflicts with visualui

Lucas de Souza 5 سال پیش
والد
کامیت
f130cf2580
50فایلهای تغییر یافته به همراه10364 افزوده شده و 581 حذف شده
  1. 71 0
      css/ivprog-term.css
  2. 376 14
      css/ivprog-visual-1.0.css
  3. 34 2
      i18n/en/error.json
  4. 73 1
      i18n/en/ui.json
  5. 71 1
      i18n/es/ui.json
  6. 0 53
      i18n/i18n-engine.js
  7. 72 2
      i18n/pt/ui.json
  8. 124 74
      index.html
  9. 90 0
      js/assessment/ivprogAssessment.js
  10. 302 13
      js/iassign-integration-functions.js
  11. 138 0
      js/io/domConsole.js
  12. 10 47
      js/main.js
  13. 19 0
      js/processor/ivprogProcessor.js
  14. 49 0
      js/runner.js
  15. 1 18
      js/semantic/semantic-buttons.js
  16. 22 0
      js/services/i18nHelper.js
  17. 5 4
      js/services/languageService.js
  18. 0 1
      js/services/localizedStringsService.js
  19. 5 3
      js/util/inputTest.js
  20. 39 0
      js/visualUI/algorithm.js
  21. 1074 0
      js/visualUI/code_generator.js
  22. 1045 0
      js/visualUI/commands.js
  23. 488 0
      js/visualUI/commands/attribution.js
  24. 27 0
      js/visualUI/commands/break.js
  25. 36 0
      js/visualUI/commands/comment.js
  26. 231 0
      js/visualUI/commands/conditional_expression.js
  27. 94 0
      js/visualUI/commands/contextualized_menu.js
  28. 49 0
      js/visualUI/commands/dowhiletrue.js
  29. 32 0
      js/visualUI/commands/functioncall.js
  30. 60 0
      js/visualUI/commands/iftrue.js
  31. 34 0
      js/visualUI/commands/reader.js
  32. 170 0
      js/visualUI/commands/repeatNtimes.js
  33. 32 0
      js/visualUI/commands/return.js
  34. 75 0
      js/visualUI/commands/switch.js
  35. 1069 0
      js/visualUI/commands/variable_value_menu.js
  36. 50 0
      js/visualUI/commands/whiletrue.js
  37. 86 0
      js/visualUI/commands/writer.js
  38. 782 0
      js/visualUI/functions.js
  39. 947 0
      js/visualUI/globals.js
  40. 268 0
      js/visualUI/ivprog_elements.js
  41. 0 0
      js/visualUI/old_functions.js
  42. 0 0
      js/visualUI/old_visual.js
  43. 7 0
      js/visualUI/types.js
  44. 921 0
      js/visualUI/variables.js
  45. 76 0
      js/visualUI/visual.js
  46. 0 126
      main.html
  47. 1124 217
      package-lock.json
  48. 4 2
      package.json
  49. 78 0
      runner.html
  50. 4 3
      webpack.config.js

+ 71 - 0
css/ivprog-term.css

@@ -0,0 +1,71 @@
+.ivprog-term-div {
+  background-color: black;
+  width: 100%;
+  height: 12rem;
+  overflow-y: scroll;
+}
+
+.ivprog-term-userText {
+  color: white;
+}
+
+.ivprog-term-info {
+  color: green;
+}
+
+.ivprog-term-error {
+  color: red;
+}
+
+.ivprog-term-input {
+  font-family: 'Courier New', Courier, monospace;
+  font-weight: 500;
+  background-color: inherit;
+  border: 0;
+  color: white;
+}
+
+.ivprog-term-div > .ivprog-term-input, .ivprog-term-div > .ivprog-term-userText,
+.ivprog-term-div > .ivprog-term-info, .ivprog-term-div, .ivprog-term-error {
+  padding-left: 20px;
+}
+
+#ivprog-term {
+  border: 1px solid gray;
+  background: black;
+  margin-top: -30px;
+  position: relative;
+  padding: 5px;
+}
+#ivprog-term i {
+  margin-left: 5px;
+  cursor: pointer;
+}
+.div_toggle_console {
+  cursor: pointer;
+}
+.ivprog-term-active {
+  box-shadow: 0 0 5px rgba(81, 203, 238, 1) !important;
+  border: 3px solid rgba(81, 203, 238, 1) !important;
+}
+
+.ivprog-term-div {
+  overflow:scroll;
+}
+
+.ivprog-term-div::-webkit-scrollbar {
+    width: 12px;
+}
+ 
+.ivprog-term-div::-webkit-scrollbar-track {
+    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 
+    -webkit-border-radius: 10px;
+    border-radius: 10px;
+}
+ 
+.ivprog-term-div::-webkit-scrollbar-thumb {
+    -webkit-border-radius: 10px;
+    border-radius: 10px;
+    background: green;
+    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); 
+}

+ 376 - 14
css/ivprog-visual-1.0.css

@@ -6,15 +6,24 @@ body {
   height: 100%;
 }
 
-.div_to_body {
-  height: 90%;
+.ui.raised.container.segment.div_to_body {
+  height: 92%;
+  padding: 10px;
+  padding-left: 6px;
+  padding-right: 6px;
 }
 
 .ivprog_visual_panel {
-	height: 91%;
+	height: 96%;
 	overflow: auto;
 	overflow-x: auto;
+}
 
+.ivprog_textual_code {
+	width: 100%;
+	min-height: 500px;
+	resize: none;
+	background-color: white;
 }
 
 .main_title h2 {
@@ -42,7 +51,7 @@ body {
 }
 .content_margin .content_sub_margin {
 	display: inline; 
-	margin-left: 15%; 
+    margin-left: 34%;
 	margin-top: 50px;
 }
 .ui.icon.menu.center.aligned.container {
@@ -111,11 +120,52 @@ body {
 	min-width: 50px;
 }
 
-.function_name_div, .function_return_div, .function_name_parameter {
+.text_attr_receives {
+	margin-left: 20px;
+	margin-right: 20px;
+}
+
+.menu_operations {
+	margin-left: 10px;
+	margin-right: 10px;
+}
+
+.case_commands_block {
+	/*border: 1px solid red;*/
+}
+
+.context_menu {
 	display: inline;
+	float: right; 
+	margin-right: 25px;
+	margin-top: -4px;
 }
 
-.enable_edit_name_function, .enable_edit_name_parameter, .add_parameter, .remove_parameter {
+.case_div {
+	border: 1px solid gray;
+	margin-left: 30px;
+	padding-left: 5px;
+	margin-top: 5px;
+}
+
+.function_name_div, .function_return_div, .function_name_parameter, .created_div_valor_var, .function_return, .var_value_menu_div, .variable_rendered, .variable_rendered div, .var_attributed,
+.expression_operand_1, .expression_operand_2, .operator, .div_comment_text, .value_rendered, .parameters_function_called, .parameters_function_called div, .expression_elements,
+.expression_element, .var_rendered, .menu_add_item, .component_element, .component_element, .conditional_expression, .variable_attribution, .attribution_expression, .var_value_expression,
+.incrementation_field, .incrementation_variable, .first_operand, .operator, .second_operand, .variable_to_switch, .variable_case, .button_remove_case, .editing_name_var, .parameter_div_edit,
+.all_elements_write, .container_var_element_control {
+	display: inline;
+}
+
+.conditional_comands_block {
+	min-height: 10px;
+}
+
+.div_comment_text {
+	min-width: 100px;
+	font-style: italic;
+}
+
+.enable_edit_name_function, .add_parameter, .remove_parameter, .add_parameter_button, .remove_variable {
 	cursor: pointer;
 }
 
@@ -127,8 +177,9 @@ body {
 }
 
 .ui.segment.ivprog_visual_panel {
-	padding: 8px;
-	background-image: url('../img/background-panel.png');
+	padding: 3px;
+	margin-top: -5px;
+	background: #edf4ff;
 }
 
 .ui.segment.function_div {
@@ -171,6 +222,7 @@ body {
 	margin-left: 30px;
 	width: calc(100% - 30px);
 	background-color: #f9f9f9;
+	min-height: 30px;
 }
 
 .ui.segment.variables_list_div {
@@ -196,7 +248,7 @@ body {
 	display: inline;
 }
 
-.function_return, .parameter_type {
+.parameter_type {
 	margin-left: 10px;
     margin-right: 15px;
 }
@@ -223,14 +275,23 @@ div.buttons_manage_columns {
 .ui.comment span {
 	font-style: italic;
 }
-.ui.comment {
+.ui.comment, .ui.reader, .ui.writer, .ui.attribution, .ui.iftrue, .ui.repeatNtimes, .ui.whiletrue, .ui.dowhiletrue, .ui.switch, .ui.functioncall,
+.ui.return {
 	border: 1px solid gray;
 	padding: 5px;
 	border-radius: 5px;
 	margin: 5px;
 	background: #f9f9f9;
 }
-
+.ui.repeatNtimes .separator_character {
+	margin-right: 10px;
+}
+.ui.repeatNtimes, .ui.whiletrue {
+    min-height: 50px;
+}
+.ui.dowhiletrue .ui.block_commands {
+	min-height: 10px;
+}
 .add_var_top_button {
 	padding-right: 50px;
 }
@@ -251,12 +312,11 @@ div.buttons_manage_columns {
 }
 
 .global_var {
-	margin-bottom: 10px;
+	margin-bottom: 7px;
 }
 
 .list_globals, .global_const {
 	display: inline;
-	cursor: pointer;
 }
 
 .created_element {
@@ -265,4 +325,306 @@ div.buttons_manage_columns {
 	z-index: 99999999;
 	opacity: .8;
 	cursor: move;
-}
+}
+
+.width-dynamic {
+	min-width: 100px;
+}
+
+.ui.icon.plus.square.outline.icon_add_item_to_writer {
+	margin-right: 10px;
+	margin-left: 10px;
+	cursor: pointer;
+}
+
+.button_remove_command, .button_refresh_attribution {
+	float: right;
+	cursor: pointer;
+}
+
+.expression_drag {
+	cursor: col-resize;
+	border: 2px gray solid;
+	display: inline;
+	width: 5px;
+}
+
+.ui.icon.red.exclamation.triangle.error_icon {
+	float: left;
+    margin-left: -30px;
+}
+
+.height_100 {
+  height: 100%;
+}
+
+.default_visual_title {
+  display: none;
+}
+
+.expandingArea textarea {
+	min-height: 30px;
+	resize: none;
+	padding: 5px;
+}
+
+.ui table .btn_actions {
+	text-align: center;
+}
+
+.button_remove_case {
+	cursor: pointer;
+	padding: 3px;
+}
+
+.ui.button_add_case {
+	margin-top: 10px;
+}
+.accordion {
+	margin: auto;
+}
+
+.global_container:hover, 
+.variable_container:hover {
+	border: 2px solid gray;
+	padding-left: 8px;
+	padding-right: 8px;
+	padding-top: 5px;
+	padding-bottom: 4px;
+}
+
+.ui.label.function_name_parameter:hover {
+	border: 2px solid gray;
+	padding: 5px 6px 5px 6px;
+}
+
+.ui.label.function_name_parameter {
+	padding: 7px 8px 7px 8px;
+}
+
+.global_container:hover,  .variable_container:hover {
+	margin-bottom:  4px !important;
+}
+
+.global_container .global_type, .editing_name_var, .global_container .span_value_variable,
+.variable_container .variable_type,  .variable_container .span_value_variable,
+.ui.dropdown.function_return, div.function_name_div_updated,
+.ui.dropdown.parameter_type, .parameter_div_edit {
+	background: #cecece;
+	border-radius: 5px;
+	padding: 4px;
+	margin-left: 5px;
+	margin-right: 5px;
+}
+.parameter_div_edit {
+	padding-bottom: 2px;
+	padding-top: 2px;
+}
+.ui.dropdown.parameter_type {
+
+}
+div.function_name_div_updated {
+	padding-top: 5px;
+	padding-bottom: 5px;
+	margin-right: 10px;
+}
+.function_name_div_updated .name_function_updated {
+	padding-left: 10px;
+    padding-right: 10px;
+}
+.variable_container .variable_type {
+	padding: 5px;
+	margin-left: 0;
+	margin-right: 3px;
+}
+
+.global_container .global_type:hover, .editing_name_var:hover, .global_container .span_value_variable:hover,
+.variable_container .variable_type:hover, .variable_container .span_name_variable:hover, .variable_container .span_value_variable:hover,
+.ui.dropdown.function_return:hover, div.function_name_div_updated:hover,
+.ui.dropdown.parameter_type:hover, .parameter_div_edit:hover {
+	background: #848484;
+	color: #fff;
+	z-index: 999999;
+}
+
+.editing_name_var {
+	min-width: 40px;
+	padding-top: 3px;
+	padding-bottom: 3px;
+}
+
+.global_container .global_type:active, 
+.variable_container .variable_type:active,
+.ui.dropdown.function_return:active, 
+div.function_name_div_updated:active,
+.ui.dropdown.parameter_type:active {
+	background: #636363;
+	color: #fff;
+}
+
+.global_container i {
+	cursor: pointer;
+}
+
+.global_container .ui.icon.plus.square.outline, .global_container .ui.icon.minus.square.outline {
+	font-size: 120%;
+}
+
+.character_equals {
+	vertical-align: sub;
+    font-size: 150%;
+}
+
+.red.icon.times.remove_global,
+.red.icon.times.remove_variable,
+.red.icon.times.remove_parameter {
+	float: right;
+    margin-right: -1px;
+    margin-left: 8px;
+    opacity: 0;
+}
+
+.global_container:hover > .red.icon.times.remove_global, .variable_container:hover > .red.icon.times.remove_variable,
+.function_name_parameter:hover > .red.icon.times.remove_parameter {
+	opacity: 1;
+}
+
+.tr_manage_lines {
+	padding-top: 10px;
+}
+
+.ui.icon.button.add-globalVar-button.add_global_button {
+	padding: 8px;
+	margin-bottom: 4px;
+}
+.all_functions {
+	margin-top: -5px;
+}
+.only_in_frame {
+	position: absolute;
+    z-index: 9999;
+    width: 90px;
+    top: 5px;
+    left: 5px;
+    opacity: .6;
+}
+.only_in_frame:hover {
+	opacity: 1;
+}
+.only_in_frame:hover span {
+	display: block;
+}
+.only_in_frame span {
+	display: none;
+	margin-top: -5px;
+}
+.ui.container.main_title {
+	width: 85px;
+}
+.ui.label.global_container {
+	margin-bottom: 3px;
+}
+.ui.label.variable_container {
+	margin-bottom: 3px;
+}
+.created_div_valor_var {
+	display: inline-block;
+}
+.ui.dropdown.function_return {
+	padding-left: 15px;
+    padding-right: 15px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+.parethesis_function {
+	font-size: 120%;
+}
+
+.var_value_menu_div,
+.attribution .var_attributed,
+.component_element,
+.conditional_expression .expression_element,
+.menu_start_rendered,
+.attribution_expression .variable_attribution,
+.render_style_param,
+.attribution_expression .div_expression_st:not(:empty),
+.incrementation_field .incrementation_variable,
+.incrementation_field .first_operand:not(:empty),
+.incrementation_field .operator:not(:empty),
+.incrementation_field .second_operand:not(:empty) {
+	background: #e8e8e8;
+	border-radius: 5px;
+	min-width: 40px;
+	padding: 2px;
+    padding-left: 5px;
+    padding-right: 5px;
+    border: 1px solid gray;
+    box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.2), 0 3px 3px 0 rgba(0, 0, 0, 0.19);
+    color: black;
+}
+.menu_start_rendered {
+	padding-left: 12px;
+}
+.menu_start_rendered i {
+	width: 1.5em;
+    margin-right: -1em;
+}
+.row_container:hover, .column_container:hover {
+	background: #cecece;
+}
+
+.column_container, .row_container {
+	border-radius: 4px;
+    border: 1px solid gray;
+    padding: 1px 2px 1px 2px;
+    background: #e8e8e8;
+
+    box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.2), 0 3px 3px 0 rgba(0, 0, 0, 0.19);
+}
+
+.var_value_menu_div div i {
+	color: black;
+}
+
+.span_command_spec {
+	color: black;
+	font-weight: bold;
+	font-size: 110%;
+}
+
+.ui.comment.command_container .var_value_menu_div {
+	display: inline-block;
+	width: 93%;
+}
+
+.ui.comment.command_container .var_value_menu_div .variable_rendered,
+.ui.comment.command_container .var_value_menu_div .value_rendered {
+    width: 100%;
+    cursor: text;
+    font-style: italic;
+}
+
+.ui.comment.command_container .var_value_menu_div {
+	cursor: text;
+}
+
+.ui.comment.command_container .var_value_menu_div {
+	background: none;
+	border-radius: 0;
+    border: 0px solid gray;
+    box-shadow: none;
+    padding: 0px;
+    font-size: 110%;
+}
+.ui.comment.command_container .var_name,
+.ui.comment.command_container .value_rendered {
+	color: rgba(0,0,0,.6);
+}
+.ui.comment.command_container .var_value_menu_div input {
+    width: 100%;
+    display: inline-block;
+    font-style: italic;
+}
+.ui.dropdown.menu_start_rendered .text i {
+    padding-right: 8px;
+}

+ 34 - 2
i18n/en/error.json

@@ -1,3 +1,35 @@
 {
-  
-}
+  "token_missing_one": "Erro de sintaxe: Espera-se $0, mas encontrou-se $1 na linha:$2, coluna:$3",
+  "token_missing_two": "Erro de sintaxe: Esperava-se $0 ou $1 mas encontrou-se $2 na liha:$3, coluna: $4",
+  "eos_missing": "Falta uma nova linha ou ; na linha: $0, coluna: $1",
+  "invalid_type": "$0 na linha: $1, coluna: $2 é um tipo inválido. Os tipos válidos são: $3",
+  "invalid_array_dimension": "A dimensão inválida na linha: $0, coluna: $1. Insira um $2 ou identificador válido do mesmo tipo.",
+  "invalid_array_size": "O tamnho do vetor/matriz excede o máximo de 2 na linha $0",
+  "extra_lines": "Nenhum texto é permitido após '}' em 'programa {...}'",
+  "invalid_main_return": "A função $0 deve retornar $1 na linha $2",
+  "invalid_var_declaration": "Erro na linha $0. Variáveis só podem ser declarados no corpo principal da função e de preferência nas primeiras linhas.",
+  "invalid_break_command": "Erro na linha $0. O comando $1 não pode ser usado fora de uma estrutura de repetição ou 'escolha...caso'",
+  "invalid_terminal": "Não é possível utilizar $0 na expressão da linha: $1, coluna: $2. Tente um valor númerico, variável ou chamada de função.",
+  "id_missing": "Esperava-se um identificador, mas encontrou-se $0 na linha: $1, coluna: $2",
+  "main_missing": "A função principal não foi encontrada",
+  "invalid_global_var": "Erro crítico: Chamada inválida da função initGlobal fora do contexto BASE",
+  "not_implemented": "Erro interno crítico: A função definida pelo sistema $0 não foi implementada.",
+  "function_missing": "A função $0 não foi encontrada",
+  "invalid_parameters_size": "A quantidade de parâmetros fornecidos está incorreta. Esperava-se $0, encontrou-se $1",
+  "invalid_ref": "Você deve fornecer apenas um identificador como parâmetro",
+  "invalid_parameter_type": "O valor fornecido como parâmetro é do tipo $0, mas o tipo esperado é $1",
+  "unknown_command": "Erro interno crítico: Comando desconhecido encontrado",
+  "loop_condition_type": "A condição dos laços de repetição deve ser do tipo lógico",
+  "if_condition_type": "A condição de um comando se...senao deve ser do tipo lógico",
+  "invalid_return_type": "A função $0 deve retornar um tipo $1, ao invés de $1",
+  "unexpected_break_command": "Erro interno crítico: Comando pare encontrado fora do contexto de um laço/escolha..caso",
+  "invalid_dimension": "As dimensões de um vetor/matriz devem ser do tipo inteiro",
+  "void_in_expression": "A função $0 não pode ser utilizada aqui pois seu tipo de retorno é vazio",
+  "invalid_array": "Expressão literal de Vetor/Mariz inválida",
+  "invalid_array_access": "Identificador $0 não se refere a um vetor/matriz válido",
+  "column_outbounds": "Número de colunas $0 é inválido para a matriz $1 que possui $2 colunas",
+  "line_outbounds": "Número de linhas $0 é invaálido para a matriz $1 que possui $2 linhas",
+  "invalid_infix_op": "Não é possível aplicar a operação $0 entre os tipos $1 e $2",
+  "invalid_unary_op": "Não é possível aplicar a operação $0 ao tipo $1",
+  "unknown_op": "Erro interno crítico: Operação $0 desconhecida"
+}

+ 73 - 1
i18n/en/ui.json

@@ -1,12 +1,21 @@
 {
   "function": "function",
+  "btn_clear": "Clear",
   "btn_function": "Function",
+  "btn_arithmetic_plus": "Sum",
+  "btn_arithmetic_minus": "Minus",
+  "btn_arithmetic_multiplication": "Multiplication",
+  "btn_arithmetic_division": "Division",
+  "btn_arithmetic_module": "Module",
+  "btn_break":"Break",
+  "btn_case":"Case",
   "start": "start",
   "void": "void",
   "integer": "integer",
   "real": "real",
   "program": "program",
   "text": "text",
+  "text_start": "text",
   "boolean": "boolean",
   "true": "true",
   "false": "false",
@@ -21,5 +30,68 @@
   "text_comment_main": "This is the main function...",
   "text_read_var": "Reading data",
   "text_write_var": "Writing data",
-  "text_comment": "Comment"
+  "text_command_read":"read",
+  "text_command_write":"write",
+  "text_comment": "Comment",
+  "text_attribution": "Attribution",
+  "text_if":"if",
+  "text_else":"else",
+  "text_break":"break",
+  "text_for":"for",
+  "text_code_while":"while",
+  "text_code_do":"do",
+  "text_command_do":"do",
+  "text_code_switch": "switch",
+  "text_code_case": "case",
+  "text_logic_expression": "Logic Expression",
+  "text_arithmetic_expression": "Arithmetic Expression",
+  "text_iftrue": "If true then",
+  "text_receives": "receives",
+  "text_repeatNtimes": "Repeat N times",
+  "text_return":"return",
+  "text_btn_return":"Return",
+  "text_whiletrue": "While true",
+  "text_dowhiletrue": "Do while true",
+  "text_switch": "Switch",
+  "text_functioncall": "Function call",
+  "text_value": "Value",
+  "text_operator": "Operator",
+  "text_parentheses": "Parentheses",
+  "text_change": "Change",
+  "text_teacher_algorithm": "Algorithm",
+  "text_teacher_algorithm_include": "Include the following algorithm in exercise",
+  "text_teacher_test_case": "Test cases",
+  "text_teacher_config": "Settings",
+  "text_teacher_data_types": "Data types",
+  "text_teacher_commands": "Commands",
+  "text_teacher_functions": "Functions",
+  "text_teacher_create_functions": "Create new functions",
+  "text_teacher_create_movement_functions": "Move functions",
+  "text_teacher_test_case_input": "Input",
+  "text_teacher_test_case_output": "Output",
+  "text_teacher_test_case_actions": "Actions",
+  "text_teacher_test_case_add": "Add test cases",
+  "text_header_ivprog_functions": "iVProg Functions",
+  "text_menu_functions_math":"Mathematics",
+  "text_menu_functions_text":"Text",
+  "text_menu_functions_arrangement":"Arrangement",
+  "text_menu_functions_conversion":"Conversion",
+  "tooltip_visual": "Visual programming",
+  "tooltip_textual": "Textual programming",
+  "tooltip_upload": "Upload code file",
+  "tooltip_download": "Download code file",
+  "tooltip_undo": "Undo",
+  "tooltip_redo": "Redo",
+  "tooltip_run": "Run program",
+  "tooltip_evaluate": "Evaluate program",
+  "tooltip_help": "Help",
+  "tooltip_add_global": "Add global variable",
+  "tooltip_minimize": "Hidde function elements",
+  "tooltip_console": "Open/Close console",
+  "var_menu_select_var": "Select a var",
+  "var_menu_select_all": "Select",
+  "var_menu_select_function": "Select a function",
+  "expression_menu_select": "Select an expression",
+  "$sin": "Matematica.sen"
+
 }

+ 71 - 1
i18n/es/ui.json

@@ -1,12 +1,21 @@
 {
   "function": "function",
+  "btn_clear": "Clear",
   "btn_function": "Function",
+  "btn_arithmetic_plus": "Sum",
+  "btn_arithmetic_minus": "Minus",
+  "btn_arithmetic_multiplication": "Multiplication",
+  "btn_arithmetic_division": "Division",
+  "btn_arithmetic_module": "Module",
+  "btn_break":"Break",
+  "btn_case":"Case",
   "start": "start",
   "void": "void",
   "integer": "integer",
   "real": "real",
   "program": "program",
   "text": "text",
+  "text_start": "text",
   "boolean": "boolean",
   "true": "true",
   "false": "false",
@@ -21,5 +30,66 @@
   "text_comment_main": "This is the main function...",
   "text_read_var": "Reading data",
   "text_write_var": "Writing data",
-  "text_comment": "Comment"
+  "text_command_read":"read",
+  "text_command_write":"write",
+  "text_comment": "Comment",
+  "text_attribution": "Attribution",
+  "text_if":"if",
+  "text_break":"break",
+  "text_else":"else",
+  "text_return":"return",
+  "text_btn_return":"Return",
+  "text_for":"for",
+  "text_code_while":"while",
+  "text_code_do":"do",
+  "text_command_do":"do",
+  "text_code_switch": "switch",
+  "text_code_case": "case",
+  "text_logic_expression": "Logic Expression",
+  "text_arithmetic_expression": "Arithmetic Expression",
+  "text_iftrue": "If true then",
+  "text_repeatNtimes": "Repeat N times",
+  "text_receives": "receives",
+  "text_whiletrue": "While true",
+  "text_dowhiletrue": "Do while true",
+  "text_switch": "Switch",
+  "text_functioncall": "Function call",
+  "text_value": "Value",
+  "text_operator": "Operator",
+  "text_parentheses": "Parentheses",
+  "text_change": "Change",
+  "text_teacher_algorithm": "Algorithm",
+  "text_teacher_algorithm_include": "Include the following algorithm in exercise",
+  "text_teacher_test_case": "Test cases",
+  "text_teacher_config": "Settings",
+  "text_teacher_data_types": "Data types",
+  "text_teacher_commands": "Commands",
+  "text_teacher_functions": "Functions",
+  "text_teacher_create_functions": "Create new functions",
+  "text_teacher_create_movement_functions": "Move functions",
+  "text_teacher_test_case_input": "Input",
+  "text_teacher_test_case_output": "Output",
+  "text_teacher_test_case_actions": "Actions",
+  "text_teacher_test_case_add": "Add test cases",
+  "text_header_ivprog_functions": "iVProg Functions",
+  "text_menu_functions_math":"Mathematics",
+  "text_menu_functions_text":"Text",
+  "text_menu_functions_arrangement":"Arrangement",
+  "text_menu_functions_conversion":"Conversion",
+  "tooltip_visual": "Visual programming",
+  "tooltip_textual": "Textual programming",
+  "tooltip_upload": "Upload code file",
+  "tooltip_download": "Download code file",
+  "tooltip_undo": "Undo",
+  "tooltip_redo": "Redo",
+  "tooltip_run": "Run program",
+  "tooltip_evaluate": "Evaluate program",
+  "tooltip_help": "Help",
+  "tooltip_add_global": "Add global variable",
+  "tooltip_minimize": "Hidde function elements",
+  "tooltip_console": "Open/Close console",
+  "var_menu_select_var": "Select a var",
+  "var_menu_select_all": "Select",
+  "var_menu_select_function": "Select a function",
+  "expression_menu_select": "Select an expression"
 }

+ 0 - 53
i18n/i18n-engine.js

@@ -1,53 +0,0 @@
-
-function i18n(identifier) {
-  if (!i18n.db[i18n.locale]) {
-    if (!i18n.db['en'][identifier]) {
-      return "{MISSING_I18N_IDENTIFIER}";
-    }
-    return i18n.db['en'][identifier];
-  }
-  if (!i18n.db[i18n.locale][identifier]) {
-    return "{MISSING_I18N_IDENTIFIER}";
-  }
-  return i18n.db[i18n.locale][identifier];
-}
-
-i18n.set = function(locale, identifier, translate) {
-  if (!i18n.db[locale]) {
-    i18n.db[locale] = {};
-  }
-  i18n.db[locale][identifier] = translate;
-}
-
-i18n.updateLocale = function(new_locale) {
-  i18n.locale = new_locale;
-  $( "data.i18n" ).each(function( index ) {
-    $( this ).text(i18n($( this ).val()));
-  });
-}
-
-i18n.locale = iLMparameters.lang;
-i18n.db = {};
-
-$.ajaxSetup({
-    async: false
-});
-
-$.getJSON('i18n/i18n-database.json', function(data) {
-    for (x in data) {
-      l = data[x];
-      i18n.set('en', x, l.en);
-      i18n.set('es', x, l.es);
-      i18n.set('pt', x, l.pt);
-    }
-});
-
-$.ajaxSetup({
-    async: true
-});
-
-$( document ).ready(function() {
-  $( "data.i18n" ).each(function( index ) {
-    $( this ).text(i18n($( this ).val()));
-  });
-});

+ 72 - 2
i18n/pt/ui.json

@@ -1,6 +1,14 @@
 {
   "function": "funcao",
+  "btn_clear": "Limpar",
   "btn_function": "Função",
+  "btn_arithmetic_plus": "Adição",
+  "btn_arithmetic_minus": "Subtração",
+  "btn_arithmetic_multiplication": "Multiplicação",
+  "btn_arithmetic_division": "Divisão",
+  "btn_arithmetic_module": "Módulo",
+  "btn_break":"Pare",
+  "btn_case":"Caso",
   "start": "inicio",
   "void": "vazio",
   "integer": "inteiro",
@@ -10,9 +18,10 @@
   "real": "real",
   "program": "programa",
   "text": "cadeia",
+  "text_start": "texto",
   "boolean": "logico",
   "true": "verdadeiro",
-  "false": "fals0",
+  "false": "falso",
   "variable": "Variável",
   "command": "Comando",
   "new_parameter": "novo_parametro",
@@ -24,8 +33,69 @@
   "text_comment_main": "Esta é a função principal...",
   "text_read_var": "Leitura de dados",
   "text_write_var": "Escrita de dados",
+  "text_command_read":"leia",
+  "text_command_write":"escreva",
+  "text_return":"retorne",
+  "text_btn_return":"Retorno",
   "text_comment": "Comentário",
   "join_or": "ou",
   "matrix_string": "matriz de $0",
-  "vector_string": "vetor de $0"
+  "vector_string": "vetor de $0",
+  "text_attribution": "Atribuição",
+  "text_if":"se",
+  "text_break":"pare",
+  "text_else":"senao",
+  "text_for":"para",
+  "text_code_while":"enquanto",
+  "text_code_do":"faca",
+  "text_command_do":"faça",
+  "text_code_switch": "escolha",
+  "text_code_case": "caso",
+  "text_logic_expression": "Expressão Lógica",
+  "text_arithmetic_expression": "Expressão Aritmética",
+  "text_iftrue": "Se verdadeiro então",
+  "text_repeatNtimes": "Repita N vezes",
+  "text_receives": "recebe",
+  "text_whiletrue": "Enquanto verdadeiro",
+  "text_dowhiletrue": "Faça enquanto verdadeiro",
+  "text_switch": "Escolha",
+  "text_functioncall": "Chamada de função",
+  "text_value": "Valor",
+  "text_operator": "Operador",
+  "text_parentheses": "Parênteses",
+  "text_change": "Alterar",
+  "text_teacher_algorithm": "Algoritmo",
+  "text_teacher_algorithm_include": "Incluir o algoritmo abaixo no exercício",
+  "text_teacher_test_case": "Casos de teste",
+  "text_teacher_config": "Configurações",
+  "text_teacher_data_types": "Tipos de dados",
+  "text_teacher_commands": "Comandos",
+  "text_teacher_functions": "Funções",
+  "text_teacher_create_functions": "Criar novas funções",
+  "text_teacher_create_movement_functions": "Movimentar funções",
+  "text_teacher_test_case_input": "Entrada",
+  "text_teacher_test_case_output": "Saída",
+  "text_teacher_test_case_actions": "Ações",
+  "text_teacher_test_case_add": "Adicionar caso de teste",
+  "text_header_ivprog_functions": "Funções do iVProg",
+  "text_menu_functions_math":"Matemática",
+  "text_menu_functions_text":"Texto",
+  "text_menu_functions_arrangement":"Arranjo",
+  "text_menu_functions_conversion":"Conversão",
+  "tooltip_visual": "Programação visual",
+  "tooltip_textual": "Programação textual",
+  "tooltip_upload": "Upload de código fonte",
+  "tooltip_download": "Download do código fonte",
+  "tooltip_undo": "Desfazer",
+  "tooltip_redo": "Refazer",
+  "tooltip_run": "Executar o programa",
+  "tooltip_evaluate": "Avaliar o programa",
+  "tooltip_help": "Ajuda",
+  "tooltip_add_global": "Adicionar variável global",
+  "tooltip_minimize": "Ocultar os elementos da função",
+  "tooltip_console": "Abrir/fechar o terminal",
+  "var_menu_select_var": "Selecione uma variável",
+  "var_menu_select_all": "Selecione",
+  "var_menu_select_function": "Selecione uma função",
+  "expression_menu_select": "Selecione uma expressão"
 }

+ 124 - 74
index.html

@@ -1,87 +1,137 @@
 <!DOCTYPE html>
 <html>
-<head>
-  <link rel="stylesheet" type="text/css" href="js/semantic/semantic.min.css">
-  <style>
-    .ivprog-io-output {
-      border: 1px solid gainsboro;
-      width: 80%;
-      height: 360px;
-      overflow-y: scroll;
-      background-color: black;
-      color: white;
-    }
-
-    .ivprog-io-input {
-      width: 80%;
-      margin-top: 10px;
-      border: 1.5px solid green;
-      height: 3rem;
-      color: black;
-      font-size: 12pt;
-    }
-  </style>
-  <title></title>
-</head>
-<body>
-    <div style="padding-top: 50px;content: ''"></div>
-  <div class="ui container grid">
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <meta http-equiv="cache-control" content="no-cache">
+    <meta http-equiv="cache-control" content="no-store">
+    <meta http-equiv="cache-control" content="max-age=0">
+    <meta http-equiv="expires" content="-1">
+    <meta http-equiv="pragma" content="no-cache">
+    <title></title>
+    <link rel="stylesheet" type="text/css" href="js/semantic/semantic.min.css">
+    <link rel="stylesheet" type="text/css" href="css/ivprog-visual-1.0.css">
+    <link rel="stylesheet" type="text/css" href="css/ivprog-term.css">
+    <script src="js/jquery-3.3.1.min.js"></script>
+    <script src="js/iassign-integration-functions.js"></script>
+    <script src="build/ivprog.bundle.js"></script>
+    <script src="js/semantic/semantic.min.js"></script>
+    <script src="js/semantic/semantic-buttons.js"></script>
+
+    <script src="js/jquery-ui.js"></script>
+    <script src="js/Sortable.js"></script>
     
-    <div class="four wide column">
-      <div class="row">
-        <textarea class="ui form control" name="input" id="input" cols="100" rows="30">
-          programa {
-
-            funcao inicio() {
-              cadeia a = "mustache"
-              cadeia b = "mostacheh"
-              escreva(editDist(a,b,comprimento(a), comprimento(b)))
-            }
-        
-            funcao inteiro editDist(cadeia str1 , cadeia str2 , inteiro m ,inteiro n) {
-              inteiro l = m + 1
-              inteiro c = n + 1
-              inteiro i, j
-              inteiro mat[l][c]
-              para(i = 0; i <= m; i = i + 1 ) {
-                para(j = 0; j <= n; j = j + 1) {
-                  se (i==0) {
-                    mat[i][j] = j
-                  } senao se (j == 0) {
-                    mat[i][j] = i
-                  } senao se (char_at(str1, i-1) == char_at(str2, j-1)) {
-                    mat[i][j] = mat[i-1][j-1]
-                  } senao {
-                    mat[i][j] = 1 + Matematica.minimo({mat[i][j-1], mat[i-1][j], mat[i-1][j-1]})
-                  }
-                }
-              }
-              retorne mat[m][n]
-            }
+  </head>
+  <body>
+
+    <div class="ui height_100 add_accordion">
+
+      <div class="title default_visual_title">
+        <i class="dropdown icon"></i>
         
-          }
-        </textarea>
       </div>
-      <div class="row">
-          <button class="ui button" id="btn">Run</button>
+
+    <div class="content height_100">
+   
+    <div class="ui one column doubling stackable grid container">
+      <div class="column">
+        <div class="ui container main_title">
+          <h2>iVProg</h2>
+          <span>interactive coding</span>
+        </div>
+
+        <div class="ui container content_margin">
+          <div class="content_sub_margin">
+              <div class="blue ui ivprog_format buttons">
+                <button class="ui button active visual_coding_button">Visual</button>
+                <button class="ui button textual_coding_button">Textual</button>
+              </div>
+            </div>
+          </div>
+
       </div>
     </div>
-    <div class="six wide column">
-      <div id="dom-out" class="ivprog-io-output">
 
-      </div>
-      <input id="dom-in" type="text" class="ivprog-io-input">
+    <div class="ui container main_title only_in_frame" style="display: none;">
+      <h2>iVProg</h2>
+      <span class="subtext">interactive coding</span>
     </div>
-    <div class="six wide column">
-        <div style="overflow-y: scroll; height: 70%;">
-            <pre id="json-renderer" class="ui right floated"></pre>
+
+    <div class="ui raised container segment div_to_body">
+
+      <div class="ui icon menu center aligned container" style="width: 438px; margin-top: -25px;">
+        <a class="item active visual_coding_button">
+          <i class="window maximize outline icon"></i>
+        </a>
+        <a class="item textual_coding_button">
+          <i class="code icon"></i>
+        </a>
+        <a class="item upload_file_button disabled">
+          <i class="upload icon"></i>
+        </a>
+        <a class="item download_file_button disabled">
+          <i class="download icon"></i>
+        </a>
+        <a class="item undo_button disabled">
+          <i class="undo icon"></i>
+        </a>
+        <a class="item redo_button disabled">
+          <i class="redo icon"></i>
+        </a>
+        <a class="item run_button">
+          <i class="play icon"></i>
+        </a>
+        <a class="item assessment assessment_button">
+          <i class="check icon"></i>
+        </a>
+        <a class="item help_button">
+          <i class="help icon"></i>
+        </a>
+      </div>
+
+      <div class="ui one column container segment ivprog_visual_panel loading">
+
+        <div class="global_var">
+          
+          <div class="ui icon button add-globalVar-button add_global_button"><i class="icon superscript"></i></div>
+
+          <div class="list_globals"></div>
+
+        </div>
+
+        <div class="all_functions list-group" id="listWithHandle">
+
+        </div>
+
+
+        <div class="ui teal small labeled icon button add_function_button">
+          <data class="i18n" value="ui:btn_function">Function</data>
+          <i class="add icon"></i>
         </div>
+        <div class="program_final"></div>
+
+      </div>
+
+
+      <div class="ui one column container segment ivprog_textual_panel loading" style="display: none;">
+        <textarea class="ivprog_textual_code" readonly></textarea>
+      </div>
+
+      <div id='ivprog-term' class="six column wide">
+        <div class="div_toggle_console"><i class="inverted terminal icon green button_toggle_console"></i></div>
+      </div>
+    </div>
+
     </div>
+
   </div>
-  
-  
-</body>
-<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
-<script type="text/javascript" src="js/jquery.json-editor.min.js"></script>
-<script type="text/javascript" src="build/ivprog.bundle.js"></script>
+
+    <script>
+      $(document).ready(() => {
+        ivprogCore.LocalizedStrings.updateTagText();
+        ivprogCore.initVisualUI();
+        prepareEnvironment();
+      });
+    </script>
+
+  </body>
 </html>

+ 90 - 0
js/assessment/ivprogAssessment.js

@@ -0,0 +1,90 @@
+import { IVProgParser } from "./../ast/ivprogParser";
+import { SemanticAnalyser } from "./../processor/semantic/semanticAnalyser";
+import { IVProgProcessor } from "./../processor/ivprogProcessor";
+import { InputTest } from "./../util/inputTest";
+import { OutputTest } from "./../util/outputTest";
+
+export class IVProgAssessment {
+
+  constructor (textCode, testCases, domConsole) {
+    this.textCode = textCode;
+    this.testCases = testCases;
+    this.domConsole = domConsole;
+  }
+
+  runTest () {
+    try {
+      // try and show error messages through domconsole
+      const parser = IVProgParser.createParser(this.textCode);
+      const semantic = new SemanticAnalyser(parser.parseTree());
+      const validTree = semantic.analyseTree();
+      // loop test cases and show messages through domconsole
+      const partialTests = this.testCases.map( (t, name) => {
+        return this.partialEvaluateTestCase(new IVProgProcessor(validTree), t.input, t.output, name);
+      });
+      const testResult = partialTests.reduce((acc, curr) => acc.then( v => curr(v)), Promise.resolve(0));
+      return testResult.then(total => Promise.resolve(total / this.testCases.length))
+        .catch(err => {
+          this.domConsole.err("Erro durante a execução do programa");// try and show error messages through domconsole
+          this.domConsole.err(err.message);
+          return Promise.resolve(0);
+      });
+    } catch (error) {
+      this.domConsole.err("Erro durante a execução do programa");// try and show error messages through domconsole
+      this.domConsole.err(error.message);
+      return Promise.resolve(0);
+    }
+  }
+
+  evaluateTestCase (prog, inputList, outputList, name, accumulator) {
+    const outerThis = this;
+    const input = new InputTest(inputList);
+    const output = new OutputTest();
+    prog.registerInput(input);
+    prog.registerOutput(output);
+    const startTime = Date.now()
+    return prog.interpretAST().then( _ => {
+      const millis = Date.now() - startTime;
+      if (input.inputList.length !== input.index) {
+        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou, ainda restam entradas!`);
+        outerThis.domConsole.info(`Levou ${millis}ms`);
+        return Promise.resolve(accumulator + 1 * (input.index/inputList.length));
+      } else if (output.list.length < outputList.length) {
+        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
+        outerThis.domConsole.info(`Levou ${millis}ms`);
+        return Promise.resolve(accumulator + 1 * (output.list.length/outputList.length));
+      } else if (output.list.length > outputList.length) {
+        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
+        outerThis.domConsole.info(`Levou ${millis}ms`);
+        return Promise.resolve(accumulator + 1 * (outputList.length/output.list.length));
+      } else {
+        const isOk = outerThis.checkOutput(output.list, outputList);
+        if(!isOk) {
+          outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
+          outerThis.domConsole.info(`Levou ${millis}ms`);
+          return Promise.resolve(accumulator);
+        } else {
+          outerThis.domConsole.info(`Caso de teste ${name + 1}: OK!`);
+          outerThis.domConsole.info(`Levou ${millis}ms`);
+          return Promise.resolve(accumulator + 1);
+        }
+      }
+    }).catch( _ => Promise.resolve(accumulator));
+  }
+
+  partialEvaluateTestCase (prog, inputList, outputList, name) {
+    let partial = (accumulator) => this.evaluateTestCase(prog, inputList, outputList, name, accumulator)
+    patrial = partial.bind(this);
+    return partial;
+  }
+
+  checkOutput (aList, bList) {
+    for (let i = 0; i < aList.length; i++) {
+      const outValue = aList[i];
+      if(outValue != bList[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+}

+ 302 - 13
js/iassign-integration-functions.js

@@ -1,6 +1,6 @@
 // Função para ler parâmetros informados pelo iTarefa via URL
 // Apesar de não ser obrigatório, será muito útil para capturar os parâmetros
-function getParameterByName(name, defaultReturn = null) {
+function getParameterByName (name, defaultReturn = null) {
     var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
     return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defaultReturn;
 }
@@ -12,47 +12,336 @@ var iLMparameters = {
     iLM_PARAM_SendAnswer: getParameterByName("iLM_PARAM_SendAnswer"),
     iLM_PARAM_AssignmentURL: getParameterByName("iLM_PARAM_AssignmentURL"),
     iLM_PARAM_Assignment: getParameterByName("iLM_PARAM_Assignment"),
-    lang: getParameterByName("lang", "en")
+    lang: getParameterByName("lang", "pt")
 };
 
 // Set the lang parameter to the localStorage for easy access
 // and no dependency to the global scope, avoind future 'strict mode' problems
-localStorage.setItem('ivprog.lang', iLMparameters.lang);
+//localStorage.setItem('ivprog.lang', iLMparameters.lang);
 
 // Função chamada pelo iTarefa quando o professor finaliza a criação da atividade
 // ou quando o aluno finaliza a resolução do exercício
 // O retorno é um JSON com os dados do exercício ou da resolução
 // Esse retorno será armazenado no banco de dados do Moodle, pelo iTarefa
-function getAnswer() {
+function getAnswer () {
     // Se o parâmetro "iLM_PARAM_SendAnswer" for false,
     // então trata-se de resolução de atividade
     if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-        // Montar o retorno da resposta do aluno
-        
+        // Montar o retorno com a resposta do aluno
+        var contentToSend = previousContent.split("\n::algorithm::")[0];
+        contentToSend += '\n::algorithm::\n';
+        contentToSend += JSON.stringify(window.program_obj);
+
+        contentToSend += '\n::logs::';
+        contentToSend += getTrackingLogs();
+
+        return contentToSend;
+
     } else {
-        
+        // Montar o retorno com a criação da atividade do professor
+        var ret = ' { ' + prepareTestCases() 
+            + ',\n"settings_data_types": \n' + JSON.stringify($('form[name="settings_data_types"]').serializeArray()) 
+            + ',\n"settings_commands": \n' + JSON.stringify($('form[name="settings_commands"]').serializeArray()) 
+            + ',\n"settings_functions": \n' + JSON.stringify($('form[name="settings_functions"]').serializeArray()) 
+            + ' } ';
+
+        if ($("input[name='include_algo']").is(':checked')) {
+            ret += '\n::algorithm::\n';
+            ret += JSON.stringify(window.program_obj);
+        }
+
+        return ret;
     }
 }
 
+function prepareTestCases () {
+    var ret = ' \n "testcases" : [ '
+    var test_cases_array = $('form[name="test_cases"]').serializeArray();
+    for (var i = 0; i < test_cases_array.length; i = i + 2) {
+        ret += '\n{ ';
+        ret += '\n "input": [';
+        var inps = test_cases_array[i].value.match(/[^\r\n]+/g);
+        if (inps) {
+            for (var j = 0; j < inps.length; j++) {
+                ret += '"' + inps[j] + '"';
+                if ((j + 1) < inps.length) {
+                    ret += ', ';
+                }
+            }
+        }
+        ret += '], \n "output": [';
+        var outs = test_cases_array[i+1].value.match(/[^\r\n]+/g);
+        if (outs) {
+            for (var j = 0; j < outs.length; j++) {
+                ret += '"' + outs[j] + '"';
+                if ((j + 1) < outs.length) {
+                    ret += ', ';
+                }
+            }
+        }
+        ret += ']';
+        ret += '\n}'
+        if ((i + 2) < test_cases_array.length) {
+            ret += ',';
+        }
+    }
+    ret += '\n] ';
+    return ret;
+}
+
 // Função chamada pelo iTarefa para receber a nota do aluno na atividade
 // O retorno é um valor entre 0.0 e 1.0
-function getEvaluation() {
+function getEvaluation () {
     if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-        // Calcula a nota do aluno:
-
         // A chamada do método abaixo é obrigatória!
         // Observe que a chamada parte do iLM para o iTarefa
-        parent.getEvaluationCallback(0);
+        //parent.getEvaluationCallback(window.studentGrade);
+
+        runCodeAssessment();
     }
 }
 
 
+var testCases = null;
+var settingsDataTypes = null;
+var settingsCommands = null;
+var settingsFunctions = null;
+var algorithm_in_ilm = null;
+var previousContent = null;
+
 // Função para que o iMA leia os dados da atividade fornecidos pelo iTarefa
-function getiLMContent() {
+function getiLMContent () {
 
     // O parâmetro "iLM_PARAM_Assignment" fornece o URL do endereço que deve ser
     // requisitado via AJAX para a captura dos dados da atividade
     $.get(iLMparameters.iLM_PARAM_Assignment, function (data) {
-        
+        if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+            previousContent = data;
+            prepareActivityToStudent(data);
+        } else {
+
+        }
+    });
+}
+
+function prepareActivityToStudent (ilm_cont) {
+    var content = JSON.parse(ilm_cont.split('\n::algorithm::')[0]);
+    testCases = content.testcases;
+    settingsDataTypes = content.settings_data_types;
+    settingsCommands = content.settings_commands;
+    settingsFunctions = content.settings_functions;
+    if (ilm_cont.split('\n::algorithm::')[1]) {
+        algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
+        window.program_obj.functions = JSON.parse(algorithm_in_ilm).functions;
+        window.program_obj.globals = JSON.parse(algorithm_in_ilm).globals;
+    }
+    $('.assessment_button').removeClass('disabled');
+    renderAlgorithm();
+}
+
+// Função para organizar se para criação, visualização ou resolução de atividade
+function prepareEnvironment () {
+    if ((iLMparameters.iLM_PARAM_AssignmentURL == "true") && (iLMparameters.iLM_PARAM_SendAnswer == "true")) {
+        prepareActivityCreation();
+    }
+}
+
+$(document).ready(function() {
+
+    // Se iLM_PARAM_SendAnswer for false, então trata-se de resolução de atividade,
+    // portanto, a "DIV" de resolução é liberada
+    if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+        //$('.resolucao').css("display","block");
+        getiLMContent();
+
+
+        $( document ).ready(function() {
+            $('.div_to_body').mousemove(function(e) {
+                trackingMatrix.push(adCoords(e, 0));
+            });
+
+            $('.div_to_body').click(function(e) {
+                trackingMatrix.push(adCoords(e, 1));                    
+            });
+
+        });
+
+    } else {
+        // Caso não esteja em modo de resolução de atividade, a visualização no momento
+        // é para a elaboração de atividade:
+        //$('.elaboracao').css("display","block");
+    }
+
+    if (!testCases) {
+        $('.assessment_button').addClass('disabled');
+    }
+
+});
+
+// Função para preparar a interface para o professor criar atividade:
+function prepareActivityCreation () {
+
+    $('.add_accordion').addClass('accordion');
+
+    $('.default_visual_title').toggle();
+    $('.default_visual_title').append('<span>'+LocalizedStrings.getUI('text_teacher_algorithm')+'</span>');
+    $('.height_100').removeClass('height_100');
+    $('.main_title').remove();
+    $('.ui.accordion').addClass('styled');
+    
+    $('<div class="ui checkbox"><input type="checkbox" name="include_algo" class="include_algo" tabindex="0" class="hidden"><label>'+LocalizedStrings.getUI('text_teacher_algorithm_include')+'</label></div>').insertBefore('.content_margin');
+    
+    var cases_test_div = $('<div class="ui accordion styled"><div class="active title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case')+'</div><div class="active content"></div></div>');
+
+    cases_test_div.insertBefore('.accordion');
+
+    var config_div = $('<div class="ui accordion styled"><div class="title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_config')+'</div><div class="content"></div></div>');
+
+    config_div.insertAfter(cases_test_div);
+
+    $('.ui.accordion').accordion();
+
+    $('.ui.checkbox').checkbox();
+
+    prepareTableSettings(config_div.find('.content'));
+
+    prepareTableTestCases(cases_test_div.find('.content'));
+}
+
+function prepareTableTestCases (div_el) {
+
+    var table_el = '<form name="test_cases"><table class="ui blue table"><thead><tr><th width="30px">#</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_input')+'</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_output')+'</th><th width="80px">'+LocalizedStrings.getUI('text_teacher_test_case_actions')+'</th></tr></thead>'
+            + '<tbody class="content_cases"></tbody></table></form>';
+
+    div_el.append(table_el);
+
+    div_el.append('<button class="ui teal labeled icon button button_add_case"><i class="plus icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case_add')+'</button>');
+
+    $('.button_add_case').on('click', function(e) {
+        addTestCase();
+    });
+
+}
+
+var hist = false;
+
+function addTestCase () {
+    var new_row = $('<tr><td class="counter"></td><td class="expandingArea"><textarea rows="1" name="input" class="text_area_input"></textarea></td><td class="expandingArea"><textarea rows="1" name="output" class="text_area_output"></textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>');
+    $('.content_cases').append(new_row);
+
+    new_row.find('.button_remove_case').click(function(e) {
+        new_row.remove();
+        updateTestCaseCounter();
+    });
+
+    $('textarea').on('input', function(e) {
+        var lines = $(this).val().split('\n').length;
+        $(this).attr('rows', lines);
     });
+    
+    updateTestCaseCounter();
+
+     $('.text_area_output').keydown(function(e) {
+        var code = e.keyCode || e.which;
+        if (code == 9 && $(this).closest("tr").is(":last-child")) {
+            hist = true;
+            addTestCase();
+        }
+     });
+     if (!hist) {
+        $( ".content_cases tr:last" ).find('.text_area_input').focus();
+     } else {
+        hist = false;
+     }
 }
+
+function updateTestCaseCounter () {
+    var i = 1;
+    $( ".content_cases" ).find('tr').each(function() {
+      $( this ).find('.counter').text(i);
+      i ++;
+    });
+}
+
+function prepareTableSettings (div_el) {
+    div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_data_types')+'</h4>');
+    div_el.append('<form name="settings_data_types"><div class="ui stackable five column grid">'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="integer_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('integer')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="real_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('real')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="text_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="boolean_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('boolean')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="void_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('void')+'</label></div></div>'
+        +'</div></form>');
+
+
+    div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_commands')+'</h4>');
+    div_el.append('<form name="settings_commands"><div class="ui stackable three column grid">'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_read" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_read_var')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_write" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_write_var')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_comment" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_comment')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_attribution" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_attribution')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_functioncall" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_functioncall')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_iftrue" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_iftrue')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_repeatNtimes" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_repeatNtimes')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_while" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_whiletrue')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_dowhile" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_dowhiletrue')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_switch" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_switch')+'</label></div></div>'
+        +'</div></form>');
+
+    div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_functions')+'</h4>');
+    div_el.append('<form name="settings_functions"><div class="ui stackable one column grid">'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_creation" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_functions')+'</label></div></div>'
+        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_move" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_movement_functions')+'</label></div></div>'
+        +'</div></form>');
+
+    $('.ui.checkbox').checkbox();
+
+
+}
+
+function getTrackingLogs () {
+    var ret = "";
+    for (var i = 0; i < trackingMatrix.length; i++) {
+        ret += "\n" + trackingMatrix[i][0] + "," + trackingMatrix[i][1] + "," + trackingMatrix[i][2];
+        if (trackingMatrix[i][2] === 1) {
+            ret += ',"' + trackingMatrix[i][3] + '"';
+        }
+    }
+    return ret;
+}
+
+// Tracking mouse movements
+var trackingMatrix = [];
+
+function adCoords(e, code){
+    var x = e.pageX; 
+    var y = e.pageY;
+    if (code === 1) {
+        return [x, y, code, e.target.classList['value']];
+    } else {
+        return [x, y, code];
+    }
+}
+
+$( document ).ready(function() {
+
+    if (inIframe()) {
+        orderIcons();
+    }
+
+});
+
+function orderIcons() {
+    $('.ui.one.column.doubling.stackable.grid.container').css('display', 'none');
+    $('.only_in_frame').css('display', 'block');
+    
+}
+
+
+function inIframe () {
+    try {
+        return window.self !== window.top;
+    } catch (e) {
+        return true;
+    }
+}

+ 138 - 0
js/io/domConsole.js

@@ -0,0 +1,138 @@
+import $ from 'jquery';
+
+export class DOMConsole {
+
+  static get USER () {
+    return 0;
+  }
+
+  static get INFO () {
+    return 1;
+  }
+
+  static get ERR () {
+    return 2;
+  }
+
+  constructor (elementID) {
+    this.input = null;
+    this.needInput = false;
+    this.termDiv = null;
+    this.anyKey = false;
+    this.parent = $(elementID);
+    this.setup();
+    this.inputListeners = [];
+  }
+
+  setup () {
+    this._setupDom();
+    this._setupEvents();
+  }
+
+  _setupEvents () {
+    this.input.on("keydown", (event) => {
+      if (!this.needInput) {
+        event.preventDefault();
+        return;
+      }
+      const keyCode = event.which;
+      if (keyCode === 13 || this.anyKey) {
+        let text = this.input.val();
+        text = text.replace('[\n\r]+', '');
+        this.notifyListeners(text);
+        this.write(text);
+        this.input.val("");
+      }
+    });
+  }
+
+  _setupDom () {
+    this.termDiv = $("<div></div>");
+    this.termDiv.addClass("ivprog-term-div");
+    this.input = $('<input text="type">')
+    this.input.addClass("ivprog-term-input");
+    this.termDiv.append(this.input);
+    this.parent.append(this.termDiv);
+  }
+
+  notifyListeners (text) {
+    this.inputListeners.forEach(resolve => resolve(text));
+    this.inputListeners.splice(0, this.inputListeners.length);
+    this.hideInput();
+    this.anyKey = false;
+  }
+
+  write (text) {
+    this._appendText(text, DOMConsole.USER);
+  }
+
+  info (text) {
+    this._appendText(text, DOMConsole.INFO);
+  }
+
+  err (text) {
+    this._appendText(text, DOMConsole.ERR);
+  }
+
+  _appendText (text, type) {
+    const divClass = this.getClassForType(type);
+    const textDiv = $("<div></div>");
+    textDiv.addClass(divClass);
+    textDiv.append(text);
+    textDiv.insertBefore(this.input);
+    this.scrollTerm();
+  }
+
+  scrollTerm () {
+    this.termDiv.animate({
+      scrollTop: this.termDiv.prop('scrollHeight')
+    }, 0);
+  }
+
+  getClassForType (type) {
+    switch (type) {
+      case DOMConsole.USER:
+        return "ivprog-term-userText";
+      case DOMConsole.INFO:
+        return "ivprog-term-info";
+      case DOMConsole.ERR:
+        return "ivprog-term-error";
+    }
+  }
+
+  dispose () {
+    this.parent.off();
+    this.input.off();
+    this.input = null;
+    this.parent.empty();
+  }
+
+  showInput () {
+    this.needInput = true;
+    this.input.show();
+    this.input.focus();
+  }
+
+  hideInput () {
+    this.needInput = false;
+    this.input.hide();
+  }
+
+  requestInput (callback, anyKey = false) {
+    this.inputListeners.push(callback);
+    this.anyKey = anyKey;
+    this.showInput();
+  }
+
+  sendOutput (text) {
+    text.split("\n").forEach(t => {
+      t = t.replace(/\t/g,'&#9;');
+      this.write(t)
+    });
+  }
+
+  clear () {
+    this.input.parent().children().not(this.input).remove();
+    this.input.val("");
+  }
+}

+ 10 - 47
js/main.js

@@ -1,50 +1,13 @@
-import { IVProgParser } from './ast/ivprogParser';
-import { IVProgProcessor } from './processor/ivprogProcessor';
-import { SemanticAnalyser } from "./processor/semantic/semanticAnalyser";
-import {DOMInput} from './io/domInput';
-import {DOMOutput} from './io/domOutput';
-import { LanguageService } from './services/languageService';
-import { LocalizedStrings } from './services/localizedStringsService';
+import { runner } from './runner';
+import { initVisualUI } from './visualUI/functions';
+import { LocalizedStrings} from './services/localizedStringsService';
+import { i18nHelper } from "./services/i18nHelper";
 
-const ivprogLexer = LanguageService.getCurrentLexer();
-console.log(LocalizedStrings.getUI('start'));
+const i18n = i18nHelper.i18n
 
-// const lexer = new ivprogLexer(new InputStream(input));
-// const stream = new CommonTokenStream(lexer);
-// stream.fill();
-// let i = 1;
-// let token = null;
-// while ((token = stream.LT(i)).type !== ivprogLexer.EOF && token.type !== ivprogLexer.WHITESPACE) {
-//     console.log(`${token.type}-${token.text}`);
-//     console.log('\n')
-//     i++;
-// }
-// const anaSin = new IVProgParser(input, ivprogLexer);
-const editor = new JsonEditor('#json-renderer', {});
-const domIn = new DOMInput('#dom-in');
-const domOut = new DOMOutput('#dom-out');
-// proc.interpretAST().then( sto => {
-//   console.log(sto.applyStore('a'));
-// }).catch(e => console.log(e));
-try {
-  $('#btn').click( () => {
-    const input = $('#input').val();
-    const analiser = new IVProgParser(input, ivprogLexer);
-    try {
-      const data = analiser.parseTree();
-      const semAna = new SemanticAnalyser(data);
-      const proc = new IVProgProcessor(semAna.analyseTree());
-      proc.registerInput(domIn);
-      domOut.clear();
-      proc.registerOutput(domOut);
-      proc.interpretAST().then(_ => editor.load({}))
-        .catch( e => {alert(e);console.log(e);});
-    } catch (error) {
-      alert(error);
-      console.log(error);
-    }
-    
-  });
-} catch(a) {
-  console.log(a);
+export {
+  runner,
+  initVisualUI,
+  LocalizedStrings,
+  i18n
 }

+ 19 - 0
js/processor/ivprogProcessor.js

@@ -45,10 +45,14 @@ export class IVProgProcessor {
   }
 
   registerInput (input) {
+    if(this.input !== null)
+      this.input = null;
     this.input = input;
   }
 
   registerOutput (output) {
+    if(this.output !== null)
+      this.output = null;
     this.output = output;
   }
 
@@ -66,7 +70,22 @@ export class IVProgProcessor {
     }
   }
 
+  prepareState () {
+    if(this.stores !== null) {
+      for (let i = 0; i < this.stores.length; i++) {
+        delete this.stores[i];
+      }
+      this.stores = null;
+    }
+    if(this.globalStore !== null)
+      this.globalStore = null;
+    this.globalStore = new Store("$global");
+    this.stores = [this.globalStore];
+    this.context = [Context.BASE];
+  }
+
   interpretAST () {
+    this.prepareState();
     this.initGlobal();
     const mainFunc = this.findMainFunction();
     if(mainFunc === null) {

+ 49 - 0
js/runner.js

@@ -0,0 +1,49 @@
+import { IVProgParser } from './ast/ivprogParser';
+import { IVProgProcessor } from './processor/ivprogProcessor';
+import {DOMConsole} from './io/domConsole';
+import { LanguageService } from './services/languageService';
+import { SemanticAnalyser } from './processor/semantic/semanticAnalyser';
+
+export function runner () {
+const ivprogLexer = LanguageService.getCurrentLexer();
+
+
+// const lexer = new ivprogLexer(new InputStream(input));
+// const stream = new CommonTokenStream(lexer);
+// stream.fill();
+// let i = 1;
+// let token = null;
+// while ((token = stream.LT(i)).type !== ivprogLexer.EOF && token.type !== ivprogLexer.WHITESPACE) {
+//     console.log(`${token.type}-${token.text}`);
+//     console.log('\n')
+//     i++;
+// }
+// const anaSin = new IVProgParser(input, ivprogLexer);
+const editor = new JsonEditor('#json-renderer', {});
+const domConsole = new DOMConsole("#console");
+// proc.interpretAST().then( sto => {
+//   console.log(sto.applyStore('a'));
+// }).catch(e => console.log(e));
+try {
+  $('#btn').click( () => {
+    const input = $('#input').val();
+    const analiser = new IVProgParser(input, ivprogLexer);
+    try {
+      const data = analiser.parseTree();
+      const semAna = new SemanticAnalyser(data);
+      const proc = new IVProgProcessor(semAna.analyseTree());
+      proc.registerInput(domConsole);
+      domConsole.clear();
+      proc.registerOutput(domConsole);
+      proc.interpretAST().then(sto => editor.load(sto.store))
+        .catch( e => {alert(e); console.log(e)});
+    } catch (error) {
+      alert(error);
+      console.log(error);
+    }
+    
+  });
+} catch(a) {
+  console.log(a);
+}
+}

+ 1 - 18
js/semantic/semantic-buttons.js

@@ -34,13 +34,8 @@ var button_ready = function() {
     .dropdown()
   ;
 
-  $('.program_signature_text').text(i18n('program'));
-
-
-  $('.add_function_button').on('click', addFunctionHandler);
-
   // Atualiza a tela do algoritmo
-  renderAlgorithm();
+  //renderAlgorithm();
 
   $('.ivprog_visual_panel').removeClass("loading");
 
@@ -55,18 +50,6 @@ var button_ready = function() {
 
   });
 
-
-  //Sortable:
-  Sortable.create(listWithHandle, {
-    handle: '.glyphicon-move',
-    animation: 100,
-    ghostClass: 'ghost',
-    group: 'functions_divs_drag',
-    onEnd: function (evt) {
-      updateSequenceFunctionHandler(evt.oldIndex, evt.newIndex);
-    }
-  });
-
 };
 
 var mouseX;

+ 22 - 0
js/services/i18nHelper.js

@@ -0,0 +1,22 @@
+import line_i18n from "line-i18n";
+import { LocalizedStrings } from "./localizedStringsService";
+
+const StringTypes = line_i18n.StringTypes;
+
+export const i18nHelper = Object.freeze({
+  i18n: (identifier) => {
+    var opts = identifier.split(':');
+    var type = opts[0].toLowerCase();
+    var id = opts[1];
+    if (StringTypes.ERROR === type) {
+      return LocalizedStrings.getError(id);
+    } else if (StringTypes.MESSAGE === type) {
+      return LocalizedStrings.getMessage(id); 
+    } else if (StringTypes.UI === type) {
+      return LocalizedStrings.getUI(id);
+    } else {
+      console.warn("A string has been passed to the i18n helper function that was not in the form type:id -> " + identifier);
+      return LocalizedStrings.getString(identifier, type);
+    }
+  }
+});

+ 5 - 4
js/services/languageService.js

@@ -1,12 +1,13 @@
 import Lexers from './../../grammar/';
 import line_i18n from 'line-i18n';
 
-const DEFAULT_LANG = "pt";
+// This is for LanguageService with localStorage
+// const DEFAULT_LANG = "pt";
 
-class LanguageServiceExtended extends line_i18n.LanguageService {
+class LanguageServiceExtended extends line_i18n.LanguageServiceNoLS {
 
   constructor () {
-    super("ivprog.lang", DEFAULT_LANG);
+    super(iLMparameters.lang);
   }
 
   getCurrentLexer () {
@@ -36,4 +37,4 @@ class LanguageServiceExtended extends line_i18n.LanguageService {
   }
 }
 
-export const LanguageService  = Object.freeze(new LanguageServiceExtended());
+export const LanguageService  = new LanguageServiceExtended();

+ 0 - 1
js/services/localizedStringsService.js

@@ -1,5 +1,4 @@
 import { LanguageService } from "./languageService";
 import line_i18n from 'line-i18n'
 import Langs from './../../i18n';
-
 export const LocalizedStrings = Object.freeze(new line_i18n.LocalizedStrings(LanguageService, Langs, true));

+ 5 - 3
js/util/inputTest.js

@@ -4,14 +4,16 @@ export class InputTest extends Input {
 
   constructor (inputList) {
     super();
+    this.index = 0;
     this.inputList = inputList;
   }
 
   requestInput (callback) {
-    if(this.inputList.length <= 0) {
-      throw new Error('The amount of requests exceeded the amount of available inputs');
+    if(this.index < this.inputList.length) {      
+      callback(this.inputList[this.index]);
+      this.index++;
     } else {
-      callback(this.inputList.splice(0,1)[0]);
+      throw new Error('The amount of requests exceeded the amount of available inputs');
     }
   }
 }

+ 39 - 0
js/visualUI/algorithm.js

@@ -0,0 +1,39 @@
+import $ from 'jquery';
+import { Types } from './types';
+import * as Models from './ivprog_elements';
+import { LocalizedStrings } from './../services/localizedStringsService';
+import * as GlobalsManagement from './globals';
+import * as VariablesManagement from './variables';
+import * as CommandsManagement from './commands';
+import * as CodeManagement from './code_generator';
+import * as VariableValueMenu from './commands/variable_value_menu';
+import * as FunctionsManagement from './functions';
+import { DOMConsole } from './../io/domConsole';
+import { IVProgParser } from './../ast/ivprogParser';
+import { IVProgProcessor } from './../processor/ivprogProcessor';
+import { LanguageService } from '../services/languageService';
+
+var block_render = false;
+
+export function renderAlgorithm () {
+	if (block_render) {
+		return;
+	}
+	block_render = true;
+
+ 	$('.all_functions').children().off();
+	$('.all_functions').empty();
+
+	$('.list_globals').children().off();
+	$('.list_globals').empty();	
+
+	for (var i = 0; i < window.program_obj.functions.length; i++) {
+		FunctionsManagement.renderFunction(window.program_obj.functions[i]);
+	}
+
+	for (var i = 0; i < window.program_obj.globals.length; i++) {
+		GlobalsManagement.renderGlobal(window.program_obj.globals[i]);
+	}	
+
+	setTimeout(function(){ block_render = false; }, 500);
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1074 - 0
js/visualUI/code_generator.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1045 - 0
js/visualUI/commands.js


+ 488 - 0
js/visualUI/commands/attribution.js

@@ -0,0 +1,488 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as VariableValueMenu from './variable_value_menu';
+import * as VariableValueMenuManagement from './variable_value_menu';
+import * as CommandsManagement from '../commands';
+
+export function createFloatingCommand () {
+	return $('<div class="ui attribution created_element"> <i class="ui icon small arrow left"></i> <span> x = 1 + 1 </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	
+	var el = $('<div class="ui attribution command_container"><i class="ui icon small arrow left command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="var_attributed"></div> <span class="text_attr_receives span_command_spec">'+LocalizedStrings.getUI('text_receives')+'</span> '
+		 + '<div class="expression_elements"></div> </div>');
+	el.data('command', command);
+
+	VariableValueMenu.renderMenu(command, command.variable, el.find('.var_attributed'), function_obj);
+
+	if (!command.expression || command.expression.length < 1) {
+		var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.op_exp, [Models.ARITHMETIC_TYPES.none, 
+		new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
+
+		command.expression.push(exp);
+	}
+
+	addHandlers(command, function_obj, el);
+
+	renderExpressionElements(command, function_obj, el);
+
+	return el;
+
+}
+
+export function manageExpressionElements (command, ref_object, dom_object, menu_var_or_value, function_obj, selectedItem, expression_element) {
+	
+	var index_to_move = expression_element.itens.indexOf(ref_object);
+
+	switch (selectedItem.data('exp')) {
+		case Models.EXPRESSION_ELEMENTS.exp_op_exp:
+
+			var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.exp_op_exp, [expression_element.itens[index_to_move],
+	     		Models.ARITHMETIC_TYPES.plus, 
+				new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
+
+			expression_element.itens[index_to_move] = exp;
+
+			break;
+
+		case Models.EXPRESSION_ELEMENTS.op_exp:
+
+			var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.op_exp, [Models.ARITHMETIC_TYPES.plus, 
+				expression_element.itens[index_to_move] ]);
+
+			expression_element.itens[index_to_move] = exp;
+
+			break;
+
+		case Models.EXPRESSION_ELEMENTS.par_exp_par:
+
+			var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.par_exp_par, [expression_element.itens[index_to_move]]);
+
+			expression_element.itens[index_to_move] = exp;
+
+			break;
+	}
+
+	renderExpressionElements(command, function_obj, dom_object);
+
+}
+
+function renderExpressionElements (command, function_obj, el) {
+	var expression_div = el.find('.expression_elements');
+	var command_container;
+
+	if (el.hasClass("command_container") == false) {
+		var hier = el.parentsUntil(".command_container");
+		for (var i = 0; i < hier.length; i++) {
+			if ($(hier[i]).hasClass("command_container")) {
+				command_container = $(hier[i]);
+				break;
+			}
+			if ($(hier[i]).hasClass("expression_elements")) {
+				expression_div = $(hier[i]);
+				break;
+			}
+		}
+	}
+
+	if (command_container) {
+		expression_div = command_container.find('.expression_elements');
+	}
+
+	expression_div.text('');
+
+	for (var i = 0; i < command.expression.length; i++) {
+
+		var temp = $('<div class="expression_element"></div>');
+		temp.data('ref_element', command.expression[i]);
+		temp.data('ref_index', i);
+
+		expression_div.append(temp);
+
+		renderElement(command, function_obj, temp, command.expression[i]);
+	}
+}
+
+function renderOperator (command, function_obj, temp_op, expression_element, index_op) {
+
+	var context_menu = '<div class="ui dropdown"><div class="text">';
+
+	switch (expression_element.itens[index_op]) {
+		case Models.ARITHMETIC_TYPES.plus:
+			context_menu += '+';
+			break;
+
+		case Models.ARITHMETIC_TYPES.minus:
+			context_menu += '-';
+			break;
+
+		case Models.ARITHMETIC_TYPES.multiplication:
+			context_menu += '*';
+			break;
+
+		case Models.ARITHMETIC_TYPES.division:
+			context_menu += '/';
+			break;
+
+		case Models.ARITHMETIC_TYPES.module:
+			context_menu += '%';
+			break;
+
+		case Models.ARITHMETIC_TYPES.none:
+			context_menu += '...';
+			break;
+	}
+	
+	context_menu += '</div><div class="menu">';
+	context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.plus+'">+</div>';
+	context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.minus+'">-</div>';
+	context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.multiplication+'">*</div>';
+	context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.division+'">/</div>';
+	context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.module+'">%</div>';
+	context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.none+'" data-text="...">Nenhum</div>';
+	context_menu += '</div></div>';
+
+	context_menu = $(context_menu);
+
+	temp_op.append(context_menu);
+
+	context_menu.dropdown({
+		onChange: function(value, text, $selectedItem) {
+	     expression_element.itens[index_op] = value;
+      }
+	});
+
+}
+
+function renderMenuAddExpression (command, function_obj, el, dom_append_menu, expression_append_new_expression) {
+
+	if (el.hasClass("command_container") == false) {
+		var hier = el.parentsUntil(".commands_list_div");
+
+		for (var i = 0; i < hier.length; i++) {
+			if ($(hier[i]).hasClass("command_container")) {
+				el = $(hier[i]);
+				break;
+			}
+		}
+	}
+
+	if (dom_append_menu.hasClass("expression_elements") == false) {
+		var hier = el.parentsUntil(".commands_list_div");
+
+		for (var i = 0; i < hier.length; i++) {
+			if ($(hier[i]).hasClass("expression_elements")) {
+				dom_append_menu = $(hier[i]);
+				break;
+			}
+		}
+	}
+
+	var context_menu = '<div class="ui dropdown"><div class="text"></div><i class="ui icon arrow alternate circle right outline"></i><div class="menu">';
+	context_menu += '<div class="item" data-value="'+Models.EXPRESSION_ELEMENTS.exp_op_exp+'">EXP OP EXP</div>';
+	context_menu += '<div class="item" data-value="'+Models.EXPRESSION_ELEMENTS.op_exp+'">OP EXP</div>';
+	context_menu += '<div class="item" data-value="'+Models.EXPRESSION_ELEMENTS.par_exp_par+'">( EXP )</div>';
+	context_menu += '</div></div>';
+
+	context_menu = $(context_menu);
+
+	dom_append_menu.append(context_menu);
+
+	context_menu.dropdown({
+		onChange: function(value, text, $selectedItem) {
+	     switch (value) {
+	     	case Models.EXPRESSION_ELEMENTS.exp_op_exp:
+
+	     	var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.exp_op_exp, [new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true),
+	     		Models.ARITHMETIC_TYPES.plus, 
+				new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
+
+			expression_append_new_expression.push(exp);
+			break;
+
+		case Models.EXPRESSION_ELEMENTS.op_exp:
+			var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.op_exp, [Models.ARITHMETIC_TYPES.plus, 
+				new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
+
+			expression_append_new_expression.push(exp);
+			break;
+
+		case Models.EXPRESSION_ELEMENTS.par_exp_par:
+
+			var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.par_exp_par, [new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
+
+			expression_append_new_expression.push(exp);
+
+			break;
+		}
+		
+		renderExpressionElements(command, function_obj, el);
+      }
+	});
+
+}
+
+function renderElement (command, function_obj, el, expression_element) {
+
+	switch (expression_element.type_exp) {
+		case Models.EXPRESSION_ELEMENTS.exp_op_exp:
+
+			var temp_op = $('<div class="component_element"></div>');
+			var temp_exp_1 = $('<div class="component_element"></div>');
+			var temp_exp_2 = $('<div class="component_element"></div>');
+
+			el.append(temp_exp_1);
+			el.append(temp_op);
+			el.append(temp_exp_2);
+			
+			if (expression_element.itens[0].type) {
+				VariableValueMenu.renderMenu(command, expression_element.itens[0], temp_exp_1, function_obj, 2, expression_element);
+			} else {
+				renderElement(command, function_obj, temp_exp_1, expression_element.itens[0]);
+			}
+
+			renderOperator(command, function_obj, temp_op, expression_element, 1);
+
+			if (expression_element.itens[2].type) {
+				VariableValueMenu.renderMenu(command, expression_element.itens[2], temp_exp_2, function_obj, 2, expression_element);
+			} else {
+				renderElement(command, function_obj, temp_exp_2, expression_element.itens[2]);
+			}
+
+			break;
+
+		case Models.EXPRESSION_ELEMENTS.op_exp:
+			var temp_op = $('<div class="component_element"></div>');
+			var temp_exp = $('<div class="component_element"></div>');
+
+			el.append(temp_op);
+			el.append(temp_exp);
+
+			renderOperator(command, function_obj, temp_op, expression_element, 0);
+
+			if (expression_element.itens[1].type) {
+				VariableValueMenu.renderMenu(command, expression_element.itens[1], temp_exp, function_obj, 2, expression_element);
+			} else {
+				renderElement(command, function_obj, temp_exp, expression_element.itens[1]);
+			}
+			break;
+
+		case Models.EXPRESSION_ELEMENTS.par_exp_par:
+
+			var temp_par_1 = $('<div class="component_element"> ( </div>');
+			var temp_exp = $('<div class="component_element"></div>');
+			var temp_par_2 = $('<div class="component_element"> ) </div>');
+
+			el.append(temp_par_1);
+			el.append(temp_exp);
+
+			for (var j = 0; j < expression_element.itens.length; j++) {
+				if (expression_element.itens[j].type) {
+					VariableValueMenu.renderMenu(command, expression_element.itens[j], temp_exp, function_obj, 2, expression_element);
+				} else {
+					renderElement(command, function_obj, temp_exp, expression_element.itens[j]);
+				}
+			}
+			
+
+			//renderMenuAddExpression(command, function_obj, el, el, expression_element.itens);
+
+			el.append(temp_par_2);
+
+			break;
+	}
+
+}
+
+
+function renderExpression (command, function_obj, el) {
+
+	var expression_div = el.find('.expression_elements');
+	expression_div.text('');
+
+	var menu_add_item = $('<div class="menu_add_item"></div>');
+	menu_add_item.data('index_add', 0);
+
+	expression_div.append(menu_add_item);
+	
+	for (var i = 0; i < command.expression.length; i++) {
+
+		if (command.expression[i].type) {
+
+			var temp = $('<div class="expression_element"></div>');
+			temp.data('ref_element', command.expression[i]);
+			temp.data('ref_index', i);
+
+			expression_div.append(temp);
+
+			VariableValueMenu.renderMenu(command, command.expression[i], temp, function_obj);
+
+		} else if (command.expression[i] == "(" || command.expression[i] == ")") {
+
+			var temp = $('<div class="expression_element">'+command.expression[i]+'</div>');
+			temp.data('ref_element', command.expression[i]);
+			temp.data('ref_index', i);
+
+			expression_div.append(temp);
+
+		} else {
+
+			var temp = '<div class="expression_element">';
+
+			switch(command.expression[i]) {
+				case Models.ARITHMETIC_TYPES.plus:
+					temp += '+';
+					break;
+				case Models.ARITHMETIC_TYPES.minus:
+					temp += '-';
+					break;
+				case Models.ARITHMETIC_TYPES.multiplication:
+					temp += '*';
+					break;
+				case Models.ARITHMETIC_TYPES.division:
+					temp += '/';
+					break;
+				case Models.ARITHMETIC_TYPES.module:
+					temp += '%';
+					break;
+			}
+
+			temp += '</div>';
+			temp = $(temp);
+			temp.data('ref_element', command.expression[i]);
+			temp.data('ref_index', i);
+
+			expression_div.append(temp);
+
+		}
+		
+		var menu_add_item_seq = $('<div class="menu_add_item"></div>');
+		var index_temp = (i + 1);
+		menu_add_item_seq.data('index_add', index_temp);
+		expression_div.append(menu_add_item_seq);
+
+	}
+
+	addMenuItens(command, function_obj, el);
+
+}
+
+function addMenuItens (command, function_obj, expression_div) {
+	var divs_expression = expression_div.find('.menu_add_item');
+
+	for (var i = 0; i < divs_expression.length; i++) {
+
+		var temp = $(divs_expression[i]).data('index_add');
+
+		var context_menu = '<div class="ui dropdown context_menu_clear"><i class="ui icon plus square outline"></i><div class="menu">';
+		context_menu += '<div class="item" data-option="value" data-index="'+temp+'">'+LocalizedStrings.getUI('text_value')+'</div>';
+		context_menu += '<div class="item" data-option="operator" data-index="'+temp+'">'+LocalizedStrings.getUI('text_operator')+'</div>';
+		context_menu += '<div class="item" data-option="parentheses" data-index="'+temp+'">'+LocalizedStrings.getUI('text_parentheses')+'</div>';
+		context_menu += '</div></div>';
+
+		context_menu = $(context_menu);
+
+		$(divs_expression[i]).append(context_menu);
+
+		context_menu.dropdown({
+	      on: 'hover',
+	      onChange: function(value, text, $selectedItem) {
+    		switch ($selectedItem.data('option')) {
+    			case "value":
+    				command.expression.splice($selectedItem.data('index'), 0, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true));
+    				renderExpression(command, function_obj, expression_div);
+    				break;
+    			case "operator":
+    				command.expression.splice($selectedItem.data('index'), 0, Models.ARITHMETIC_TYPES.plus);
+    				renderExpression(command, function_obj, expression_div);
+    				break;
+    			case "parentheses":
+    				command.expression.splice($selectedItem.data('index'), 0, "(");
+    				command.expression.splice($selectedItem.data('index') + 1, 0, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true));
+    				command.expression.splice($selectedItem.data('index') + 2, 0, ")");
+    				renderExpression(command, function_obj, expression_div);
+    				break;
+    		 }
+        	}
+	    });
+
+	}
+}
+
+
+function addHandlers (command, function_obj, attribution_dom) {
+
+	attribution_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, attribution_dom)) {
+			attribution_dom.remove();
+		}
+	});
+
+	attribution_dom.find('.button_refresh_attribution').on('click', function() {
+		renderExpressionElements(command, function_obj, attribution_dom);
+	});
+}
+
+export function renderMenuOperations (command, ref_object, dom_object, menu_var_or_value, function_obj, variable_selected) {
+
+	/*console.log("recebido o seguinte DOM: ");
+	console.log(dom_object);
+
+	if (dom_object.hasClass('var_attributed')) {
+		return;
+	} else {
+		var hier = dom_object.parentsUntil(".command_container");
+		for (var i = 0; i < hier.length; i++) {
+			if ($(hier[i]).hasClass('var_attributed') || $(hier[i]).hasClass('parameters_function_called')) {
+				return;
+			}
+		}
+
+
+		
+	}
+
+	dom_object.find('.context_menu_clear').remove();
+
+
+	var menu_operations = '<div class="ui dropdown menu_operations"><div class="text"></div><i class="dropdown icon"></i><div class="menu">';
+
+	for (var tm in Models.ARITHMETIC_TYPES) {
+
+		menu_operations += '<div class="item" data-option="'+tm+'">'+LocalizedStrings.getUI('btn_arithmetic_' + tm)+'</div>';
+    }
+    menu_operations += '<div class="item" data-option="clear">'+LocalizedStrings.getUI('btn_clear')+'</div>';
+	
+    menu_operations += '</div></div>';
+
+    menu_operations = $(menu_operations);
+
+    dom_object.append(menu_operations);
+
+    menu_operations.dropdown({
+    	onChange: function(value, text, $selectedItem) {
+    		switch ($($selectedItem).data('option')) {
+    			case "clear":
+	    			$(dom_object).text('');
+		     	 	VariableValueMenu.renderMenu(command, ref_object, dom_object, function_obj);
+    				break;
+    			default:
+    				createExpressionAround(command, ref_object, dom_object, function_obj);
+    				menu_operations.find('.text').text('');
+    		}
+        }
+    });*/
+}
+
+function createExpressionAround (command, ref_object, dom_object, function_obj) {
+	$('<span> ( </span>').insertBefore(dom_object);
+	$('<span> ) </span>').insertAfter(dom_object);
+
+	VariableValueMenu.renderMenu(command, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true), dom_object, function_obj);
+}
+

+ 27 - 0
js/visualUI/commands/break.js

@@ -0,0 +1,27 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as CommandsManagement from '../commands';
+
+export function createFloatingCommand () {
+	return $('<div class="ui comment created_element"> <i class="ui icon small quote left"></i> <span> '+LocalizedStrings.getUI('text_break')+' </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var el = $('<div class="ui comment command_container"> <i class="ui icon small quote left"></i> <i class="ui icon times red button_remove_command"></i> <span>'+LocalizedStrings.getUI('text_break')+'</span> </div>');
+	el.data('command', command);
+
+	addHandlers(command, function_obj, el);
+
+	return el;
+}
+
+function addHandlers (command, function_obj, break_dom) {
+
+	break_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, break_dom)) {
+			break_dom.remove();
+		}
+	});
+}

+ 36 - 0
js/visualUI/commands/comment.js

@@ -0,0 +1,36 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as VariableValueMenu from './variable_value_menu';
+import * as CommandsManagement from '../commands';
+
+export function createFloatingCommand () {
+	return $('<div class="ui comment created_element"> <i class="ui icon small quote left"></i> <span class="span_comment_text" "> '+LocalizedStrings.getUI('text_comment')+' </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var el = $('<div class="ui comment command_container"> <i class="ui icon small quote left"></i> <i class="ui icon times red button_remove_command"></i> <div class="var_value_menu_div"></div> <div class="div_comment_text">'+'</div> </div>');
+	el.data('command', command);
+
+	addHandlers(command, function_obj, el);
+
+	renderTextComment(command, function_obj, el);
+
+	return el;
+}
+
+function renderTextComment (command, function_obj, el) {
+	VariableValueMenu.renderMenu(command, command.comment_text, el.find('.var_value_menu_div'), function_obj, 20);
+}
+
+function addHandlers (command, function_obj, comment_dom) {
+
+	comment_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, comment_dom)) {
+			comment_dom.remove();
+		}
+	});
+}

+ 231 - 0
js/visualUI/commands/conditional_expression.js

@@ -0,0 +1,231 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as VariableValueMenuManagement from './variable_value_menu';
+
+
+export function renderExpression (command, expression, function_obj, initial_el_to_render) {
+
+	if (expression.expression == null || expression.expression.length < 1) {
+
+		renderStartMenu(command, expression, function_obj, initial_el_to_render);
+
+	} else {
+		
+		var main_div = $('<div class="expression_elements"></div>');
+
+		switch (expression.expression.type) {
+			case Models.EXPRESSION_TYPES.exp_logic:
+				renderLogicExpression(command, expression, expression.expression, function_obj, main_div, initial_el_to_render);
+				break;
+			case Models.EXPRESSION_TYPES.exp_arithmetic:
+				renderArithmeticExpression(command, expression, expression.expression, function_obj, main_div);
+				break;
+		}
+
+		initial_el_to_render.append(main_div);	
+	}
+}
+
+function renderArithmeticOperator (command, all_expression, expression_arithmetic, arithmetic_operator, function_obj, element_to_append) {
+
+	var menu_operator = $('<div class="ui dropdown"><div class="text"></div><i class="dropdown icon"></i></div>');
+	menu_operator.dropdown({
+	    values: [
+	      {
+	        name     : '>',
+	        value    : Models.ARITHMETIC_COMPARISON.greater_than,
+	        selected : (arithmetic_operator == Models.ARITHMETIC_COMPARISON.greater_than)
+	      },
+	      {
+	        name     : '<',
+	        value    : Models.ARITHMETIC_COMPARISON.less_than,
+	        selected : (arithmetic_operator == Models.ARITHMETIC_COMPARISON.less_than)
+	      },
+	      {
+	        name     : '==',
+	        value    : Models.ARITHMETIC_COMPARISON.equals_to,
+	        selected : (arithmetic_operator == Models.ARITHMETIC_COMPARISON.equals_to)
+	      },
+	      {
+	        name     : '!=',
+	        value    : Models.ARITHMETIC_COMPARISON.not_equals_to,
+	        selected : (arithmetic_operator == Models.ARITHMETIC_COMPARISON.not_equals_to)
+	      },
+	      {
+	        name     : '>=',
+	        value    : Models.ARITHMETIC_COMPARISON.greater_than_or_equals_to,
+	        selected : (arithmetic_operator == Models.ARITHMETIC_COMPARISON.greater_than_or_equals_to)
+	      },
+	      {
+	        name     : '<=',
+	        value    : Models.ARITHMETIC_COMPARISON.less_than_or_equals_to,
+	        selected : (arithmetic_operator == Models.ARITHMETIC_COMPARISON.less_than_or_equals_to)
+	      }
+	    ],
+	    onChange: function(value, text, $selectedItem) {
+	    	expression_arithmetic.operator = value;
+	    }
+	  })
+	;
+
+	element_to_append.append(menu_operator);
+}
+
+function renderLogicOperator (command, all_expression, expression_logic, logic_operator, function_obj, element_to_append, initial_el_to_render) {
+
+	var menu_operator = $('<div class="ui dropdown"><div class="text"></div><i class="dropdown icon"></i></div>');
+	menu_operator.dropdown({
+	    values: [
+	      {
+	        name     : '==',
+	        value    : Models.LOGIC_COMPARISON.equals_to,
+	        selected : (logic_operator == Models.LOGIC_COMPARISON.equals_to)
+	      },
+	      {
+	        name     : '!=',
+	        value    : Models.LOGIC_COMPARISON.not_equals_to,
+	        selected : (logic_operator == Models.LOGIC_COMPARISON.not_equals_to)
+	      },
+	      {
+	        name     : '&&',
+	        value    : Models.LOGIC_COMPARISON.and,
+	        selected : (logic_operator == Models.LOGIC_COMPARISON.and)
+	      },
+	      {
+	        name     : '||',
+	        value    : Models.LOGIC_COMPARISON.or,
+	        selected : (logic_operator == Models.LOGIC_COMPARISON.or)
+	      }
+	    ],
+	    onChange: function(value, text, $selectedItem) {
+	    	if ($selectedItem) {
+		    	expression_logic.operator = value;
+		    	if (expression_logic.second_operand == null) {
+		    		expression_logic.second_operand = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true);
+		    		initial_el_to_render.empty();
+		    		renderExpression(command, all_expression, function_obj, initial_el_to_render);
+		    	}
+	    	}
+	    }
+	  });
+
+	element_to_append.append(menu_operator);
+
+}
+
+
+function renderLogicExpression (command, all_expression, expression_logic, function_obj, element_to_append, initial_el_to_render) {
+
+	var exp_el_par_1 = $(' <span class="span_command_spec"> </span> ');
+	var exp_el_expr_el_1 = $('<div class="expression_element"></div>');
+	var exp_el_expr_operand = $('<div class="expression_element"></div>');
+	var exp_el_expr_el_2 = $('<div class="expression_element"></div>');
+	var exp_el_par_2 = $(' <span class="span_command_spec"> </span> ');
+
+	if (expression_logic.first_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
+		renderLogicExpression(command, all_expression, expression_logic.first_operand, function_obj, exp_el_expr_el_1);
+	} else if (expression_logic.first_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic) {
+		renderArithmeticExpression(command, all_expression, expression_logic.first_operand, function_obj, exp_el_expr_el_1);
+	} else {
+		VariableValueMenuManagement.renderMenu(command, expression_logic.first_operand, exp_el_expr_el_1, function_obj);
+	}
+
+	element_to_append.append(exp_el_par_1);
+	element_to_append.append(exp_el_expr_el_1);
+
+	renderLogicOperator(command, all_expression, expression_logic, expression_logic.operator, function_obj, exp_el_expr_operand, initial_el_to_render);
+
+	element_to_append.append(exp_el_expr_operand);
+
+	if (expression_logic.second_operand) {
+		if (expression_logic.second_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
+			renderLogicExpression(command, all_expression, expression_logic.second_operand, function_obj, exp_el_expr_el_2);
+		} else if (expression_logic.second_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic) {
+			renderArithmeticExpression(command, all_expression, expression_logic.second_operand, function_obj, exp_el_expr_el_2);
+		} else {
+			VariableValueMenuManagement.renderMenu(command, expression_logic.second_operand, exp_el_expr_el_2, function_obj);
+		}
+
+		element_to_append.append(exp_el_expr_el_2);
+	}
+
+	element_to_append.append(exp_el_par_2);
+
+}
+
+function renderArithmeticExpression (command, all_expression, expression_arithmetic, function_obj, element_to_append) {
+
+	var exp_el_par_1 = $(' <span class="span_command_spec"> </span> ');
+	var exp_el_expr_el_1 = $('<div class="expression_element"></div>');
+	var exp_el_expr_operand = $('<div class="expression_element"></div>');
+	var exp_el_expr_el_2 = $('<div class="expression_element"></div>');
+	var exp_el_par_2 = $(' <span class="span_command_spec"> </span> ');
+
+
+	if (expression_arithmetic.first_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
+		renderLogicExpression(command, all_expression, expression_arithmetic.first_operand, function_obj, exp_el_expr_el_1);
+	} else if (expression_arithmetic.first_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic) {
+		renderArithmeticExpression(command, all_expression, expression_arithmetic.first_operand, function_obj, exp_el_expr_el_1);
+	} else {
+		VariableValueMenuManagement.renderMenu(command, expression_arithmetic.first_operand, exp_el_expr_el_1, function_obj);
+	}
+
+	if (expression_arithmetic.second_operand.type == Models.EXPRESSION_TYPES.exp_logic) {
+		renderLogicExpression(command, all_expression, expression_arithmetic.second_operand, function_obj, exp_el_expr_el_2);
+	} else if (expression_arithmetic.second_operand.type == Models.EXPRESSION_TYPES.exp_arithmetic) {
+		renderArithmeticExpression(command, all_expression, expression_arithmetic.second_operand, function_obj, exp_el_expr_el_2);
+	} else {
+		VariableValueMenuManagement.renderMenu(command, expression_arithmetic.second_operand, exp_el_expr_el_2, function_obj);
+	}
+
+	renderArithmeticOperator(command, all_expression, expression_arithmetic, expression_arithmetic.operator, function_obj, exp_el_expr_operand);
+
+	element_to_append.append(exp_el_par_1);
+	element_to_append.append(exp_el_expr_el_1);
+	element_to_append.append(exp_el_expr_operand);
+	element_to_append.append(exp_el_expr_el_2);
+	element_to_append.append(exp_el_par_2);
+}
+
+function renderStartMenu (command, expression, function_obj, initial_el_to_render) {
+	var start_menu = '';
+	start_menu += '<div class="ui dropdown menu_start_rendered"><div class="text"><i>'+LocalizedStrings.getUI('expression_menu_select')+'</i></div><i class="dropdown icon"></i><div class="menu">';
+	start_menu += '<div class="item" data-exp="'+Models.EXPRESSION_TYPES.exp_logic+'">'+LocalizedStrings.getUI('text_logic_expression')+'</div>';
+	start_menu += '<div class="item" data-exp="'+Models.EXPRESSION_TYPES.exp_arithmetic+'">'+LocalizedStrings.getUI('text_arithmetic_expression')+'</div>';
+	start_menu += '</div></div>';
+	start_menu = $(start_menu);
+
+	start_menu.dropdown({
+		onChange: function(value, text, $selectedItem) {
+			switch ($selectedItem.data('exp')) {
+				case Models.EXPRESSION_TYPES.exp_logic:
+					expression.expression = 
+						new Models.LogicExpression(false, 
+							new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true));
+					break;
+				case Models.EXPRESSION_TYPES.exp_arithmetic:
+					expression.expression = 
+						new Models.ArithmeticExpression(
+							new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true), 
+							new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true), 
+							Models.ARITHMETIC_COMPARISON.less_than);
+					break;
+			}
+
+			initial_el_to_render.html('');
+
+			renderExpression(command, expression, function_obj, initial_el_to_render);
+
+    	}
+	});
+
+	initial_el_to_render.append(' <span class="span_command_spec"> </span> ');
+	
+	initial_el_to_render.append(start_menu);
+
+	initial_el_to_render.append(' <span class="span_command_spec"> </span> ');
+}

+ 94 - 0
js/visualUI/commands/contextualized_menu.js

@@ -0,0 +1,94 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as CommandsManagement from '../commands';
+import * as VariableValueMenuManagement from './variable_value_menu';
+import * as SwitchManagement from './switch';
+
+import * as RepeatNTimesManagement from './repeatNtimes';
+
+export function renderMenu (command, dom_where_render, function_obj, dom_command) {
+
+	var menu_div = '<div class="ui dropdown menu_commands" ><i class="icon code"></i> <div class="menu"> ';
+
+	if ((command.type == Models.COMMAND_TYPES.repeatNtimes) 
+		|| (command.type == Models.COMMAND_TYPES.whiletrue) 
+		|| (command.type == Models.COMMAND_TYPES.dowhiletrue)) {
+
+		menu_div += '<a class="item" data-command="'+Models.COMMAND_TYPES.break+'"><i class="download icon"></i> '+LocalizedStrings.getUI('btn_break')+' </a>';
+
+	} else {
+
+		menu_div += '<a class="item" data-command="'+Models.COMMAND_TYPES.break+'"><i class="download icon"></i> '+LocalizedStrings.getUI('btn_break')+' </a>';
+		menu_div += '<a class="item" data-command="'+Models.COMMAND_TYPES.switchcase+'"><i class="download icon"></i> '+LocalizedStrings.getUI('btn_case')+' </a>';
+
+	}
+
+	menu_div += '</div></div>';
+
+	menu_div = $(menu_div);
+  	
+	dom_where_render.append(menu_div);
+
+	addHandlers(command, dom_where_render, function_obj, dom_command);
+}
+
+function addHandlers (command, dom_where_render, function_obj, dom_command) {
+
+	dom_where_render.find('.menu_commands').dropdown({
+      on: 'hover'
+    });
+	
+	dom_where_render.find('.menu_commands a').on('click', function(evt){
+
+		if ((command.type == Models.COMMAND_TYPES.repeatNtimes) 
+			|| (command.type == Models.COMMAND_TYPES.whiletrue) 
+			|| (command.type == Models.COMMAND_TYPES.dowhiletrue)) {
+
+				if (command.commands_block == null || command.commands_block.length == 0) {
+
+			      command.commands_block = [];
+
+			      var new_cmd = CommandsManagement.genericCreateCommand($(this).data('command'));
+			      command.commands_block.push(new_cmd);
+
+			      CommandsManagement.renderCommand(new_cmd, dom_command.find('.block_commands'), 3, function_obj);
+
+			    } else {
+			      CommandsManagement.createFloatingCommand(function_obj, dom_command.find('.block_commands'), $(this).data('command'), evt);
+			    }
+
+		} else {
+
+			switch ($(this).data('command')) {
+				case Models.COMMAND_TYPES.break:
+					CommandsManagement.createFloatingCommand(function_obj, null, $(this).data('command'), evt);
+					break;
+
+				case Models.COMMAND_TYPES.switchcase:
+					addCaseToSwitch(command, dom_where_render, function_obj, dom_command);
+					break;
+			}
+
+		}
+
+	});
+}
+
+function addCaseToSwitch (command, dom_where_render, function_obj, dom_command) {
+	
+	if ((command.cases == null)) {
+		command.cases = [];
+	}
+	
+	var sc = new Models.SwitchCase(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true));
+
+	command.cases.push(sc);
+
+	SwitchManagement.renderCase(sc, command, function_obj, dom_command.find('.all_cases_div'));
+
+}
+
+
+

+ 49 - 0
js/visualUI/commands/dowhiletrue.js

@@ -0,0 +1,49 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as CommandsManagement from '../commands';
+import * as ConditionalExpressionManagement from './conditional_expression';
+import * as ContextualizedMenu from './contextualized_menu';
+
+export function createFloatingCommand () {
+	return $('<div class="ui dowhiletrue created_element"> <i class="ui icon small sync"></i> <span> '+ LocalizedStrings.getUI('text_command_do') +' {<br>} ' + LocalizedStrings.getUI('text_code_while') +'(x < 10) </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var ret = '';
+	ret += '<div class="ui dowhiletrue command_container"> <i class="ui icon small random command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="ui context_menu"></div>  <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_command_do') + ' </span>';
+	ret += '<div class="ui block_commands" data-subblock="" data-idcommand="">';
+	ret += '</div>';
+	ret += ' <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_code_while') + ' </span> <span class="span_command_spec"> ( </span> <div class="conditional_expression"></div> <span class="span_command_spec"> ) </span>';
+	ret += '</div>';
+
+	var el = $(ret);
+	el.data('command', command);
+
+	addHandlers(command, function_obj, el);
+
+	ContextualizedMenu.renderMenu(command, el.find('.context_menu'), function_obj, el);
+
+	ConditionalExpressionManagement.renderExpression(command, command.expression, function_obj, el.find('.conditional_expression'));
+
+	if (command.commands_block) {
+		for (var j = 0; j < command.commands_block.length; j++) {
+		    CommandsManagement.renderCommand(command.commands_block[j], $(el.find('.block_commands')[0]), 3, function_obj);
+		}
+	}
+
+	return el;
+}
+
+
+function addHandlers (command, function_obj, dowhiletrue_dom) {
+
+	dowhiletrue_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, dowhiletrue_dom)) {
+			dowhiletrue_dom.remove();
+		}
+	});
+}

+ 32 - 0
js/visualUI/commands/functioncall.js

@@ -0,0 +1,32 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as VariableValueMenu from './variable_value_menu';
+import * as CommandsManagement from '../commands';
+
+export function createFloatingCommand () {
+	return $('<div class="ui functioncall created_element"> <i class="hand point right icon"></i> <span> funcao() </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var el = $('<div class="ui functioncall command_container"> <i class="hand point right icon command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="var_value_menu_div"></div> </div>');
+	el.data('command', command);
+
+	VariableValueMenu.renderMenu(command, command.function_called, el.find('.var_value_menu_div'), function_obj);
+
+	addHandlers(command, function_obj, el);
+
+	return el;
+}
+
+function addHandlers (command, function_obj, functioncall_dom) {
+
+	functioncall_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, functioncall_dom)) {
+			functioncall_dom.remove();
+		}
+	});
+}

+ 60 - 0
js/visualUI/commands/iftrue.js

@@ -0,0 +1,60 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as CommandsManagement from '../commands';
+import * as ConditionalExpressionManagement from './conditional_expression';
+
+export function createFloatingCommand () {
+	return $('<div class="ui iftrue created_element"> <i class="ui icon small random"></i> <span> if (x < 1) { } </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var ret = '';
+	ret += '<div class="ui iftrue command_container"><div class="ui data_block_if" data-if="true">  <i class="ui icon small random command_drag"></i> <i class="ui icon times red button_remove_command"></i>';
+	ret += '<span class="span_command_spec"> ' + LocalizedStrings.getUI('text_if') + '</span>';
+	ret += ' <span class="span_command_spec"> ( </span> <div class="conditional_expression"></div> <span class="span_command_spec"> ) </span>';
+	ret += '<span> </span> ';
+	ret += '<div class="ui block_commands commands_if conditional_comands_block" data-if="true">';
+ 	ret += '</div></div>';
+	ret += '<div class="ui data_block_else" data-else="true"> <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_else') + ' </span>';
+	ret += '<div class="ui block_commands commands_else conditional_comands_block" data-else="true">';
+	ret += '</div>';
+	ret += '<span></span></div>';
+	ret += '</div>';
+
+	var el = $(ret);
+	el.data('command', command);
+	el.find('.block_commands').data('command', command);
+	el.find('.data_block_if').data('command', command);
+	el.find('.data_block_else').data('command', command);
+
+	addHandlers(command, function_obj, el);
+
+	ConditionalExpressionManagement.renderExpression(command, command.expression, function_obj, el.find('.conditional_expression'));
+
+	if (command.commands_block) {
+		for (var j = 0; j < command.commands_block.length; j++) {
+		    CommandsManagement.renderCommand(command.commands_block[j], $(el.find('.commands_if')[0]), 3, function_obj);
+		}
+	}
+	if (command.commands_else) {
+		for (var j = 0; j < command.commands_else.length; j++) {
+		    CommandsManagement.renderCommand(command.commands_else[j], $(el.find('.commands_else')[0]), 3, function_obj);
+		}
+	}
+
+	return el;
+}
+
+
+function addHandlers (command, function_obj, iftrue_dom) {
+
+	iftrue_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, iftrue_dom)) {
+			iftrue_dom.remove();
+		}
+	});
+}

+ 34 - 0
js/visualUI/commands/reader.js

@@ -0,0 +1,34 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as VariableValueMenu from './variable_value_menu';
+import * as CommandsManagement from '../commands';
+
+export function createFloatingCommand () {
+	return $('<div class="ui reader created_element"> <i class="ui icon small download"></i> <span> '+LocalizedStrings.getUI('text_command_read')+' var </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var el = '<div class="ui reader command_container"> <i class="ui icon small download command_drag"></i> <i class="ui icon times red button_remove_command"></i> <span class="span_command_spec">'+LocalizedStrings.getUI('text_command_read')+' ( </span> <div class="var_value_menu_div"></div> <span class="close_parentheses span_command_spec">)</span> </div>';
+	
+	el = $(el);
+	el.data('command', command);
+
+	VariableValueMenu.renderMenu(command, command.variable_value_menu, el.find('.var_value_menu_div'), function_obj);
+
+	addHandlers(command, function_obj, el);
+
+	return el;
+}
+
+function addHandlers (command, function_obj, reader_dom) {
+
+	reader_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, reader_dom)) {
+			reader_dom.remove();
+		}
+	});
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 170 - 0
js/visualUI/commands/repeatNtimes.js


+ 32 - 0
js/visualUI/commands/return.js

@@ -0,0 +1,32 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as VariableValueMenu from './variable_value_menu';
+import * as CommandsManagement from '../commands';
+
+export function createFloatingCommand () {
+	return $('<div class="ui return created_element"> <i class="ui icon small reply"></i> <span> '+LocalizedStrings.getUI('text_return')+' </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var el = $('<div class="ui return command_container"> <i class="ui icon small reply"></i> <i class="ui icon times red button_remove_command"></i> <span class="span_command_spec"> '+LocalizedStrings.getUI('text_return')+' </span>  <div class="var_value_menu_div"></div></div>');
+	el.data('command', command);
+
+	addHandlers(command, function_obj, el);
+
+	VariableValueMenu.renderMenu(command, command.variable_value_menu, el.find('.var_value_menu_div'), function_obj);
+
+	return el;
+}
+
+function addHandlers (command, function_obj, return_dom) {
+
+	return_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, return_dom)) {
+			return_dom.remove();
+		}
+	});
+}

+ 75 - 0
js/visualUI/commands/switch.js

@@ -0,0 +1,75 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as CommandsManagement from '../commands';
+import * as VariableValueMenu from './variable_value_menu';
+import * as ContextualizedMenu from './contextualized_menu';
+
+export function createFloatingCommand () {
+	return $('<div class="ui switch created_element"> <i class="ui icon small random"></i> <span> '+LocalizedStrings.getUI('text_code_switch')+' ( x ) { <br> '+LocalizedStrings.getUI('text_code_case')+' 1: <br> '+LocalizedStrings.getUI('text_code_case')+' 2: <br> } </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var ret = '';
+	ret += '<div class="ui switch command_container"> <i class="ui icon small random command_drag" ></i> <i class="ui icon times red button_remove_command"></i> <div class="ui context_menu"></div> <span> '+LocalizedStrings.getUI('text_code_switch')+' ( <div class="ui variable_to_switch"></div> ) <div class="ui all_cases_div"></div></span>';
+	ret += '</div>';
+
+	var el = $(ret);
+	el.data('command', command);
+
+	addHandlers(command, function_obj, el);
+
+	ContextualizedMenu.renderMenu(command, el.find('.context_menu'), function_obj, el);
+
+	VariableValueMenu.renderMenu(command, command.variable, el.find('.variable_to_switch'), function_obj);
+
+	if (command.cases) {
+		for (var i = 0; i < command.cases.length; i++) {
+			renderCase(command.cases[i], command, function_obj, el.find('.all_cases_div'));
+		}
+	}
+
+	return el;
+}
+
+export function renderCase (switchcase, command, function_obj, el) {
+
+	var casediv = $('<div class="ui case_div"><i class="ui icon times red button_remove_command"></i><span>'+LocalizedStrings.getUI('text_code_case')+'</span> <div class="ui variable_case"></div>: <div class="case_commands_block"></div></div>');
+
+	VariableValueMenu.renderMenu(command, switchcase.variable_value_menu, casediv.find('.variable_case'), function_obj);
+
+	casediv.data('switchcase', switchcase);
+	casediv.find('.case_commands_block').data('switchcase', switchcase);
+
+	el.append(casediv);
+
+	if (switchcase.commands_block) {
+		for (var j = 0; j < switchcase.commands_block.length; j++) {
+		    CommandsManagement.renderCommand(switchcase.commands_block[j], $(casediv.find('.case_commands_block')[0]), 3, function_obj);
+		}
+	}
+
+	casediv.find('.button_remove_command').on('click', function() {
+		for (var i = 0; i < command.cases.length; i++) {
+			if (switchcase == command.cases[i]) {
+				delete command.cases[i];
+				command.cases.splice(i, 1);
+				casediv.remove();
+				break;
+			}
+		}
+	});
+
+}
+
+function addHandlers (command, function_obj, switch_dom) {
+
+	switch_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, switch_dom)) {
+			switch_dom.remove();
+		}
+	});
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1069 - 0
js/visualUI/commands/variable_value_menu.js


+ 50 - 0
js/visualUI/commands/whiletrue.js

@@ -0,0 +1,50 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as CommandsManagement from '../commands';
+import * as ConditionalExpressionManagement from './conditional_expression';
+import * as ContextualizedMenu from './contextualized_menu';
+
+export function createFloatingCommand () {
+	return $('<div class="ui whiletrue created_element"> <i class="ui icon small sync"></i> <span> ' + LocalizedStrings.getUI('text_code_while') + ' ( x < 10 ) { } </span></div>');
+}
+
+export function renderCommand (command, function_obj) {
+	var ret = '';
+	ret += '<div class="ui whiletrue command_container"> <i class="ui icon small random command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="ui context_menu"></div>  <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_code_while') + ' </span>';
+	ret += '<span class="span_command_spec"> ( </span> <div class="conditional_expression"></div> <span class="span_command_spec"> ) </span>';
+	ret += ' </span>';
+	ret += '<div class="ui block_commands">';
+	ret += '</div>';
+	ret += '<span> </span>';
+	ret += '</div>';
+
+	var el = $(ret);
+	el.data('command', command);
+
+	addHandlers(command, function_obj, el);
+
+	ContextualizedMenu.renderMenu(command, el.find('.context_menu'), function_obj, el);
+
+	ConditionalExpressionManagement.renderExpression(command, command.expression, function_obj, el.find('.conditional_expression'));
+
+	if (command.commands_block) {
+		for (var j = 0; j < command.commands_block.length; j++) {
+		    CommandsManagement.renderCommand(command.commands_block[j], $(el.find('.block_commands')[0]), 3, function_obj);
+		}
+	}
+
+	return el;
+}
+
+function addHandlers (command, function_obj, whiletrue_dom) {
+
+	whiletrue_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, whiletrue_dom)) {
+			whiletrue_dom.remove();
+		}
+	});
+}

+ 86 - 0
js/visualUI/commands/writer.js

@@ -0,0 +1,86 @@
+import $ from 'jquery';
+import { Types } from '../types';
+import * as Models from '../ivprog_elements';
+import { LocalizedStrings } from '../../services/localizedStringsService';
+import * as GlobalsManagement from '../globals';
+import * as VariablesManagement from '../variables';
+import * as VariableValueMenu from './variable_value_menu';
+import * as VariableValueMenuManagement from './variable_value_menu';
+import * as CommandsManagement from '../commands';
+
+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) {
+	var ret = '';
+	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="close_parentheses span_command_spec">)</span> </div>';
+
+	var el = $(ret);
+	el.data('command', command);
+
+	for (var i = 0; i < command.content.length; i ++) {
+		var new_div_item = $( '<div class="var_value_menu_div"></div>' );
+		el.find('.all_elements_write').append(new_div_item);
+		VariableValueMenu.renderMenu(command, command.content[i], new_div_item, function_obj);
+
+		addHandlerIconAdd(el.find('.all_elements_write'), command, function_obj);
+	}
+	addHandlers(command, function_obj, el);
+	return el;
+}
+
+function addHandlers (command, function_obj, writer_dom) {
+
+	writer_dom.find('.button_remove_command').on('click', function() {
+		if (CommandsManagement.removeCommand(command, function_obj, writer_dom)) {
+			writer_dom.remove();
+		}
+	});
+}
+
+function addHandlerIconAdd (dom_object, command, function_obj, insert_after = false, after_which = null) {
+	var 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(e) {
+		var new_div_item = $( '<div class="var_value_menu_div" style="display:none;"></div>' );
+		new_div_item.insertAfter(icon_add_item);
+		var 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, new_div_item);
+		var 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 ++;
+			}
+		});
+		new_div_item.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')) {
+		var 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(e) {
+			var new_div_item = $( '<div class="var_value_menu_div"></div>' );
+			new_div_item.insertAfter(icon_add_item);
+			var 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);
+
+			command.content.push(new_related_menu);
+		});
+	}
+}

+ 782 - 0
js/visualUI/functions.js

@@ -0,0 +1,782 @@
+import $ from 'jquery';
+import { Types } from './types';
+import * as Models from './ivprog_elements';
+import { LocalizedStrings } from './../services/localizedStringsService';
+import * as GlobalsManagement from './globals';
+import * as VariablesManagement from './variables';
+import * as CommandsManagement from './commands';
+import * as CodeManagement from './code_generator';
+import * as VariableValueMenu from './commands/variable_value_menu';
+import { DOMConsole } from './../io/domConsole';
+import { IVProgParser } from './../ast/ivprogParser';
+import { IVProgProcessor } from './../processor/ivprogProcessor';
+import WatchJS from 'melanke-watchjs';
+import { SemanticAnalyser } from '../processor/semantic/semanticAnalyser';
+import { IVProgAssessment } from '../assessment/ivprogAssessment';
+import * as AlgorithmManagement from './algorithm';
+
+import '../Sortable.js';
+
+var counter_new_functions = 0;
+var counter_new_parameters = 0;
+
+let studentTemp = null;
+let domConsole = null;
+window.studentGrade = null;
+const program = new Models.Program();
+
+window.system_functions = [];
+window.system_functions.push(new Models.SystemFunction('$sin', Types.REAL, 0, [new Models.VariableValueMenu(VariableValueMenu.VAR_OR_VALUE_TYPES.all, null, null, null, true)],
+  "seno de um número", Models.SYSTEM_FUNCTIONS_CATEGORIES.math));
+
+/*const variable1 = new Models.Variable(Types.INTEGER, "a", 1);
+const parameter1 = new Models.Variable(Types.INTEGER, "par_1", 1);
+const command1 = new Models.Comment(new Models.VariableValueMenu(VariableValueMenu.VAR_OR_VALUE_TYPES.only_value, "Testing rendering commands"));
+
+const sumFunction = new Models.Function("soma", Types.INTEGER, 0, [parameter1], false, false, [], null, [command1]);
+
+
+program.addFunction(sumFunction);
+*/
+
+console.log('       ___           ___                    ________          \n      /   /         /   /                  /   ____/  \n     /   /         /   /                  /   /        \n    /   /         /   /  ______    ___   /   /__         \n   /   /         /   /  /      \\  /  /  /   ___/      \n  /   /______   /   /  /   /\\   \\/  /  /   /      \n /          /  /   /  /   /  \\     /  /   /____     \n/__________/  /___/  /___/    \\___/  /________/       ');
+
+const mainFunction = new Models.Function(LocalizedStrings.getUI("start"), Types.VOID, 0, [], true, false);
+mainFunction.function_comment = new Models.Comment(LocalizedStrings.getUI('text_comment_main'));
+program.addFunction(mainFunction);
+
+window.program_obj = program;
+
+window.generator = CodeManagement.generate;
+window.runCodeAssessment = runCodeAssessment;
+window.renderAlgorithm = AlgorithmManagement.renderAlgorithm;
+
+WatchJS.watch(program.globals, function(){
+  AlgorithmManagement.renderAlgorithm();
+}, 1);
+
+function addFunctionHandler () {
+
+	var new_function = new Models.Function(LocalizedStrings.getUI("new_function") + "_" + counter_new_functions, Types.VOID, 0, [], false, false, [], new Models.Comment(LocalizedStrings.getUI('text_comment_start')));
+	program.addFunction(new_function);
+
+	counter_new_functions ++;
+
+  renderFunction(new_function);
+}
+
+function addParameter (function_obj, function_container) {
+  if (function_obj.parameters_list == null) {
+    function_obj.parameters_list = [];
+  }
+  var new_parameter = new Models.Variable(Types.INTEGER, LocalizedStrings.getUI("new_parameter") + "_" + counter_new_parameters);
+  function_obj.parameters_list.push(new_parameter);
+  counter_new_parameters ++;
+
+  renderParameter(function_obj, new_parameter, function_container);
+}
+
+function updateReturnType (function_obj, new_type, new_dimensions = 0) {
+  function_obj.return_type = new_type;
+  function_obj.return_dimensions = new_dimensions;
+}
+
+function removeFunction (function_obj) {
+  
+  var index = program.functions.indexOf(function_obj);
+  if (index > -1) {
+    program.functions.splice(index, 1);
+  }
+}
+
+function minimizeFunction (function_obj) {
+  function_obj.is_hidden = !function_obj.is_hidden;
+}
+
+function addHandlers (function_obj, function_container) {
+
+  function_container.find('.ui.dropdown.function_return').dropdown({
+      onChange: function(value, text, $selectedItem) {
+        if ($selectedItem.data('dimensions')) {
+          updateReturnType(function_obj, Types[$selectedItem.data('type')], $selectedItem.data('dimensions'));
+        } else {
+          updateReturnType(function_obj, Types[$selectedItem.data('type')]);
+        }
+      }
+  });
+
+  function_container.find( ".name_function_updated" ).on('click', function(e){
+    enableNameFunctionUpdate(function_obj, function_container);
+  });
+
+  function_container.find( ".add_parameter_button" ).on('click', function(e){
+    addParameter(function_obj, function_container);
+  });
+
+  function_container.find('.menu_commands').dropdown({
+      on: 'hover'
+    });
+
+  function_container.find('.menu_commands a').on('click', function(evt){
+    if (function_obj.commands == null || function_obj.commands.length == 0) {
+      function_obj.commands = [];
+      var new_cmd = CommandsManagement.genericCreateCommand($(this).data('command'));
+      function_obj.commands.push(new_cmd);
+
+      CommandsManagement.renderCommand(new_cmd, function_container.find('.commands_list_div'), 3, function_obj);
+    } else {
+      CommandsManagement.createFloatingCommand(function_obj, function_container, $(this).data('command'), evt);
+    }
+
+  });
+
+  function_container.find('.add_var_button_function').on('click', function(e){
+    VariablesManagement.addVariable(function_obj, function_container);
+  });
+
+  function_container.find('.remove_function_button').on('click', function(e){
+    removeFunction(function_obj);
+    function_container.slideUp(400);
+  });
+
+  function_container.find('.minimize_function_button').on('click', function(e){
+    minimizeFunction(function_obj);
+    function_container.find(".function_area").toggle();
+    function_container.find(".add_var_top_button").toggle();
+  });
+}
+
+// Essa função imprime o tipo de retorno da função e cria o menu do tipo 'select' para alteração
+function renderFunctionReturn (function_obj, function_element) {
+
+  var ret = '<div class="ui dropdown function_return">';
+    
+    if (function_obj.return_dimensions > 0) {
+      ret += '<div class="text">'+ LocalizedStrings.getUI("vector") +':'+ LocalizedStrings.getUI(function_obj.return_type);
+      if (function_obj.return_dimensions == 1) {
+        ret += ' [ ] ';
+      } else {
+        ret += ' [ ] [ ] ';
+      }
+      ret += '</div>';
+    } else {
+      ret += '<div class="text">'+LocalizedStrings.getUI(function_obj.return_type)+'</div>';
+    }
+
+    ret += '<div class="menu">';
+
+
+    for (var tm in Types) {
+      ret += '<div class="item ' + (function_obj.return_type == tm.toLowerCase()  && function_obj.return_dimensions < 1 ? ' selected ' : '') + '" data-type="'+tm+'" >'+LocalizedStrings.getUI(tm.toLowerCase())+'</div>';
+    }
+
+    for (var tm in Types) {
+      if (tm == Types.VOID.toUpperCase()) {
+        continue;
+      }
+      ret += '<div class="item">'
+        + '<i class="dropdown icon"></i>'
+        +  LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())
+          +  '<div class="menu">'
+            + '<div class="item '+(function_obj.return_type == tm.toLowerCase()  && function_obj.return_dimensions > 0 ? ' selected ' : '')+'" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] " data-type="'+tm+'" data-dimensions="1">[ ]</div>'
+            + '<div class="item '+(function_obj.return_type == tm.toLowerCase()  && function_obj.return_dimensions > 0 ? ' selected ' : '')+'" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] [ ] " data-type="'+tm+'" data-dimensions="2">[ ] [ ] </div>'
+          +  '</div>'
+        + '</div>'; 
+    }
+
+    ret += '</div></div>';
+
+    ret = $(ret);
+    
+    function_element.find('.function_return').append(ret);
+}
+
+
+export function renderFunction (function_obj) {
+
+  var appender = '<div class="ui secondary segment function_div list-group-item">';
+
+  if (function_obj.function_comment) {
+    //appender += renderComment(function_obj.function_comment, sequence, true, -1);
+  }
+    
+  appender += '<span class="glyphicon glyphicon-move move_function" aria-hidden="true"><i class="icon sort alternate vertical"></i></span>';
+
+  appender += (function_obj.is_main ? '<div class="div_start_minimize_v"> </div>' : '<button class="ui icon button large remove_function_button"><i class="red icon times"></i></button>')
+    + '<button class="ui icon button tiny minimize_function_button"><i class="icon window minimize"></i></button>';
+
+  appender += '<div class="ui small icon buttons add_var_top_button"><div class="ui icon button add_var_button_function"><i class="icon superscript"></i></div>';
+  
+  appender += '<div class="ui icon button dropdown menu_commands" ><i class="icon code"></i> <div class="menu"> ';
+  appender += '<a class="item" data-command="'+Models.COMMAND_TYPES.reader+'"><i class="download icon"></i> ' +LocalizedStrings.getUI('text_read_var')+ '</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.writer+'"><i class="upload icon"></i> '+LocalizedStrings.getUI('text_write_var')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.comment+'"><i class="quote left icon"></i> '+LocalizedStrings.getUI('text_comment')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.attribution+'"><i class="arrow left icon"></i> '+LocalizedStrings.getUI('text_attribution')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.functioncall+'"><i class="hand point right icon"></i> '+LocalizedStrings.getUI('text_functioncall')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.iftrue+'" ><i class="random icon"></i> '+LocalizedStrings.getUI('text_iftrue')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.repeatNtimes+'"><i class="sync icon"></i> '+LocalizedStrings.getUI('text_repeatNtimes')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.whiletrue+'"><i class="sync icon"></i> '+LocalizedStrings.getUI('text_whiletrue')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.dowhiletrue+'"><i class="sync icon"></i> '+LocalizedStrings.getUI('text_dowhiletrue')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.switch+'"><i class="list icon"></i> '+LocalizedStrings.getUI('text_switch')+'</a>'
+        + '<a class="item" data-command="'+Models.COMMAND_TYPES.return+'"><i class="reply icon"></i> '+LocalizedStrings.getUI('text_btn_return')+'</a>'
+        + '</div></div></div>';
+
+  appender += '<div class="function_signature_div">'+LocalizedStrings.getUI("function")+' ';
+
+  if (function_obj.is_main) {
+      appender += '<div class="function_name_div">  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ' + LocalizedStrings.getUI('void') + ' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="span_name_function" >'+function_obj.name+'</span> </div> '
+        + ' <span class="parethesis_function">( </span> <div class="ui large labels parameters_list">';
+  } else {
+      appender += '<div class="ui function_return"></div>';
+
+      appender += '<div class="function_name_div function_name_div_updated"><span class="span_name_function name_function_updated">'+function_obj.name+'</span> </div> ' 
+        + ' <span class="parethesis_function"> ( </span> <i class="ui icon plus square outline add_parameter_button"></i> <div class="ui large labels parameters_list container_parameters_list">';
+  }
+    
+  appender += '</div> <span class="parethesis_function"> ) </span> </div>'
+    + (function_obj.is_hidden ? ' <div class="function_area" style="display: none;"> ' : ' <div class="function_area"> ')
+
+    + '<div class="ui top attached segment variables_list_div">'
+    + '</div>'
+
+    + '<div class="ui bottom attached segment commands_list_div" id="function_drag_cmd_">';
+
+  appender += '</div>';
+
+  appender += '<div class="function_close_div"></div>'
+    + '</div>'
+    + '</div>';
+
+  appender = $(appender);
+
+  $('.all_functions').append(appender);
+
+  appender.data('fun', function_obj);
+  appender.find('.commands_list_div').data('fun', function_obj);
+
+  renderFunctionReturn(function_obj, appender);
+
+  addHandlers(function_obj, appender);
+
+
+  // Rendering parameters: 
+  for (var j = 0; j < function_obj.parameters_list.length; j++) {
+    renderParameter(function_obj, function_obj.parameters_list[j], appender);
+  }
+
+  // Rendering variables:
+  for (var j = 0; j < function_obj.variables_list.length; j++) {
+    VariablesManagement.renderVariable(appender, function_obj.variables_list[j], function_obj);
+  }
+
+  // Rendering commands:
+  for (var j = 0; j < function_obj.commands.length; j++) {
+    CommandsManagement.renderCommand(function_obj.commands[j], $(appender.find('.commands_list_div')[0]), 3, function_obj);
+  }
+
+
+  $('.minimize_function_button').popup({
+    content : LocalizedStrings.getUI("tooltip_minimize"),
+    delay: {
+      show: 750,
+      hide: 0
+    }
+  });
+}
+
+
+export function initVisualUI () {
+  // MUST USE CONST, LET, OR VAR !!!!!!
+  const mainDiv = $('#visual-main-div');
+  // fill mainDiv with functions and globals...
+  // renderAlgorithm()...
+  $('.add_function_button').on('click', () => {
+    addFunctionHandler();
+  });
+  $('.add_global_button').on('click', () => {
+    GlobalsManagement.addGlobal(program);
+  });
+
+  $('.run_button').on('click', () => {
+    runCode();
+  });
+
+  $('.visual_coding_button').on('click', () => {
+    toggleVisualCoding();
+  });
+
+  $('.textual_coding_button').on('click', () => {
+    toggleTextualCoding();
+  });
+
+  $('.assessment').on('click', () => {
+    runCodeAssessment();
+    is_iassign = true;
+  });
+
+  $('.div_toggle_console').on('click', () => {
+    toggleConsole();
+  });
+}
+
+var is_iassign = false;
+
+$( document ).ready(function() {
+
+  for (var i = 0; i < program.functions.length; i++) {
+    renderFunction(program.functions[i]);
+  }
+
+  var time_show = 750;
+  $('.visual_coding_button').popup({
+    content : LocalizedStrings.getUI("tooltip_visual"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.textual_coding_button').popup({
+    content : LocalizedStrings.getUI("tooltip_textual"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.upload_file_button').popup({
+    content : LocalizedStrings.getUI("tooltip_upload"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.download_file_button').popup({
+    content : LocalizedStrings.getUI("tooltip_download"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.undo_button').popup({
+    content : LocalizedStrings.getUI("tooltip_undo"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.redo_button').popup({
+    content : LocalizedStrings.getUI("tooltip_redo"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.run_button').popup({
+    content : LocalizedStrings.getUI("tooltip_run"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.assessment_button').popup({
+    content : LocalizedStrings.getUI("tooltip_evaluate"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.help_button').popup({
+    content : LocalizedStrings.getUI("tooltip_help"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.add_global_button').popup({
+    content : LocalizedStrings.getUI("tooltip_add_global"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+  $('.div_toggle_console').popup({
+    content : LocalizedStrings.getUI("tooltip_console"),
+    delay: {
+      show: time_show,
+      hide: 0
+    }
+  });
+
+  Sortable.create(listWithHandle, {
+    handle: '.glyphicon-move',
+    animation: 100,
+    ghostClass: 'ghost',
+    group: 'functions_divs_drag',
+    onEnd: function (evt) {
+       updateSequenceFunction(evt.oldIndex, evt.newIndex);
+    }
+  });
+
+});
+
+function updateSequenceFunction (oldIndex, newIndex) {
+  program_obj.functions.splice(newIndex, 0, program_obj.functions.splice(oldIndex, 1)[0]);
+}
+
+function runCodeAssessment () {
+  toggleConsole(true);
+
+  window.studentGrade = null;
+  studentTemp = null;
+  const strCode = CodeManagement.generate();
+  if (strCode == null) {
+    return;
+  }
+  if(domConsole == null)
+    domConsole = new DOMConsole("#ivprog-term");
+  $("#ivprog-term").slideDown(500);
+  const runner = new IVProgAssessment(strCode, testCases, domConsole);
+
+  runner.runTest().then(grade => {
+    if (!is_iassign) {
+      parent.getEvaluationCallback(grade);
+    } else {
+      is_iassign = false;
+    }
+  }).catch( err => domConsole.err(err.message));
+  
+}
+
+function runCode () {
+  toggleConsole(true);
+
+  const strCode = CodeManagement.generate();
+  if (strCode == null) {
+    return;
+  }
+  if(domConsole == null)
+    domConsole = new DOMConsole("#ivprog-term");
+  $("#ivprog-term").slideDown(500);
+  try {
+    const parser = IVProgParser.createParser(strCode);
+    const analyser = new SemanticAnalyser(parser.parseTree());
+    const data = analyser.analyseTree();
+    const proc = new IVProgProcessor(data);
+    proc.registerInput(domConsole);
+    proc.registerOutput(domConsole);
+    $("#ivprog-term").addClass('ivprog-term-active');
+
+    proc.interpretAST().then( _ => {
+      domConsole.info("Programa executado com sucesso!");
+      $("#ivprog-term").removeClass('ivprog-term-active');
+    }).catch(err => {
+      domConsole.err(err.message);
+      $("#ivprog-term").removeClass('ivprog-term-active');
+    }) 
+  } catch (error) {
+    domConsole.err(error.message);
+    console.log(error);
+  }
+  
+}
+
+function toggleConsole (is_running) {
+
+  if (is_running) {
+    $('.ivprog-term-div').css('display', 'block');
+    $('#ivprog-term').css('min-height', '160px');
+    $('#ivprog-term').css('margin-top', '-170px');
+    return;
+  }
+
+  if ($('#ivprog-term').css('min-height') == '160px') {
+    // esconder
+    $('.ivprog-term-div').css('display', 'none');
+    $('#ivprog-term').css('min-height', '0');
+    $('#ivprog-term').css('margin-top', '-30px');
+    $('#ivprog-term').css('padding', '5px');
+  } else {
+    // mostrar
+    $('.ivprog-term-div').css('display', 'block');
+    $('#ivprog-term').css('min-height', '160px');
+    $('#ivprog-term').css('margin-top', '-170px');
+  }
+}
+
+function waitToCloseConsole () {
+  domConsole.info("Aperte qualquer tecla para fechar...");
+  const p = new Promise((resolve, _) => {
+    domConsole.requestInput(resolve, true);
+  });
+  p.then( _ => {
+    domConsole.dispose();
+    domConsole = null;
+    $("#ivprog-term").hide();
+  })
+}
+
+function toggleTextualCoding () {
+  var code = CodeManagement.generate();
+  $('.ivprog_visual_panel').css('display', 'none');
+  $('.ivprog_textual_panel').css('display', 'block');
+  $('.ivprog_textual_panel').removeClass('loading');
+  $('.ivprog_textual_code').text(code);
+
+  $('.visual_coding_button').removeClass('active');
+  $('.textual_coding_button').addClass('active');
+}
+
+function toggleVisualCoding () {
+  $('.ivprog_textual_panel').addClass('loading');
+  $('.ivprog_textual_panel').css('display', 'none');
+  $('.ivprog_visual_panel').css('display', 'block');
+
+  $('.textual_coding_button').removeClass('active');
+  $('.visual_coding_button').addClass('active');
+}
+
+function removeParameter (function_obj, parameter_obj, parameter_container) {
+  var index = function_obj.parameters_list.indexOf(parameter_obj);
+  if (index > -1) {
+    function_obj.parameters_list.splice(index, 1);
+  }
+  $(parameter_container).remove();
+}
+
+function updateParameterType(parameter_obj, new_type, new_dimensions = 0) {
+  parameter_obj.type = new_type;
+  parameter_obj.dimensions = new_dimensions;
+
+  if (new_dimensions > 0) {
+    parameter_obj.rows = new_dimensions;
+    parameter_obj.columns = 2;
+  }
+
+}
+
+function renderParameter (function_obj, parameter_obj, function_container) {
+  var ret = "";
+
+  ret += '<div class="ui label function_name_parameter">';
+
+  ret += '<div class="ui dropdown parameter_type">';
+
+  if (parameter_obj.dimensions > 0) {
+    ret += '<div class="text">'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(parameter_obj.type);
+    if (parameter_obj.dimensions == 1) {
+      ret += ' [ ] ';
+    } else {
+      ret += ' [ ] [ ] ';
+    }
+    ret += '</div>';
+  } else {
+    ret += '<div class="text">'+LocalizedStrings.getUI(parameter_obj.type)+'</div>';
+  }
+
+  ret += '<div class="menu">';
+
+  
+  for (var tm in Types) {
+      if (tm == Types.VOID.toUpperCase()) {
+        continue;
+      }
+      ret += '<div class="item ' + (parameter_obj.type == tm.toLowerCase() ? ' selected ' : '') + '" data-type="'+tm+'" >'+LocalizedStrings.getUI(tm.toLowerCase())+'</div>';
+  }
+
+  for (var tm in Types) {
+    if (tm == Types.VOID.toUpperCase()) {
+      continue;
+    }
+    ret += '<div class="item">'
+      + '<i class="dropdown icon"></i>'
+      +  LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())
+        +  '<div class="menu">'
+          + '<div class="item" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] " data-type="'+tm+'" data-dimensions="1">[ ]</div>'
+          + '<div class="item" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] [ ] " data-type="'+tm+'" data-dimensions="2">[ ] [ ] </div>'
+        +  '</div>'
+      + '</div>'; 
+  }
+
+  ret += '</div></div>';
+
+  ret += '<div class="parameter_div_edit"><span class="span_name_parameter label_enable_name_parameter">'+parameter_obj.name+'</span></div> ';
+
+  ret += ' <i class="red icon times remove_parameter"></i></div>';
+
+  ret = $(ret);
+  
+  function_container.find('.container_parameters_list').append(ret);
+
+  ret.find('.remove_parameter').on('click', function(e){
+    removeParameter(function_obj, parameter_obj, ret);
+  });
+  
+  ret.find('.ui.dropdown.parameter_type').dropdown({
+    onChange: function(value, text, $selectedItem) {
+      if ($selectedItem.data('dimensions')) {
+        updateParameterType(parameter_obj, Types[$selectedItem.data('type')], $selectedItem.data('dimensions'));
+      } else {
+        updateParameterType(parameter_obj, Types[$selectedItem.data('type')]);
+      }
+    }
+  });
+
+  ret.find('.label_enable_name_parameter').on('click', function(e){
+    enableNameParameterUpdate(parameter_obj, ret);
+  });
+
+}
+
+var opened_name_parameter = false;
+var opened_input_parameter = null;
+function enableNameParameterUpdate (parameter_obj, parent_node) {
+  if (opened_name_parameter) {
+    opened_input_parameter.focus();
+    return;
+  }
+  opened_name_parameter = true;
+  parent_node = $(parent_node);
+
+  var input_field;
+
+  parent_node.find('.span_name_parameter').text('');
+  input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"+parameter_obj.name+"' />" );
+  input_field.insertBefore(parent_node.find('.span_name_parameter'));
+
+  input_field.on('input', function() {
+    var inputWidth = input_field.textWidth()+10;
+    opened_input_parameter = input_field;
+    input_field.focus();
+
+    var tmpStr = input_field.val();
+    input_field.val('');
+    input_field.val(tmpStr);
+
+    input_field.css({
+        width: inputWidth
+    })
+  }).trigger('input');
+
+  input_field.focusout(function() {
+    /// update array:
+    if (input_field.val().trim()) {
+      parameter_obj.name = input_field.val().trim();
+      parent_node.find('.span_name_parameter').text(parameter_obj.name);
+    }
+    input_field.off();
+    input_field.remove();
+
+    /// update elements:
+    opened_name_parameter = false;
+    opened_input_parameter = false;
+  });
+
+  input_field.on('keydown', function(e) {
+    var code = e.keyCode || e.which;
+    if(code == 13) {
+      if (input_field.val().trim()) {
+        parameter_obj.name = input_field.val().trim();
+        parent_node.find('.span_name_parameter').text(parameter_obj.name);
+      }
+      input_field.off();
+      input_field.remove();
+
+      /// update elements:
+      opened_name_parameter = false;
+      opened_input_parameter = false;
+
+    }
+    if(code == 27) {
+      parent_node.find('.span_name_parameter').text(parameter_obj.name);
+      input_field.off();
+      input_field.remove();
+
+      /// update elements:
+      opened_name_parameter = false;
+      opened_input_parameter = false;
+    }
+  });
+  input_field.select();
+}
+
+var opened_name_function = false;
+var opened_input = null;
+var previousPadding = null;
+function enableNameFunctionUpdate (function_obj, parent_node) {
+  if (opened_name_function) {
+    opened_input.focus();
+    return;
+  }
+  parent_node = $(parent_node);
+  parent_node.find('.span_name_function').text('');
+  var input_field;
+  if (!previousPadding) {
+    previousPadding = parent_node.find('.span_name_function').css('padding-left');
+  }
+  parent_node.find('.span_name_function').css('padding-left', '0');
+  parent_node.find('.span_name_function').css('padding-right', '0');
+  
+  input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"+function_obj.name+"' />" );
+  input_field.insertBefore(parent_node.find('.span_name_function'));
+
+  input_field.on('input', function() {
+    var inputWidth = input_field.textWidth()+10;
+    opened_input = input_field;
+    input_field.focus();
+
+    var tmpStr = input_field.val();
+    input_field.val('');
+    input_field.val(tmpStr);
+
+    input_field.css({
+        width: inputWidth
+    })
+  }).trigger('input');
+
+  input_field.focusout(function() {
+    /// update array:
+    if (input_field.val().trim()) {
+      function_obj.name = input_field.val().trim();
+    }
+    input_field.off();
+    input_field.remove();
+    parent_node.find('.span_name_function').css('padding-left', previousPadding);
+    parent_node.find('.span_name_function').css('padding-right', previousPadding);
+    parent_node.find('.span_name_function').text(function_obj.name);
+
+    /// update elements:
+    opened_name_function = false;
+    opened_input = false;
+  });
+
+  input_field.on('keydown', function(e) {
+    var code = e.keyCode || e.which;
+    if(code == 13) {
+      if (input_field.val().trim()) {
+        function_obj.name = input_field.val().trim();
+      }
+      input_field.off();
+      input_field.remove();
+      parent_node.find('.span_name_function').css('padding-left', previousPadding);
+      parent_node.find('.span_name_function').css('padding-right', previousPadding);
+      parent_node.find('.span_name_function').text(function_obj.name);
+
+      /// update elements:
+      opened_name_function = false;
+      opened_input = false;
+    }
+    if(code == 27) {
+
+      input_field.off();
+      input_field.remove();
+      parent_node.find('.span_name_function').css('padding-left', previousPadding);
+      parent_node.find('.span_name_function').css('padding-right', previousPadding);
+      parent_node.find('.span_name_function').text(function_obj.name);
+
+      /// update elements:
+      opened_name_function = false;
+      opened_input = false;
+    }
+  });
+  input_field.select();
+  
+}

+ 947 - 0
js/visualUI/globals.js

@@ -0,0 +1,947 @@
+import $ from 'jquery';
+import jQuery from 'jquery';
+import { Types } from './types';
+import * as Models from './ivprog_elements';
+import { LocalizedStrings } from './../services/localizedStringsService';
+
+
+window.jQuery = jQuery;
+
+import '../semantic/semantic.min.js';
+
+var counter_new_globals = 0;
+
+export function addGlobal (program) {
+
+	var new_global = new Models.Variable(Types.INTEGER, LocalizedStrings.getUI('new_global') + '_' + counter_new_globals, 1);
+	counter_new_globals ++;
+
+	program.addGlobal(new_global);
+
+	renderGlobal(new_global);
+
+}
+
+function toggleConstant (global_var) {
+	global_var.is_constant = !global_var.is_constant;
+}
+
+function updateName (global_var, new_name) {
+	global_var.name = new_name;
+}
+
+function updateType (global_var, new_type, new_dimensions = 0) {
+	global_var.type = new_type;
+	global_var.dimensions = new_dimensions;
+
+	if (new_dimensions > 0) {
+		global_var.rows = new_dimensions;
+		global_var.columns = 2;
+	}
+
+	updateInitialValues(global_var);
+}
+
+function removeGlobal (global_var, global_container) {
+	var index = window.program_obj.globals.indexOf(global_var);
+	if (index > -1) {
+	  window.program_obj.globals.splice(index, 1);
+	}
+	global_container.children().off();
+	global_container.off();
+	global_container.remove();
+}
+
+function updateInitialValues (global_var) {
+	if (global_var.type == Types.INTEGER) {
+		if (global_var.dimensions == 0) {
+			global_var.value = 1;
+		}
+		if (global_var.dimensions == 1) {
+			global_var.value = [1, 1];
+		}
+		if (global_var.dimensions == 2) {
+			global_var.value = [[1, 1], [1, 1]];
+		}
+	}
+
+	if (global_var.type == Types.REAL) {
+		if (global_var.dimensions == 0) {
+			global_var.value = 1.0;
+		}
+		if (global_var.dimensions == 1) {
+			global_var.value = [1.0, 1.0];
+		}
+		if (global_var.dimensions == 2) {
+			global_var.value = [[1.0, 1.0], [1.0, 1.0]];
+		}
+	}
+
+	if (global_var.type == Types.TEXT) {
+		if (global_var.dimensions == 0) {
+			global_var.value = LocalizedStrings.getUI('text_start');
+		}
+		if (global_var.dimensions == 1) {
+			global_var.value = [LocalizedStrings.getUI('text_start'), LocalizedStrings.getUI('text_start')];
+		}
+		if (global_var.dimensions == 2) {
+			global_var.value = [[LocalizedStrings.getUI('text_start'), LocalizedStrings.getUI('text_start')], 
+									[LocalizedStrings.getUI('text_start'), LocalizedStrings.getUI('text_start')]];
+		}
+	}
+
+	if (global_var.type == Types.BOOLEAN) {
+		if (global_var.dimensions == 0) {
+			global_var.value = true;
+		}
+		if (global_var.dimensions == 1) {
+			global_var.value = [true, true];
+		}
+		if (global_var.dimensions == 2) {
+			global_var.value = [[true, true], [true, true]];
+		}
+	}
+}
+
+function alternateBooleanGlobalValue (global_var, value_container) {
+	global_var.value = !global_var.value;
+	$(value_container).find('.span_value_variable').text(LocalizedStrings.getUI(global_var.value));
+}
+
+function alternateBooleanGlobalVectorValue (global_var, index, value_container) {
+	global_var.value[index] = !global_var.value[index];
+	$(value_container).find('.span_value_variable').text(LocalizedStrings.getUI(global_var.value[index]));
+}
+
+function removeGlobalColumnVector (global_var) {
+	if (global_var.columns == 0) {
+		return;
+	}
+
+	global_var.columns --;
+	global_var.value.splice(global_var.value.length - 1, 1);
+}
+
+function addGlobalColumnVector (global_var) {
+	global_var.columns ++;
+
+	if (global_var.type == Types.INTEGER) {
+		global_var.value.push(1);
+	}
+	if (global_var.type == Types.REAL) {
+		global_var.value.push(1.0);
+	}
+	if (global_var.type == Types.TEXT) {
+		global_var.value.push(LocalizedStrings.getUI('text_start'));
+	}
+	if (global_var.type == Types.BOOLEAN) {
+		global_var.value.push(true);
+	}
+}
+
+function removeColumnGlobalMatrix (global_var) {
+	if (global_var.columns == 0) {
+		return;
+	}
+
+	global_var.columns --;
+
+	for (var i = 0; i < global_var.rows; i++) {
+		global_var.value[i].splice(global_var.value[i].length - 1, 1);
+	}
+}
+
+function addColumnGlobalMatrix (global_var) {
+	global_var.columns ++;
+
+	if (global_var.type == Types.INTEGER) {
+		for (var i = 0; i < global_var.rows; i++) {
+			global_var.value[i].push(1);
+		}
+	}
+	if (global_var.type == Types.REAL) {
+		for (var i = 0; i < global_var.rows; i++) {
+			global_var.value[i].push(1.0);
+		}
+	}
+	if (global_var.type == Types.TEXT) {
+		for (var i = 0; i < global_var.rows; i++) {
+			global_var.value[i].push(LocalizedStrings.getUI('text_start'));
+		}
+	}
+	if (global_var.type == Types.BOOLEAN) {
+		for (var i = 0; i < global_var.rows; i++) {
+			global_var.value[i].push(true);
+		}
+	}
+}
+
+function removeLineGlobalMatrix (global_var) {
+	if (global_var.rows == 0) {
+		return;
+	}
+
+	global_var.rows --;
+	global_var.value.splice(global_var.value.length - 1, 1);
+}
+
+function addLineGlobalMatrix (global_var) {
+	global_var.rows ++;
+
+	if (global_var.type == Types.INTEGER) {
+		var n_l = [];
+		for (var i = 0; i < global_var.columns; i++) {
+			n_l.push(1);
+		}
+		global_var.value.push(n_l);
+	}
+	if (global_var.type == Types.REAL) {
+		var n_l = [];
+		for (i = 0; i < global_var.columns; i++) {
+			n_l.push(1.0);
+		}
+		global_var.value.push(n_l);
+	}
+
+	if (global_var.type == Types.TEXT) {
+		var n_l = [];
+		for (i = 0; i < global_var.columns; i++) {
+			n_l.push(LocalizedStrings.getUI('text_start'));
+		}
+		global_var.value.push(n_l);
+	}
+
+	if (global_var.type == Types.BOOLEAN) {
+		var n_l = [];
+		for (i = 0; i < global_var.columns; i++) {
+			n_l.push(true);
+		}
+		global_var.value.push(n_l);
+	}
+}
+
+function alternateBooleanGlobalMatrixValue (global_var, row, index, value_container) {
+	global_var.value[row][index] = !global_var.value[row][index];
+	$(value_container).find('.span_value_variable').text(LocalizedStrings.getUI(global_var.value[row][index]));
+}
+
+function renderValues (global_var, global_container) {
+
+	var ret = "";
+	var j = 0;
+
+	if (global_var.dimensions == 0) {
+		if (global_var.type == Types.REAL) {
+			ret += '<div class="created_div_valor_var"><span class="span_value_variable simple_var">'+global_var.value.toFixed(1)+'</span>  </div> ';
+		} else {
+			if (global_var.type == Types.BOOLEAN) {
+				ret += '<div class="created_div_valor_var"><span class="span_value_variable boolean_simple_type">'+LocalizedStrings.getUI(global_var.value)+'</span>  </div> ';
+			} else {
+				ret += '<div class="created_div_valor_var"><span class="span_value_variable simple_var">'+global_var.value+'</span>  </div> ';
+			}
+		}
+	} else {
+		ret += '<table class="tabela_var">';
+
+		if (global_var.dimensions == 1) {
+			ret += '<tr>';
+			if (global_var.type == Types.REAL) {
+				for (var k = 0; k < global_var.columns; k++) {
+					ret += '<td><span class="span_value_variable vector_var" data-index="'+k+'">'+global_var.value[k].toFixed(1)+'</span></td>';
+				}
+			} else {
+				for (var k = 0; k < global_var.columns; k++) {
+					if (global_var.type == Types.BOOLEAN) {
+						ret += '<td><span class="span_value_variable boolean_vector_var" data-index="'+k+'">'+LocalizedStrings.getUI(global_var.value[k])+'</span></td>';
+					} else {
+						ret += '<td><span class="span_value_variable vector_var" data-index="'+k+'">'+global_var.value[k]+'</span>'+'</td>';
+					}
+				}
+			}
+			
+			ret += '</tr>';
+			ret += '</table>';
+
+			ret += '<div class="buttons_manage_columns"><i class="ui icon minus square outline remove_global_vector_column"></i>'
+		    	+ ' <i class="ui icon plus square outline add_global_vector_column"></i></div>';
+		}
+
+		if (global_var.dimensions == 2) {
+			if (global_var.type == Types.REAL) {
+				for (var l = 0; l < global_var.rows; l++) {
+    				ret += '<tr>';
+    				for (var k = 0; k < global_var.columns; k++) {
+    					ret += '<td><span class="span_value_variable matrix_var" data-index="'+k+'" data-row="'+l+'">'+global_var.value[l][k].toFixed(1)+'</span>'+'</td>';
+    				} 
+    				ret += '</tr>';
+				}
+			} else {
+				for (var l = 0; l < global_var.rows; l++) {
+    				ret += '<tr>';
+    				for (var k = 0; k < global_var.columns; k++) {
+    					if (global_var.type == Types.BOOLEAN) { 
+    						ret += '<td><span class="span_value_variable boolean_matrix_var" data-index="'+k+'" data-row="'+l+'">'+LocalizedStrings.getUI(global_var.value[l][k])+'</span></td>';
+    					} else {
+    						ret += '<td><span class="span_value_variable matrix_var" data-index="'+k+'" data-row="'+l+'">'+global_var.value[l][k]+'</span></td>';
+    					}
+    				} 
+    				ret += '</tr>';
+				}
+			}
+			if (global_var.rows == 0) {
+				ret += '<tr><td></td></tr>';
+			}
+			ret += '<tr><td colspan="'+global_var.columns+'" class="tr_manage_lines"><i class="ui icon minus square outline remove_global_matrix_line"></i>'
+		    	+ ' <i class="ui icon plus square outline add_global_matrix_line"></i></td></tr>';
+			ret += '</table>';
+
+			ret += '<div class="buttons_manage_columns"><i class="ui icon minus square outline remove_global_matrix_column"></i>'
+		    	+ ' <i class="ui icon plus square outline add_global_matrix_column"></i></div>';
+		}
+		
+	}
+
+	global_container.find( ".div_valor_var" ).html('');
+
+	ret = $(ret);
+
+	ret.find('.span_value_variable').data('associatedOject', global_var);
+
+	ret.find( ".boolean_simple_type" ).on('click', function(e){
+		alternateBooleanGlobalValue(global_var, this.parentNode);
+	});
+	ret.find( ".simple_var" ).on('click', function(e){
+		enableGlobalValueUpdate(global_var, this.parentNode);
+	});
+
+	ret.find( ".boolean_vector_var" ).on('click', function(e){
+		alternateBooleanGlobalVectorValue(global_var, $(this).data('index'), this.parentNode);
+	});
+	ret.find( ".vector_var" ).on('click', function(e){
+		enableGlobalVectorValueUpdate(global_var, $(this).data('index'), this.parentNode);
+	});
+	ret.find( ".remove_global_vector_column" ).on('click', function(e){
+		removeGlobalColumnVector(global_var);
+		global_container.find( ".div_valor_var" ).html('');
+		renderValues(global_var, global_container);
+	});
+	ret.find( ".add_global_vector_column" ).on('click', function(e){
+		addGlobalColumnVector(global_var);
+		global_container.find( ".div_valor_var" ).html('');
+		renderValues(global_var, global_container);
+	});
+	ret.find( ".remove_global_matrix_column" ).on('click', function(e){
+		removeColumnGlobalMatrix(global_var);
+		global_container.find( ".div_valor_var" ).html('');
+		renderValues(global_var, global_container);
+	});
+	ret.find( ".add_global_matrix_column" ).on('click', function(e){
+		addColumnGlobalMatrix(global_var);
+		global_container.find( ".div_valor_var" ).html('');
+		renderValues(global_var, global_container);
+	});
+	ret.find( ".remove_global_matrix_line" ).on('click', function(e){
+		removeLineGlobalMatrix(global_var);
+		global_container.find( ".div_valor_var" ).html('');
+		renderValues(global_var, global_container);
+	});
+	ret.find( ".add_global_matrix_line" ).on('click', function(e){
+		addLineGlobalMatrix(global_var);
+		global_container.find( ".div_valor_var" ).html('');
+		renderValues(global_var, global_container);
+	});
+	ret.find( ".boolean_matrix_var" ).on('click', function(e){
+		alternateBooleanGlobalMatrixValue(global_var, $(this).data('row'), $(this).data('index'), this.parentNode);
+	});
+	ret.find( ".matrix_var" ).on('click', function(e){
+		enableGlobalMatrixValueUpdate(global_var, $(this).data('row'), $(this).data('index'), this.parentNode);
+	});
+	global_container.find( ".div_valor_var" ).append(ret);
+
+
+	updateColumnsAndRowsText(global_container, global_var);
+
+}
+
+function addHandlers (global_container) {
+	var global_var = global_container.data('associatedOject'); 
+	// Manage constant option:
+	global_container.find( ".alternate_constant" ).on('click', function(e){
+		toggleConstant(global_var);
+
+		$( this ).removeClass( "on off" );
+		if (global_var.is_constant) {
+			$( this ).addClass( "on" );
+		} else {
+			$( this ).addClass( "off" );
+		}
+	});
+
+	// Manage global name: 
+	global_container.find( ".enable_edit_name_parameter" ).on('click', function(e){
+		enableNameUpdate(global_container);
+	});
+
+	// Menu to change type:
+	global_container.find('.ui.dropdown.global_type').dropdown({
+	    onChange: function(value, text, $selectedItem) {
+	    	if ($selectedItem.data('dimensions')) {
+	    		updateType(global_var, Types[$selectedItem.data('type')], $selectedItem.data('dimensions'));
+	    	} else {
+	    		updateType(global_var, Types[$selectedItem.data('type')]);
+	    	}
+
+	    	renderValues(global_var, global_container);
+
+	    }
+	});
+
+	// Remove global: 
+	global_container.find( ".remove_global" ).on('click', function(e){
+		removeGlobal(global_var, global_container);
+	});
+
+}
+
+function updateColumnsAndRowsText (global_container, global_var) {
+	var prev = global_container.find('.text').text().split('[');
+	if (prev.length == 2) {
+		var ff = prev[0] + '[ ' + global_var.columns + ' ] ';
+		global_container.find('.text').empty();
+		global_container.find('.text').text(ff);
+	}
+	if (prev.length == 3) {
+		var ff = prev[0] + '[ ' + global_var.columns + ' ] [ ' + global_var.rows + ' ] ';
+		global_container.find('.text').empty();
+		global_container.find('.text').text(ff);
+	}
+}
+
+export function renderGlobal (global_var) {
+
+	var element = '<div class="ui label global_container"><div class="global_const">const: ';
+
+	element += '<i class="ui icon toggle '+(global_var.is_constant?"on":"off")+' alternate_constant"></i></div>';
+ 	
+ 	element += '<div class="ui dropdown global_type">';
+
+  	if (global_var.dimensions > 0) {
+  		element += '<div class="text">'+ i18n('ui:vector') + ':' + LocalizedStrings.getUI(global_var.type);
+  		for (var i = 0; i < global_var.dimensions; i ++) {
+  			element += ' [ <span class="dimensions_'+i+'"></span> ] ';
+  		}
+  		element += '</div>';
+  	} else {
+  		element += '<div class="text">' + LocalizedStrings.getUI(global_var.type.toLowerCase()) + '</div>';
+  	}
+	element += '<div class="menu">';
+
+	for (var tm in Types) {
+  		if (tm == Types.VOID.toUpperCase()) {
+  			continue;
+  		}
+  		element += '<div class="item ' + (global_var.type == tm.toLowerCase() ? ' selected ' : '') + '" data-type="'+tm+'" >'+LocalizedStrings.getUI(tm.toLowerCase())+'</div>';
+	}
+
+  	for (var tm in Types) {
+  		if (tm == Types.VOID.toUpperCase()) {
+  			continue;
+  		}
+  		element += '<div class="item">'
+	    	+ '<i class="dropdown icon"></i>'
+	    	+  LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())
+	      	+  '<div class="menu">'
+		        + '<div class="item" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] " data-type="'+tm+'" data-dimensions="1">[ ]</div>'
+		        + '<div class="item" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] [ ] " data-type="'+tm+'" data-dimensions="2">[ ] [ ] </div>'
+	      	+  '</div>'
+	    	+ '</div>';	
+  	}
+
+    element += '</div></div> <div class="editing_name_var"> <span class="span_name_variable enable_edit_name_parameter">'+global_var.name+'</span> </div> <span class="character_equals"> = </span> ';
+
+	element += '<div class="ui div_valor_var">'+global_var.value+'</div>';    
+
+	element += ' <i class="red icon times remove_global"></i></div>';
+
+	var complete_element = $(element);
+
+	complete_element.data('associatedOject', global_var);
+
+	$('.list_globals').append(complete_element);
+
+	addHandlers(complete_element);
+
+	renderValues(global_var, complete_element);
+
+	if (global_var.dimensions == 1) {
+		complete_element.find('.dimensions_0').text(global_var.columns);
+	}
+	if (global_var.dimensions == 2) {
+		complete_element.find('.dimensions_0').text(global_var.columns);
+		complete_element.find('.dimensions_1').text(global_var.rows);
+	}
+}
+
+var opened_name_value_matrix_global_v = false;
+var opened_input_value_matrix_global_v = null;
+function enableGlobalMatrixValueUpdate (global_var, row, index, parent_node) {
+	if (opened_name_value_matrix_global_v) {
+		opened_input_value_matrix_global_v.focus();
+		return;
+	}
+	parent_node = $(parent_node);
+	opened_name_value_matrix_global_v = true;
+
+	parent_node.find('.span_value_variable').text('');
+
+	var input_field;
+
+	if (global_var.type == Types.REAL) {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ global_var.value[row][index].toFixed(1) + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	} else {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ global_var.value[row][index] + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	}
+
+	input_field.on('input', function() {
+	    var inputWidth = input_field.textWidth()+10;
+	    opened_input_value_matrix_global_v = input_field;
+	    input_field.focus();
+
+	    var tmpStr = input_field.val();
+		input_field.val('');
+		input_field.val(tmpStr);
+
+	    input_field.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_field.focusout(function() {
+		/// update array:
+		if (input_field.val().trim()) {
+			if (global_var.type == Types.REAL) {
+				global_var.value[row][index] = parseFloat(input_field.val().trim());
+
+				parent_node.find('.span_value_variable').text(global_var.value[row][index].toFixed(1));
+			} else {
+				if (global_var.type == Types.INTEGER) {
+					global_var.value[row][index] = parseInt(input_field.val().trim());
+				} else {
+					global_var.value[row][index] = input_field.val().trim();
+				}
+				parent_node.find('.span_value_variable').text(global_var.value[row][index]);
+			}
+		} else {
+			if (global_var.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(global_var.value[row][index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(global_var.value[row][index]);
+			}
+		}
+		if (global_var.type == Types.TEXT) {
+			global_var.value[row][index] = input_field.val();
+			parent_node.find('.span_value_variable').text(global_var.value[row][index]);
+		}
+		input_field.off();
+		input_field.remove();
+
+		/// update elements:
+		opened_name_value_matrix_global_v = false;
+		opened_input_value_matrix_global_v = false;
+	});
+
+	input_field.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_field.val().trim()) {
+				if (global_var.type == Types.REAL) {
+					global_var.value[row][index] = parseFloat(input_field.val().trim());
+
+					parent_node.find('.span_value_variable').text(global_var.value[row][index].toFixed(1));
+				} else {
+					if (global_var.type == Types.INTEGER) {
+						global_var.value[row][index] = parseInt(input_field.val().trim());
+					} else {
+						global_var.value[row][index] = input_field.val().trim();
+					}
+					parent_node.find('.span_value_variable').text(global_var.value[row][index]);
+				}
+			} else {
+				if (global_var.type == Types.REAL) {
+					parent_node.find('.span_value_variable').text(global_var.value[row][index].toFixed(1));
+				} else {
+					parent_node.find('.span_value_variable').text(global_var.value[row][index]);
+				}
+			}
+			if (global_var.type == Types.TEXT) {
+				global_var.value[row][index] = input_field.val();
+				parent_node.find('.span_value_variable').text(global_var.value[row][index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_matrix_global_v = false;
+			opened_input_value_matrix_global_v = false;
+		}
+		if(code == 27) {
+			if (global_var.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(global_var.value[row][index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(global_var.value[row][index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_matrix_global_v = false;
+			opened_input_value_matrix_global_v = false;
+		}
+	});
+	input_field.select();
+}
+
+var opened_name_value_global_var = false;
+var opened_input_value_global_ar = null;
+function enableGlobalValueUpdate (global_var, parent_node) {
+	if (opened_name_value_global_var) {
+		opened_input_value_global_ar.focus();
+		return;
+	}
+	parent_node = $(parent_node);
+	opened_name_value_global_var = true;
+
+	parent_node.find('.span_value_variable').text('');
+
+	var input_field;
+
+	if (global_var.type == Types.REAL) {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ global_var.value.toFixed(1) + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	} else {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ global_var.value + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	}
+
+	input_field.on('input', function() {
+	    var inputWidth = input_field.textWidth()+10;
+	    opened_input_value_global_ar = input_field;
+	    input_field.focus();
+
+	    var tmpStr = input_field.val();
+		input_field.val('');
+		input_field.val(tmpStr);
+
+	    input_field.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_field.focusout(function() {
+		/// update array:
+		if (input_field.val().trim()) {
+			if (global_var.type == Types.REAL) {
+				global_var.value = parseFloat(input_field.val().trim());
+				parent_node.find('.span_value_variable').text(global_var.value.toFixed(1));
+			} else{
+				if (global_var.type == Types.INTEGER) {
+					global_var.value = parseInt(input_field.val().trim());
+				} else {
+					global_var.value = input_field.val().trim();
+				}
+				parent_node.find('.span_value_variable').text(global_var.value);
+				
+			}
+		} else {
+			if (global_var.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(global_var.value.toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(global_var.value);
+			}
+		}
+		if (global_var.type == Types.TEXT) {
+			global_var.value = input_field.val();
+			parent_node.find('.span_value_variable').text(global_var.value);
+		}
+		input_field.off();
+		input_field.remove();
+
+		/// update elements:
+		opened_name_value_global_var = false;
+		opened_input_value_global_ar = false;
+
+	});
+
+	input_field.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_field.val().trim()) {
+				if (global_var.type == Types.REAL) {
+					global_var.value = parseFloat(input_field.val().trim());
+					parent_node.find('.span_value_variable').text(global_var.value.toFixed(1));
+				} else {
+					if (global_var.type == Types.INTEGER) {
+						global_var.value = parseInt(input_field.val().trim());
+					} else {
+						global_var.value = input_field.val().trim();
+					}
+					parent_node.find('.span_value_variable').text(global_var.value);
+				}
+			} else {
+				if (global_var.type == Types.REAL) {
+					parent_node.find('.span_value_variable').text(global_var.value.toFixed(1));
+				} else {
+					parent_node.find('.span_value_variable').text(global_var.value);
+				}
+			}
+			if (global_var.type == Types.TEXT) {
+				global_var.value = input_field.val();
+				parent_node.find('.span_value_variable').text(global_var.value);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_global_var = false;
+			opened_input_value_global_ar = false;
+
+		}
+		if(code == 27) {
+			if (global_var.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(global_var.value.toFixed(1));
+			} else{
+				parent_node.find('.span_value_variable').text(global_var.value);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_global_var = false;
+			opened_input_value_global_ar = false;
+		}
+	});
+
+	input_field.select();
+}
+
+
+var opened_name_global = false;
+var opened_input_global = null;
+function enableNameUpdate (global_container) {
+
+	var global_var = global_container.data('associatedOject'); 
+
+	if (opened_name_global) {
+		opened_input_global.focus();
+		return;
+	}
+	opened_name_global = true;
+
+	global_container.find('.span_name_variable').text('');
+	var input_name = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"+global_var.name+"' />" );
+	input_name.insertBefore(global_container.find('.span_name_variable'));
+
+	input_name.on('input', function() {
+	    var inputWidth = input_name.textWidth()+10;
+	    opened_input_global = input_name;
+	    opened_input_global.focus();
+
+	    opened_input_global.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_name.focusout(function() {
+		/// update array:
+		if (input_name.val().trim().length > 0) {
+			updateName(global_var, input_name.val().trim());
+			global_container.find('.span_name_variable').text(global_var.name);
+		} else {
+			global_container.find('.span_name_variable').text(global_var.name);
+		}
+		input_name.off();
+		input_name.remove();
+
+		/// update elements:
+		opened_name_global = false;
+		opened_input_global = false;
+	});
+
+	input_name.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_name.val().trim()) {
+				updateName(global_var, input_name.val().trim());
+				global_container.find('.span_name_variable').text(global_var.name);
+			} else {
+				global_container.find('.span_name_variable').text(global_var.name);
+			}
+			input_name.off();
+			input_name.remove();
+
+			/// update elements:
+			opened_name_global = false;
+			opened_input_global = false;
+		}
+		if(code == 27) {
+
+			global_container.find('.span_name_variable').text(global_var.name);
+			input_name.off();
+			input_name.remove();
+
+			/// update elements:
+			opened_name_global = false;
+			opened_input_global = false;
+		}
+	});
+
+	input_name.select();
+	
+}
+
+
+var opened_name_value_vector_global_ = false;
+var opened_input_value_vector_global_ = null;
+function enableGlobalVectorValueUpdate (global_var, index, parent_node) {
+	if (opened_name_value_vector_global_) {
+		opened_input_value_vector_global_.focus();
+		return;
+	}
+	parent_node = $(parent_node);
+	opened_name_value_vector_global_ = true;
+
+	parent_node.find('.span_value_variable').text('');
+
+	var input_field;
+
+	if (global_var.type == Types.REAL) {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ global_var.value[index].toFixed(1) + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	} else {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ global_var.value[index] + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	}
+
+	input_field.on('input', function() {
+	    var inputWidth = input_field.textWidth()+10;
+	    opened_input_value_vector_global_ = input_field;
+	    input_field.focus();
+
+	    var tmpStr = input_field.val();
+		input_field.val('');
+		input_field.val(tmpStr);
+
+	    input_field.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_field.focusout(function() {
+		/// update array:
+		if (input_field.val().trim()) {
+			if (global_var.type == Types.REAL) {
+				global_var.value[index] = parseFloat(input_field.val().trim());
+
+				parent_node.find('.span_value_variable').text(global_var.value[index].toFixed(1));
+			} else {
+
+				if (global_var.type == Types.INTEGER) {
+					global_var.value[index] = parseInt(input_field.val().trim());
+				} else {
+					global_var.value[index] = input_field.val().trim();
+				}
+
+				parent_node.find('.span_value_variable').text(global_var.value[index]);
+
+			}
+		} else {
+			if (global_var.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(global_var.value[index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(global_var.value[index]);
+			}
+		}
+		if (global_var.type == Types.TEXT) {
+			global_var.value[index] = input_field.val();
+			parent_node.find('.span_value_variable').text(global_var.value[index]);
+		}
+		input_field.off();
+		input_field.remove();
+
+		/// update elements:
+		opened_name_value_vector_global_ = false;
+		opened_input_value_vector_global_ = false;
+	});
+
+	input_field.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_field.val().trim()) {
+				if (global_var.type == Types.REAL) {
+					global_var.value[index] = parseFloat(input_field.val().trim());
+
+					parent_node.find('.span_value_variable').text(global_var.value[index].toFixed(1));
+				} else {
+
+					if (global_var.type == Types.INTEGER) {
+						global_var.value[index] = parseInt(input_field.val().trim());
+					} else {
+						global_var.value[index] = input_field.val().trim();
+					}
+
+					parent_node.find('.span_value_variable').text(global_var.value[index]);
+
+				}
+			} else {
+				if (global_var.type == Types.REAL) {
+					parent_node.find('.span_value_variable').text(global_var.value[index].toFixed(1));
+				} else {
+					parent_node.find('.span_value_variable').text(global_var.value[index]);
+				}
+			}
+			if (global_var.type == Types.TEXT) {
+				global_var.value[index] = input_field.val();
+				parent_node.find('.span_value_variable').text(global_var.value[index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_vector_global_ = false;
+			opened_input_value_vector_global_ = false;
+		}
+		if(code == 27) {
+			if (global_var.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(global_var.value[index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(global_var.value[index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_vector_global_ = false;
+			opened_input_value_vector_global_ = false;
+		}
+	});
+
+	input_field.select();
+}
+
+
+$.fn.textWidth = function(text, font) {
+    
+    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
+    
+    $.fn.textWidth.fakeEl.text(text || this.val() || this.text() || this.attr('placeholder')).css('font', font || this.css('font'));
+    
+    return $.fn.textWidth.fakeEl.width();
+};

+ 268 - 0
js/visualUI/ivprog_elements.js

@@ -0,0 +1,268 @@
+import * as VariableValueMenuManagement from './commands/variable_value_menu';
+import { Types } from './types';
+import WatchJS from 'melanke-watchjs';
+import * as AlgorithmManagement from './algorithm';
+
+export const COMMAND_TYPES = Object.freeze({function:"function", comment:"comment", reader:"reader", writer:"writer", attribution:"attribution", iftrue:"iftrue",
+ repeatNtimes:"repeatNtimes", whiletrue:"whiletrue", dowhiletrue:"dowhiletrue", switch:"switch", switchcase:"switchcase", functioncall:"functioncall", break:"break",
+ return:"return"});
+
+export const ARITHMETIC_TYPES = Object.freeze({plus:"plus", minus:"minus", multiplication:"multiplication", division:"division", module:"module", none:"none"});
+
+export const EXPRESSION_ELEMENTS = Object.freeze({exp_op_exp:"exp_op_exp", op_exp:"op_exp", par_exp_par:"par_exp_par", start_point:"start_point"});
+
+export const EXPRESSION_TYPES = Object.freeze({exp_conditional:"exp_conditional", exp_logic:"exp_logic", exp_arithmetic:"exp_arithmetic"});
+
+export const ARITHMETIC_COMPARISON = Object.freeze({greater_than:"greater_than", less_than:"less_than", equals_to:"equals_to", not_equals_to:"not_equals_to", greater_than_or_equals_to:"greater_than_or_equals_to", less_than_or_equals_to:"less_than_or_equals_to"});
+
+export const LOGIC_COMPARISON = Object.freeze({equals_to:"equals_to", not_equals_to:"not_equals_to", and:"and", or:"or"});
+
+export const SYSTEM_FUNCTIONS_CATEGORIES = Object.freeze({math:"math", text:"text", arrangement:"arrangement", conversion:"conversion"});
+
+export class Variable {
+
+  constructor (type, name, value, dimensions = 0, is_constant = false, rows = 0, columns = 0) {
+    this.type = type;
+    this.name = name;
+    this.value = value;
+    this.dimensions = dimensions;
+    this.is_constant = is_constant;
+    this.rows = rows;
+    this.columns = columns;
+  }
+}
+
+export class Function {
+
+  constructor (name, return_type = Types.VOID, return_dimensions = 0, parameters_list = [], is_main = false, is_hidden = false, variables_list = [], function_comment = null, commands = []) {
+    this.type = COMMAND_TYPES.function;
+    this.name = name;
+    this.return_type = return_type;
+    this.return_dimensions = return_dimensions;
+    this.parameters_list = parameters_list;
+    this.is_main = is_main;
+    this.is_hidden = is_hidden;
+    this.variables_list = variables_list;
+    this.function_comment = function_comment;
+    this.commands = commands;
+  }
+}
+
+export class SystemFunction {
+
+  constructor (identifier, return_type, return_dimensions, parameters_list, function_comment = null, category) {
+    this.type = COMMAND_TYPES.function;
+    this.identifier = identifier;
+    this.return_type = return_type;
+    this.return_dimensions = return_dimensions;
+    this.parameters_list = parameters_list;
+    this.function_comment = function_comment;
+    this.category = category;
+  }
+}
+
+export class Comment {
+  
+  constructor (comment_text) {
+    this.type = COMMAND_TYPES.comment;
+    this.comment_text = comment_text;
+  }
+}
+
+export class Break {
+  
+  constructor () {
+    this.type = COMMAND_TYPES.break;
+  }
+}
+
+export class Reader {
+  
+  constructor (variable_value_menu = new VariableValueMenu()) {
+    this.type = COMMAND_TYPES.reader;
+    this.variable_value_menu = variable_value_menu;
+  }
+}
+
+export class Writer {
+
+  constructor (content) {
+    this.type = COMMAND_TYPES.writer;
+    this.content = content;
+  }
+}
+
+export class Attribution {
+
+  constructor (variable, expression = []) {
+    this.type = COMMAND_TYPES.attribution;
+    this.variable = variable;
+    this.expression = expression;
+  }
+}
+
+export class ExpressionElement {
+
+  constructor (type_exp, itens = []) {
+    this.type_exp = type_exp;
+    this.itens = itens;
+  }
+}
+
+export class ConditionalExpression {
+
+  constructor (expression) {
+    this.type = EXPRESSION_TYPES.exp_conditional;
+    this.expression = expression;
+  }
+}
+
+export class LogicExpression {
+
+  constructor (has_neg, first_operand, second_operand, operator) {
+    this.type = EXPRESSION_TYPES.exp_logic;
+    this.has_neg = has_neg;
+    this.first_operand = first_operand;
+    this.second_operand = second_operand;
+    this.operator = operator;
+  }
+}
+
+export class ArithmeticExpression {
+
+  constructor (first_operand, second_operand, operator) {
+    this.type = EXPRESSION_TYPES.exp_arithmetic;
+    this.first_operand = first_operand;
+    this.second_operand = second_operand;
+    this.operator = operator;
+  }
+}
+
+export class IfTrue {
+
+  constructor (expression, commands_block, commands_else) {
+    this.type = COMMAND_TYPES.iftrue;
+    this.expression = expression;
+    this.commands_block = commands_block;
+    this.commands_else = commands_else;
+  }
+}
+
+export class RepeatNTimes {
+
+  constructor (var_attribution, var_incrementation, expression1, expression2, expression3, commands_block) {
+    this.type = COMMAND_TYPES.repeatNtimes;
+    this.var_attribution = var_attribution;
+    this.var_incrementation = var_incrementation;
+    this.expression1 = expression1;
+    this.expression2 = expression2;
+    this.expression3 = expression3;
+    this.commands_block = commands_block;
+  }
+}
+
+export class WhileTrue {
+
+  constructor (expression, commands_block) {
+    this.type = COMMAND_TYPES.whiletrue;
+    this.expression = expression;
+    this.commands_block = commands_block;
+  }
+}
+
+export class DoWhileTrue {
+
+  constructor (expression, commands_block) {
+    this.type = COMMAND_TYPES.dowhiletrue;
+    this.expression = expression;
+    this.commands_block = commands_block;
+  }
+}
+
+export class Switch {
+
+  constructor (variable, cases = []) {
+    this.type = COMMAND_TYPES.switch;
+    this.variable = variable;
+    this.cases = cases;
+  }
+}
+
+export class Return {
+
+ constructor (variable_value_menu) {
+    this.type = COMMAND_TYPES.return;
+    this.variable_value_menu = variable_value_menu;
+  } 
+}
+
+export class SwitchCase {
+
+ constructor (variable_value_menu, commands_block = []) {
+    this.type = COMMAND_TYPES.switchcase;
+    this.variable_value_menu = variable_value_menu;
+    this.commands_block = commands_block;
+  } 
+}
+
+export class FunctionCall {
+
+  constructor (function_called, parameters_list) {
+    this.type = COMMAND_TYPES.functioncall;
+    this.function_called = function_called;
+    this.parameters_list = parameters_list;
+  }
+}
+
+export class VariableValueMenu {
+  
+  constructor (variable_and_value = 7, content = null, row = null, column = null, include_constant = true) {
+    this.type = "var_value";
+    this.variable_and_value = variable_and_value;
+    this.content = content;
+    this.row = row;
+    this.column = column;
+    this.include_constant = include_constant;
+  }
+}
+
+export class FunctionCallMenu {
+  
+  constructor (function_called = null, parameters_list = []) {
+    this.type = "function_call";
+    this.function_called = function_called;
+    this.parameters_list = parameters_list;
+  }
+}
+
+export class Program {
+
+  constructor () {
+    this.functions = [];
+    this.globals = [];
+  }
+
+  addFunction (function_to_add) {
+
+    WatchJS.watch(function_to_add.parameters_list, function(){
+      AlgorithmManagement.renderAlgorithm();
+    }, 1);
+
+    WatchJS.watch(function_to_add.variables_list, function(){
+      AlgorithmManagement.renderAlgorithm();
+    }, 1);
+
+    this.functions.push(function_to_add);
+  }
+
+  addVariable (function_to_receive, variable) {
+    if (this.functions[function_to_receive].variable === null) {
+      this.functions[function_to_receive].variables_list = [];
+    }
+    this.functions[function_to_receive].variables_list.push(variable);
+  }
+
+  addGlobal (variable) {
+    this.globals.push(variable);
+  }
+}

js/ivprog-visual-functions-1.0.js → js/visualUI/old_functions.js


js/ivprog-visual-1.0.js → js/visualUI/old_visual.js


+ 7 - 0
js/visualUI/types.js

@@ -0,0 +1,7 @@
+export const Types = Object.freeze({
+  INTEGER: "integer",
+  REAL: "real",
+  TEXT: "text",
+  BOOLEAN: "boolean",
+  VOID: "void"
+});

+ 921 - 0
js/visualUI/variables.js

@@ -0,0 +1,921 @@
+import $ from 'jquery';
+import jQuery from 'jquery';
+import { Types } from './types';
+import * as Models from './ivprog_elements';
+import { LocalizedStrings } from './../services/localizedStringsService';
+
+
+window.jQuery = jQuery;
+
+import '../semantic/semantic.min.js';
+
+var counter_new_variables = 0;
+
+export function addVariable (function_obj, function_container) {
+	var new_var = new Models.Variable(Types.INTEGER, LocalizedStrings.getUI('new_variable') + '_' + counter_new_variables, 1);
+	if (function_obj.variables_list == null) {
+		function_obj.variables_list = [];
+	}
+	function_obj.variables_list.push(new_var);
+
+	counter_new_variables ++;
+
+	renderVariable(function_container, new_var, function_obj);
+}
+
+function updateName (variable_obj, new_name) {
+	variable_obj.name = new_name;
+}
+
+function removeVariable (variable_obj, variable_container) {
+	var function_associated = variable_container.data('associatedFunction');
+
+	var index = function_associated.variables_list.indexOf(variable_obj);
+	if (index > -1) {
+	  //function_associated.variables_list[index] = null;
+	  delete function_associated.variables_list[index];
+	  function_associated.variables_list.splice(index, 1);
+	}
+	variable_container.children().off();
+	variable_container.off();
+	variable_container.remove();
+}
+
+function updateType (variable_obj, new_type, new_dimensions = 0) {
+	variable_obj.type = new_type;
+	variable_obj.dimensions = new_dimensions;
+
+	if (new_dimensions > 0) {
+		variable_obj.rows = new_dimensions;
+		variable_obj.columns = 2;
+	}
+
+	updateInitialValues(variable_obj);
+}
+
+function addHandlers (variable_obj, variable_container) {
+
+	// Manage variable name: 
+	variable_container.find( ".enable_edit_name_variable" ).on('click', function(e){
+		enableNameUpdate(variable_obj, variable_container);
+	});
+
+	// Menu to change type:
+	variable_container.find('.ui.dropdown.variable_type').dropdown({
+	    onChange: function(value, text, $selectedItem) {
+	    	if ($selectedItem.data('dimensions')) {
+	    		updateType(variable_obj, Types[$selectedItem.data('type')], $selectedItem.data('dimensions'));
+	    	} else {
+	    		updateType(variable_obj, Types[$selectedItem.data('type')]);
+	    	}
+
+	    	renderValues(variable_obj, variable_container);
+	    }
+	});
+
+	// Remove variable: 
+	variable_container.find( ".remove_variable" ).on('click', function(e){
+		removeVariable(variable_obj, variable_container);
+	});
+
+}
+
+
+export function renderVariable (function_container, new_var, function_obj) {
+
+	var element = '<div class="ui label variable_container">';
+
+	element += '<div class="ui dropdown variable_type">';
+
+  	if (new_var.dimensions > 0) {
+  		element += '<div class="text">'+ LocalizedStrings.getUI('vector') + ':' + LocalizedStrings.getUI(new_var.type.toLowerCase());
+  		for (var i = 0; i < new_var.dimensions; i ++) {
+  			element += ' [ ] ';
+  		}
+  		element += '</div>';
+  	} else {
+  		element += '<div class="text">' + LocalizedStrings.getUI(new_var.type.toLowerCase()) + '</div>';
+  	}
+	element += '<div class="menu">';
+
+	for (var tm in Types) {
+  		if (tm == Types.VOID.toUpperCase()) {
+  			continue;
+  		}
+  		element += '<div class="item ' + (new_var.type == tm.toLowerCase() ? ' selected ' : '') + '" data-type="'+tm+'" >'+LocalizedStrings.getUI(tm.toLowerCase())+'</div>';
+	}
+
+  	for (var tm in Types) {
+  		if (tm == Types.VOID.toUpperCase()) {
+  			continue;
+  		}
+  		element += '<div class="item">'
+  			+ '<i class="dropdown icon"></i>'
+	    	+  LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())
+	      	+  '<div class="menu">'
+		        + '<div class="item" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] " data-type="'+tm+'" data-dimensions="1">[ ]</div>'
+		        + '<div class="item" data-text="'+ LocalizedStrings.getUI('vector')+':'+LocalizedStrings.getUI(tm.toLowerCase())+' [ ] [ ] " data-type="'+tm+'" data-dimensions="2">[ ] [ ] </div>'
+	      	+  '</div>'
+	    	+ '</div>';	
+  	}
+
+    element += '</div></div> ';
+
+    element += '<div class="editing_name_var"><span class="span_name_variable enable_edit_name_variable">'+new_var.name+'</span> </div>';
+
+	element += ' <span class="character_equals"> = </span> <div class="ui div_valor_var">'+new_var.value+'</div>';    
+
+	element += ' <i class="red icon times remove_variable"></i></div>';
+
+	element = $(element);
+
+	element.data('associatedFunction', function_obj);
+
+	function_container.find('.variables_list_div').append(element);
+
+	addHandlers(new_var, element);
+
+	renderValues(new_var, element);
+}
+
+function updateColumnsAndRowsText (variable_container, variable_var) {
+	var prev = variable_container.find('.text').text().split('[');
+	if (prev.length == 2) {
+		var ff = prev[0] + '[ ' + variable_var.columns + ' ] ';
+		variable_container.find('.text').empty();
+		variable_container.find('.text').text(ff);
+	}
+	if (prev.length == 3) {
+		var ff = prev[0] + '[ ' + variable_var.columns + ' ] [ ' + variable_var.rows + ' ] ';
+		variable_container.find('.text').empty();
+		variable_container.find('.text').text(ff);
+	}
+}
+
+function renderValues (new_var, variable_container) {
+
+	var ret = "";
+	var j = 0;
+
+	if (new_var.dimensions == 0) {
+		if (new_var.type == Types.REAL) {
+			ret += '<div class="created_div_valor_var"><span class="span_value_variable simple_var">'+new_var.value.toFixed(1)+'</span> </div> ';
+		} else {
+			if (new_var.type == Types.BOOLEAN) {
+				ret += '<div class="created_div_valor_var"><span class="span_value_variable boolean_simple_type">'+LocalizedStrings.getUI(new_var.value)+'</span> </div> ';
+			} else {
+				ret += '<div class="created_div_valor_var"><span class="span_value_variable simple_var">'+new_var.value+'</span> </div> ';
+			}
+		}
+	} else {
+		ret += '<table class="tabela_var">';
+
+		if (new_var.dimensions == 1) {
+			ret += '<tr>';
+			if (new_var.type == Types.REAL) {
+				for (var k = 0; k < new_var.columns; k++) {
+					ret += '<td><span class="span_value_variable vector_var" data-index="'+k+'">'+new_var.value[k].toFixed(1)+'</span></td>';
+				}
+			} else {
+				for (var k = 0; k < new_var.columns; k++) {
+					if (new_var.type == Types.BOOLEAN) {
+						ret += '<td><span class="span_value_variable boolean_vector_var" data-index="'+k+'">'+LocalizedStrings.getUI(new_var.value[k])+'</span></td>';
+					} else {
+						ret += '<td><span class="span_value_variable vector_var" data-index="'+k+'">'+new_var.value[k]+'</span>'+'</td>';
+					}
+				}
+			}
+			
+			ret += '</tr>';
+			ret += '</table>';
+
+			ret += '<div class="buttons_manage_columns"><i class="ui icon minus square outline remove_global_vector_column"></i>'
+		    	+ ' <i class="ui icon plus square outline add_global_vector_column"></i></div>';
+		}
+
+		if (new_var.dimensions == 2) {
+			if (new_var.type == Types.REAL) {
+				for (var l = 0; l < new_var.rows; l++) {
+    				ret += '<tr>';
+    				for (var k = 0; k < new_var.columns; k++) {
+    					ret += '<td><span class="span_value_variable matrix_var" data-index="'+k+'" data-row="'+l+'">'+new_var.value[l][k].toFixed(1)+'</span>'+'</td>';
+    				} 
+    				ret += '</tr>';
+				}
+			} else {
+				for (var l = 0; l < new_var.rows; l++) {
+    				ret += '<tr>';
+    				for (var k = 0; k < new_var.columns; k++) {
+    					if (new_var.type == Types.BOOLEAN) { 
+    						ret += '<td><span class="span_value_variable boolean_matrix_var" data-index="'+k+'" data-row="'+l+'">'+LocalizedStrings.getUI(new_var.value[l][k])+'</span></td>';
+    					} else {
+    						ret += '<td><span class="span_value_variable matrix_var" data-index="'+k+'" data-row="'+l+'">'+new_var.value[l][k]+'</span></td>';
+    					}
+    				} 
+    				ret += '</tr>';
+				}
+			}
+			if (new_var.rows == 0) {
+				ret += '<tr><td></td></tr>';
+			}
+			ret += '<tr><td colspan="'+new_var.columns+'" class="tr_manage_lines"><i class="ui icon minus square outline remove_global_matrix_line"></i>'
+		    	+ ' <i class="ui icon plus square outline add_global_matrix_line"></i></td></tr>';
+			ret += '</table>';
+
+			ret += '<div class="buttons_manage_columns"><i class="ui icon minus square outline remove_global_matrix_column"></i>'
+		    	+ ' <i class="ui icon plus square outline add_global_matrix_column"></i></div>';
+		}
+		
+	}
+
+	$( variable_container ).find( ".div_valor_var" ).html('');
+
+	ret = $(ret);
+
+	$(ret).find('.span_value_variable').data('associatedOject', new_var);
+
+	$( ret ).find( ".boolean_simple_type" ).on('click', function(e){
+		alternateBooleanValue(new_var, this.parentNode);
+	});
+	$( ret ).find( ".simple_var" ).on('click', function(e){
+		enableValueUpdate(new_var, this.parentNode);
+	});
+
+	$( ret ).find( ".boolean_vector_var" ).on('click', function(e){
+		alternateBooleanVectorValue(new_var, $(this).data('index'), this.parentNode);
+	});
+	$( ret ).find( ".vector_var" ).on('click', function(e){
+		enableVectorValueUpdate(new_var, $(this).data('index'), this.parentNode);
+	});
+	$( ret ).find( ".remove_global_vector_column" ).on('click', function(e){
+		removeColumnVector(new_var);
+		$( variable_container ).find( ".div_valor_var" ).html('');
+		renderValues(new_var, variable_container);
+	});
+	$( ret ).find( ".add_global_vector_column" ).on('click', function(e){
+		addColumnVector(new_var);
+		$( variable_container ).find( ".div_valor_var" ).html('');
+		renderValues(new_var, variable_container);
+	});
+	$( ret ).find( ".remove_global_matrix_column" ).on('click', function(e){
+		removeColumnMatrix(new_var);
+		$( variable_container ).find( ".div_valor_var" ).html('');
+		renderValues(new_var, variable_container);
+	});
+	$( ret ).find( ".add_global_matrix_column" ).on('click', function(e){
+		addColumnMatrix(new_var);
+		$( variable_container ).find( ".div_valor_var" ).html('');
+		renderValues(new_var, variable_container);
+	});
+	$( ret ).find( ".remove_global_matrix_line" ).on('click', function(e){
+		removeLineMatrix(new_var);
+		$( variable_container ).find( ".div_valor_var" ).html('');
+		renderValues(new_var, variable_container);
+	});
+	$( ret ).find( ".add_global_matrix_line" ).on('click', function(e){
+		addLineMatrix(new_var);
+		$( variable_container ).find( ".div_valor_var" ).html('');
+		renderValues(new_var, variable_container);
+	});
+	$( ret ).find( ".boolean_matrix_var" ).on('click', function(e){
+		alternateBooleanMatrixValue(new_var, $(this).data('row'), $(this).data('index'), this.parentNode);
+	});
+	$( ret ).find( ".matrix_var" ).on('click', function(e){
+		enableMatrixValueUpdate(new_var, $(this).data('row'), $(this).data('index'), this.parentNode);
+	});
+	$( variable_container ).find( ".div_valor_var" ).append(ret);
+
+	updateColumnsAndRowsText(variable_container, new_var);
+
+}
+
+function alternateBooleanMatrixValue (var_obj, row, index, value_container) {
+	var_obj.value[row][index] = !var_obj.value[row][index];
+	$(value_container).find('.span_value_variable').text(LocalizedStrings.getUI(var_obj.value[row][index]));
+}
+
+function addLineMatrix (var_obj) {
+	var_obj.rows ++;
+
+	if (var_obj.type == Types.INTEGER) {
+		var n_l = [];
+		for (var i = 0; i < var_obj.columns; i++) {
+			n_l.push(1);
+		}
+		var_obj.value.push(n_l);
+	}
+	if (var_obj.type == Types.REAL) {
+		var n_l = [];
+		for (i = 0; i < var_obj.columns; i++) {
+			n_l.push(1.0);
+		}
+		var_obj.value.push(n_l);
+	}
+
+	if (var_obj.type == Types.TEXT) {
+		var n_l = [];
+		for (i = 0; i < var_obj.columns; i++) {
+			n_l.push(LocalizedStrings.getUI('text_start'));
+		}
+		var_obj.value.push(n_l);
+	}
+
+	if (var_obj.type == Types.BOOLEAN) {
+		var n_l = [];
+		for (i = 0; i < var_obj.columns; i++) {
+			n_l.push(true);
+		}
+		var_obj.value.push(n_l);
+	}
+}
+
+function removeLineMatrix (var_obj) {
+	if (var_obj.rows == 0) {
+		return;
+	}
+
+	var_obj.rows --;
+	var_obj.value.splice(var_obj.value.length - 1, 1);
+}
+
+function addColumnMatrix (var_obj) {
+	var_obj.columns ++;
+
+	if (var_obj.type == Types.INTEGER) {
+		for (var i = 0; i < var_obj.rows; i++) {
+			var_obj.value[i].push(1);
+		}
+	}
+	if (var_obj.type == Types.REAL) {
+		for (var i = 0; i < var_obj.rows; i++) {
+			var_obj.value[i].push(1.0);
+		}
+	}
+	if (var_obj.type == Types.TEXT) {
+		for (var i = 0; i < var_obj.rows; i++) {
+			var_obj.value[i].push(LocalizedStrings.getUI('text_start'));
+		}
+	}
+	if (var_obj.type == Types.BOOLEAN) {
+		for (var i = 0; i < var_obj.rows; i++) {
+			var_obj.value[i].push(true);
+		}
+	}
+}
+
+function removeColumnMatrix (var_obj) {
+	if (var_obj.columns == 0) {
+		return;
+	}
+
+	var_obj.columns --;
+
+	for (var i = 0; i < var_obj.rows; i++) {
+		var_obj.value[i].splice(var_obj.value[i].length - 1, 1);
+	}
+}
+
+function addColumnVector (var_obj) {
+	var_obj.columns ++;
+
+	if (var_obj.type == Types.INTEGER) {
+		var_obj.value.push(1);
+	}
+	if (var_obj.type == Types.REAL) {
+		var_obj.value.push(1.0);
+	}
+	if (var_obj.type == Types.TEXT) {
+		var_obj.value.push(LocalizedStrings.getUI('text_start'));
+	}
+	if (var_obj.type == Types.BOOLEAN) {
+		var_obj.value.push(true);
+	}
+}
+
+function removeColumnVector (var_obj) {
+	if (var_obj.columns == 0) {
+		return;
+	}
+
+	var_obj.columns --;
+	var_obj.value.splice(var_obj.value.length - 1, 1);
+}
+
+function alternateBooleanValue (var_obj, value_container) {
+	var_obj.value = !var_obj.value;
+	$(value_container).find('.span_value_variable').text(LocalizedStrings.getUI(var_obj.value));
+}
+
+function alternateBooleanVectorValue (var_obj, index, value_container) {
+	var_obj.value[index] = !var_obj.value[index];
+	$(value_container).find('.span_value_variable').text(LocalizedStrings.getUI(var_obj.value[index]));
+}
+
+function updateInitialValues (variable_obj) {
+	if (variable_obj.type == Types.INTEGER) {
+		if (variable_obj.dimensions == 0) {
+			variable_obj.value = 1;
+		}
+		if (variable_obj.dimensions == 1) {
+			variable_obj.value = [1, 1];
+		}
+		if (variable_obj.dimensions == 2) {
+			variable_obj.value = [[1, 1], [1, 1]];
+		}
+	}
+
+	if (variable_obj.type == Types.REAL) {
+		if (variable_obj.dimensions == 0) {
+			variable_obj.value = 1.0;
+		}
+		if (variable_obj.dimensions == 1) {
+			variable_obj.value = [1.0, 1.0];
+		}
+		if (variable_obj.dimensions == 2) {
+			variable_obj.value = [[1.0, 1.0], [1.0, 1.0]];
+		}
+	}
+
+	if (variable_obj.type == Types.TEXT) {
+		if (variable_obj.dimensions == 0) {
+			variable_obj.value = LocalizedStrings.getUI('text_start');
+		}
+		if (variable_obj.dimensions == 1) {
+			variable_obj.value = [LocalizedStrings.getUI('text_start'), LocalizedStrings.getUI('text_start')];
+		}
+		if (variable_obj.dimensions == 2) {
+			variable_obj.value = [[LocalizedStrings.getUI('text_start'), LocalizedStrings.getUI('text_start')], 
+									[LocalizedStrings.getUI('text_start'), LocalizedStrings.getUI('text_start')]];
+		}
+	}
+
+	if (variable_obj.type == Types.BOOLEAN) {
+		if (variable_obj.dimensions == 0) {
+			variable_obj.value = true;
+		}
+		if (variable_obj.dimensions == 1) {
+			variable_obj.value = [true, true];
+		}
+		if (variable_obj.dimensions == 2) {
+			variable_obj.value = [[true, true], [true, true]];
+		}
+	}
+}
+
+var opened_name_value_vector_global_ = false;
+var opened_input_value_vector_global_ = null;
+function enableVectorValueUpdate (var_obj, index, parent_node) {
+	if (opened_name_value_vector_global_) {
+		opened_input_value_vector_global_.focus();
+		return;
+	}
+	parent_node = $(parent_node);
+	opened_name_value_vector_global_ = true;
+
+	parent_node.find('.span_value_variable').text('');
+
+	var input_field;
+
+	if (var_obj.type == Types.REAL) {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ var_obj.value[index].toFixed(1) + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	} else {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ var_obj.value[index] + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	}
+
+	input_field.on('input', function() {
+	    var inputWidth = input_field.textWidth()+10;
+	    opened_input_value_vector_global_ = input_field;
+	    input_field.focus();
+
+	    var tmpStr = input_field.val();
+		input_field.val('');
+		input_field.val(tmpStr);
+
+	    input_field.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_field.focusout(function() {
+		/// update array:
+		if (input_field.val().trim()) {
+			if (var_obj.type == Types.REAL) {
+				var_obj.value[index] = parseFloat(input_field.val().trim());
+
+				parent_node.find('.span_value_variable').text(var_obj.value[index].toFixed(1));
+			} else {
+
+				if (var_obj.type == Types.INTEGER) {
+					var_obj.value[index] = parseInt(input_field.val().trim());
+				} else {
+					var_obj.value[index] = input_field.val().trim();
+				}
+
+				parent_node.find('.span_value_variable').text(var_obj.value[index]);
+
+			}
+		} else {
+			if (var_obj.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(var_obj.value[index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(var_obj.value[index]);
+			}
+		}
+		if (var_obj.type == Types.TEXT) {
+			var_obj.value[index] = input_field.val();
+			parent_node.find('.span_value_variable').text(var_obj.value[index]);
+		}
+		input_field.off();
+		input_field.remove();
+
+		/// update elements:
+		opened_name_value_vector_global_ = false;
+		opened_input_value_vector_global_ = false;
+	});
+
+	input_field.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_field.val().trim()) {
+				if (var_obj.type == Types.REAL) {
+					var_obj.value[index] = parseFloat(input_field.val().trim());
+
+					parent_node.find('.span_value_variable').text(var_obj.value[index].toFixed(1));
+				} else {
+
+					if (var_obj.type == Types.INTEGER) {
+						var_obj.value[index] = parseInt(input_field.val().trim());
+					} else {
+						var_obj.value[index] = input_field.val().trim();
+					}
+
+					parent_node.find('.span_value_variable').text(var_obj.value[index]);
+
+				}
+			} else {
+				if (var_obj.type == Types.REAL) {
+					parent_node.find('.span_value_variable').text(var_obj.value[index].toFixed(1));
+				} else {
+					parent_node.find('.span_value_variable').text(var_obj.value[index]);
+				}
+			}
+			if (var_obj.type == Types.TEXT) {
+				var_obj.value[index] = input_field.val();
+				parent_node.find('.span_value_variable').text(var_obj.value[index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_vector_global_ = false;
+			opened_input_value_vector_global_ = false;
+		}
+		if(code == 27) {
+			if (var_obj.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(var_obj.value[index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(var_obj.value[index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_vector_global_ = false;
+			opened_input_value_vector_global_ = false;
+		}
+	});
+
+	input_field.select();
+}
+
+var opened_name_value_global_var = false;
+var opened_input_value_global_ar = null;
+function enableValueUpdate (var_obj, parent_node) {
+	if (opened_name_value_global_var) {
+		opened_input_value_global_ar.focus();
+		return;
+	}
+	parent_node = $(parent_node);
+	opened_name_value_global_var = true;
+
+	var input_field;
+
+	parent_node.find('.span_value_variable').text('');
+	if (var_obj.type == Types.REAL) {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ var_obj.value.toFixed(1) + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	} else {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ var_obj.value + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	}
+
+	input_field.on('input', function() {
+	    var inputWidth = input_field.textWidth()+10;
+	    opened_input_value_global_ar = input_field;
+	    input_field.focus();
+
+	    var tmpStr = input_field.val();
+		input_field.val('');
+		input_field.val(tmpStr);
+
+	    input_field.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_field.focusout(function() {
+		/// update array:
+		if (input_field.val().trim()) {
+			if (var_obj.type == Types.REAL) {
+				var_obj.value = parseFloat(input_field.val().trim());
+				parent_node.find('.span_value_variable').text(var_obj.value.toFixed(1));
+			} else{
+				if (var_obj.type == Types.INTEGER) {
+					var_obj.value = parseInt(input_field.val().trim());
+				} else {
+					var_obj.value = input_field.val().trim();
+				}
+				parent_node.find('.span_value_variable').text(var_obj.value);
+				
+			}
+		} else {
+			if (var_obj.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(var_obj.value.toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(var_obj.value);
+			}
+		}
+		if (var_obj.type == Types.TEXT) {
+			var_obj.value = input_field.val();
+			parent_node.find('.span_value_variable').text(var_obj.value);
+		}
+		input_field.off();
+		input_field.remove();
+
+		/// update elements:
+		opened_name_value_global_var = false;
+		opened_input_value_global_ar = false;
+
+	});
+
+	input_field.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_field.val().trim()) {
+				if (var_obj.type == Types.REAL) {
+					var_obj.value = parseFloat(input_field.val().trim());
+					parent_node.find('.span_value_variable').text(var_obj.value.toFixed(1));
+				} else{
+					if (var_obj.type == Types.INTEGER) {
+						var_obj.value = parseInt(input_field.val().trim());
+					} else {
+						var_obj.value = input_field.val().trim();
+					}
+					parent_node.find('.span_value_variable').text(var_obj.value);
+				}
+			} else {
+				if (var_obj.type == Types.REAL) {
+					parent_node.find('.span_value_variable').text(var_obj.value.toFixed(1));
+				} else {
+					parent_node.find('.span_value_variable').text(var_obj.value);
+				}
+			}
+			if (var_obj.type == Types.TEXT) {
+				var_obj.value = input_field.val();
+				parent_node.find('.span_value_variable').text(var_obj.value);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_global_var = false;
+			opened_input_value_global_ar = false;
+
+		}
+		if(code == 27) {
+			if (var_obj.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(var_obj.value.toFixed(1));
+			} else{
+				parent_node.find('.span_value_variable').text(var_obj.value);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_global_var = false;
+			opened_input_value_global_ar = false;
+		}
+	});
+
+	input_field.select();
+}
+
+var opened_name_global = false;
+var opened_input_global = null;
+function enableNameUpdate (variable_obj, variable_container) {
+
+	if (opened_name_global) {
+		opened_input_global.focus();
+		return;
+	}
+	opened_name_global = true;
+
+	variable_container.find('.span_name_variable').text('');
+
+	var input_name;
+
+	input_name = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"+variable_obj.name+"' />" );
+	input_name.insertBefore(variable_container.find('.span_name_variable'));
+
+	input_name.on('input', function() {
+	    var inputWidth = input_name.textWidth()+10;
+	    opened_input_global = input_name;
+	    input_name.focus();
+
+	    var tmpStr = input_name.val();
+		input_name.val('');
+		input_name.val(tmpStr);
+
+	    input_name.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_name.focusout(function() {
+		/// update array:
+		if (input_name.val().trim().length > 0) {
+			updateName(variable_obj, input_name.val().trim());
+			variable_container.find('.span_name_variable').text(variable_obj.name);
+		} else {
+			variable_container.find('.span_name_variable').text(variable_obj.name);
+		}
+		input_name.off();
+		input_name.remove();
+
+		/// update elements:
+		opened_name_global = false;
+		opened_input_global = false;
+	});
+
+	input_name.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_name.val().trim().length > 0) {
+				updateName(variable_obj, input_name.val().trim());
+				variable_container.find('.span_name_variable').text(variable_obj.name);
+			} else {
+				variable_container.find('.span_name_variable').text(variable_obj.name);
+			}
+			input_name.off();
+			input_name.remove();
+
+			/// update elements:
+			opened_name_global = false;
+			opened_input_global = false;
+		}
+		if(code == 27) {
+
+			variable_container.find('.span_name_variable').text(variable_obj.name);
+			input_name.off();
+			input_name.remove();
+
+			/// update elements:
+			opened_name_global = false;
+			opened_input_global = false;
+		}
+	});
+
+	input_name.select();
+	
+}
+
+
+var opened_name_value_matrix_global_v = false;
+var opened_input_value_matrix_global_v = null;
+function enableMatrixValueUpdate (var_obj, row, index, parent_node) {
+	if (opened_name_value_matrix_global_v) {
+		opened_input_value_matrix_global_v.focus();
+		return;
+	}
+	parent_node = $(parent_node);
+	opened_name_value_matrix_global_v = true;
+
+	parent_node.find('.span_value_variable').text('');
+
+	var input_field;
+
+	if (var_obj.type == Types.REAL) {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ var_obj.value[row][index].toFixed(1) + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	} else {
+		input_field = $( "<input type='text' class='width-dynamic input_name_function' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' value='"
+			+ var_obj.value[row][index] + "' />" );
+		input_field.insertBefore(parent_node.find('.span_value_variable'));
+	}
+
+	input_field.on('input', function() {
+	    var inputWidth = input_field.textWidth()+10;
+	    opened_input_value_matrix_global_v = input_field;
+	    input_field.focus();
+
+	    var tmpStr = input_field.val();
+		input_field.val('');
+		input_field.val(tmpStr);
+
+	    input_field.css({
+	        width: inputWidth
+	    })
+	}).trigger('input');
+
+	input_field.focusout(function() {
+		/// update array:
+		if (input_field.val().trim()) {
+			if (var_obj.type == Types.REAL) {
+				var_obj.value[row][index] = parseFloat(input_field.val().trim());
+
+				parent_node.find('.span_value_variable').text(var_obj.value[row][index].toFixed(1));
+			} else {
+				if (var_obj.type == Types.INTEGER) {
+					var_obj.value[row][index] = parseInt(input_field.val().trim());
+				} else {
+					var_obj.value[row][index] = input_field.val().trim();
+				}
+				parent_node.find('.span_value_variable').text(var_obj.value[row][index]);
+			}
+		} else {
+			if (var_obj.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(var_obj.value[row][index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(var_obj.value[row][index]);
+			}
+		}
+		if (var_obj.type == Types.TEXT) {
+			var_obj.value[row][index] = input_field.val();
+			parent_node.find('.span_value_variable').text(var_obj.value[row][index]);
+		}
+		input_field.off();
+		input_field.remove();
+
+		/// update elements:
+		opened_name_value_matrix_global_v = false;
+		opened_input_value_matrix_global_v = false;
+	});
+
+	input_field.on('keydown', function(e) {
+		var code = e.keyCode || e.which;
+		if(code == 13) {
+			if (input_field.val().trim()) {
+				if (var_obj.type == Types.REAL) {
+					var_obj.value[row][index] = parseFloat(input_field.val().trim());
+
+					parent_node.find('.span_value_variable').text(var_obj.value[row][index].toFixed(1));
+				} else {
+					if (var_obj.type == Types.INTEGER) {
+						var_obj.value[row][index] = parseInt(input_field.val().trim());
+					} else {
+						var_obj.value[row][index] = input_field.val().trim();
+					}
+					parent_node.find('.span_value_variable').text(var_obj.value[row][index]);
+				}
+			} else {
+				if (var_obj.type == Types.REAL) {
+					parent_node.find('.span_value_variable').text(var_obj.value[row][index].toFixed(1));
+				} else {
+					parent_node.find('.span_value_variable').text(var_obj.value[row][index]);
+				}
+			}
+			if (var_obj.type == Types.TEXT) {
+				var_obj.value[row][index] = input_field.val();
+				parent_node.find('.span_value_variable').text(var_obj.value[row][index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_matrix_global_v = false;
+			opened_input_value_matrix_global_v = false;
+		}
+		if(code == 27) {
+			if (var_obj.type == Types.REAL) {
+				parent_node.find('.span_value_variable').text(var_obj.value[row][index].toFixed(1));
+			} else {
+				parent_node.find('.span_value_variable').text(var_obj.value[row][index]);
+			}
+			input_field.off();
+			input_field.remove();
+
+			/// update elements:
+			opened_name_value_matrix_global_v = false;
+			opened_input_value_matrix_global_v = false;
+		}
+	});
+
+	input_field.select();
+}

+ 76 - 0
js/visualUI/visual.js

@@ -0,0 +1,76 @@
+import { Types } from './../ast/types';
+
+const tiposComandos = Object.freeze({comment:"comment", reader:"reader", writer:"writer"});
+
+export class Variavel {
+
+  constructor (tipo, nome, valor, dimensoes = 0, eh_constante = false, linhas = 0, colunas = 0) {
+    this.tipo = tipo;
+    this.nome = nome;
+    this.valor = valor;
+    this.dimensoes = dimensoes;
+    this.eh_constante = eh_constante;
+    this.linhas = linhas;
+    this.colunas = colunas;
+  }
+}
+
+export class Funcao {
+
+  constructor (nome, tipo_retorno = Types.VOID, dimensoes_retorno = 0, lista_parametros = null, eh_principal = false, esta_oculta = false, variaveis = [], comentario_funcao = null) {
+    this.nome = nome;
+    this.tipo_retorno = tipo_retorno;
+    this.dimensoes_retorno = dimensoes_retorno;
+    this.lista_parametros = lista_parametros;
+    this.eh_principal = eh_principal;
+    this.esta_oculta = esta_oculta;
+    this.variaveis = variaveis;
+    this.comentario_funcao = comentario_funcao;
+    this.comandos = [];
+  }
+}
+
+export class Comentario {
+  
+  constructor (texto_comentario) {
+    this.tipo = tiposComandos.comment;
+    this.texto_comentario = texto_comentario;
+  }
+}
+
+export class Comando {
+
+  constructor (tipo) {
+    this.tipo = tipo;
+  }
+} 
+
+export class Expressao {
+
+  constructor (conteudo) {
+    this.conteudo = conteudo;
+  }
+}
+
+
+export class Programa {
+  constructor () {
+    this.funcoes = [];
+    this.globais = [];
+  };
+
+  adicionarFuncao (funcao) {
+    this.funcoes.push(funcao);
+  }
+
+  adicionarVariavel(funcao, variavel) {
+    if (this.funcoes[funcao].variaveis === null) {
+      this.funcoes[funcao].variaveis = [];
+    }
+    this.funcoes[funcao].variaveis.push(variavel);
+  }
+
+  adicionarGlobal (variavel) {
+    this.globais.push(variavel);
+  }
+}

+ 0 - 126
main.html

@@ -1,126 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <title></title>
-    <link rel="stylesheet" type="text/css" href="js/semantic/semantic.min.css">
-    <link rel="stylesheet" type="text/css" href="css/ivprog-visual-1.0.css">
-    <script src="js/jquery-3.3.1.min.js"></script>
-
-    <script src="js/iassign-integration-functions.js"></script>
-
-    <script src="i18n/i18n-engine.js"></script>
-
-    <script src="js/semantic/semantic.min.js"></script>
-    <script src="js/semantic/semantic-buttons.js"></script>
-
-    <script src="js/ivprog-visual-1.0.js"></script>
-    <script src="js/ivprog-visual-functions-1.0.js"></script>
-
-    <script src="js/jquery-ui.js"></script>
-    <script src="js/Sortable.js"></script>
-  </head>
-  <body>
-   
-    <div class="ui one column doubling stackable grid container">
-      <div class="column">
-        <div class="ui container main_title">
-          <h2>iVProg</h2>
-          <span>interactive coding</span>
-        </div>
-
-        
-
-        <div class="ui container content_margin">
-          <div class="content_sub_margin">
-              <div class="blue ui ivprog_format buttons">
-                <button class="ui button active">Visual</button>
-                <button class="ui button">Textual</button>
-                <button class="ui button">XML</button>
-              </div>
-
-              <a class="ivprog_format_info">
-                <i class="circular inverted some-wrapping-div teal info icon small label ivprog_format_info popup"></i>
-              </a>
-              <div class="ui custom popup">
-                Choice how you prefer to develop. If disabled, teacher doesn't allow this change. <a href="#">See documentation about it.</a>
-              </div>
-            </div>
-          </div>
-
-
-      </div>
-      
-    </div>
-
-    
-
-    
-
-    <div class="ui raised container segment div_to_body">
-
-      <div class="ui icon menu center aligned container" style="width: 438px; margin-top: -10px;">
-        <a class="item">
-          <i class="file icon"></i>
-        </a>
-        <a class="item">
-          <i class="save icon"></i>
-        </a>
-        <a class="item">
-          <i class="upload icon"></i>
-        </a>
-        <a class="item">
-          <i class="download icon"></i>
-        </a>
-        <a class="item undo_button disabled">
-          <i class="undo icon"></i>
-        </a>
-        <a class="item">
-          <i class="redo icon"></i>
-        </a>
-        <a class="item">
-          <i class="play icon"></i>
-        </a>
-        <a class="item">
-          <i class="stop icon"></i>
-        </a>
-        <a class="item">
-          <i class="help icon"></i>
-        </a>
-      </div>
-
-      <div class="ui one column container segment ivprog_visual_panel loading">
-        <div class="program_signature"><span class="program_signature_text">programa</span> { </div>
-
-        <div class="global_var">
-          <div class="ui icon button" onclick="addGlobalVar()"><i class="icon superscript"></i></div>
-          <div class="list_globals"></div>
-        </div>
-
-        <div class="all_functions list-group" id="listWithHandle">
-
-        </div>
-
-
-        <div class="ui teal small labeled icon button add_function_button">
-          <data class="i18n" value="Function">Function</data>
-          <i class="add icon"></i>
-        </div>
-        <div class="program_final">}</div>
-
-      </div>
-      
-    </div>
-
-    <i class="icon trash alternate outline huge" onmouseover="console.log('oi');" ></i>
-
-
-
-
-
-
-
-
-
-
-  </body>
-</html>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1124 - 217
package-lock.json


+ 4 - 2
package.json

@@ -39,15 +39,17 @@
     "karma-mocha-reporter": "^2.2.5",
     "karma-webpack": "^3.0.0",
     "puppeteer-core": "^1.7.0",
+    "webpack": "^4.*",
     "ts-loader": "^5.2.2",
     "typescript": "^3.1.3",
-    "webpack": "^4.16.5",
     "webpack-cli": "^3.1.0"
   },
   "dependencies": {
     "antlr4": "^4.7.1",
     "decimal.js": "^10.0.1",
     "jquery": "^3.3.1",
-    "line-i18n": "git+https://git.lcalion.com/LInE/line-i18n.git"
+    "line-i18n": "git+https://git.lcalion.com/LInE/line-i18n.git",
+    "melanke-watchjs": "^1.5.0",
+    "server": "^1.0.18"
   }
 }

+ 78 - 0
runner.html

@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+  <link rel="stylesheet" type="text/css" href="css/ivprog-term.css">
+
+  <link rel="stylesheet" type="text/css" href="js/semantic/semantic.min.css">
+  <style>
+    .ivprog-io-output {
+      border: 1px solid gainsboro;
+      width: 80%;
+      height: 360px;
+      overflow-y: scroll;
+      background-color: black;
+      color: white;
+    }
+
+    .ivprog-io-input {
+      width: 80%;
+      margin-top: 10px;
+      border: 1.5px solid green;
+      height: 3rem;
+      color: black;
+      font-size: 12pt;
+    }
+  </style>
+  <title></title>
+</head>
+<body>
+    <div style="padding-top: 50px;content: ''"></div>
+  <div class="ui container grid">
+    
+    <div class="four wide column">
+      <div class="row">
+        <textarea class="ui form control" name="input" id="input" cols="100" rows="30">
+            programa {
+
+              const real C = 5.5
+             
+              funcao inicio() {
+
+               inteiro a = 8
+               se (a * C > 80) {
+                a = 0
+               } senao {
+                 a = -1
+               }
+              }
+             }
+        </textarea>
+      </div>
+      <div class="row">
+          <button class="ui button" id="btn">Run</button>
+      </div>
+    </div>
+    <div class="six wide column">
+      <div id="console">
+      </div>
+    </div>
+    <div class="six wide column">
+        <div style="overflow-y: scroll; height: 70%;">
+            <pre id="json-renderer" class="ui right floated"></pre>
+        </div>
+    </div>
+  </div>
+  
+  
+</body>
+
+<script src="js/jquery-3.3.1.min.js"></script>
+
+<script type="text/javascript" src="js/jquery.json-editor.min.js"></script>
+<script type="text/javascript" src="build/ivprog.bundle.js"></script>
+
+<script>
+  ivprogCore.runner();
+</script>
+</html>

+ 4 - 3
webpack.config.js

@@ -3,11 +3,12 @@ var webpack = require('webpack');
 module.exports = {
     entry: './js/main.js',
     mode: 'development',
-    watch: false,
+    watch: true,
     output: {
         path: path.resolve(__dirname, 'build'),
-        //chunkFilename: '[name].bundle.js',
-        filename: 'ivprog.bundle.js'
+        filename: 'ivprog.bundle.js',
+        library: 'ivprogCore',
+        libraryTarget: 'umd'
     },
     node: {
         fs: 'empty',