(function(exports) {
	let response_lenght = 5
	let queryTimeout = 1000

	exports.add_template = function(template)
	{
		data_type_template.templates.push(template)
	}
	let data_type_template = {"templates": [
		{"index": "1011_1","template": "restore_params"},
		{"index": "1027_1","template": "combobox", "commands": templates_commands.head_types()},
		{"index": "1027_2","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1027_3","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1027_4","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1027_5","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1027_6","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1027_7","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1027_8","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1027_9","template": "module_types", "commands": templates_commands.module_types()},
		{"index": "1018_2","template": "ip_addr"},
		{"index": "1018_3","template": "ip_addr"},
		{"index": "2000_2","template": "ip_addr"},
		{"index": "2000_3","template": "ip_addr"},
		{"index": "2000_6","template": "ip_addr"},
		{"index": "2001_1","template": "change_value", "commands": templates_commands.restart_reason()},
		{"index": "2001_12","template": "bit_value", "commands": templates_commands.hw_error_flags()},
		{"index": "2001_13","template": "bit_value", "commands": templates_commands.sw_error_flags()},
		{"index": "2001_15","template": "bit_value", "commands": templates_commands.hw_error_flags_2()},
		{"index": "2001_16","template": "bit_value", "commands": templates_commands.sw_error_flags()},
		{"index": "2002_1","template": "combobox", "commands": templates_commands.access_commands_expert_MCU_T_ETS()},
		{"index": "2001_9","template": "change_value", "commands": templates_commands.access_values()},
		{"index": "2002_2","template": "password"},
		{"index": "2081_1","template": "datetime"},
		{"index": "2081_12","template": "datetime_with_nanosec_simple"},
		{"index": "2101_5", "template": "change_value", "commands": templates_commands.CAN_port_status()},
		{"index": "2105_5", "template": "change_value", "commands": templates_commands.CAN_port_status()},
		{"index": "2109_5", "template": "change_value", "commands": templates_commands.CAN_port_status()},
		{"index": "2211_2", "template": "change_value", "commands": templates_commands.DHCP_client_status()},
		{"index": "2211_3","template": "ip_addr"},
		{"index": "2211_4","template": "ip_addr"},
		{"index": "2213_2","template": "ip_addr"},
		{"index": "2213_3","template": "ip_addr"},
		{"index": "2213_4","template": "ip_addr"},
		{"index": "2213_5","template": "ip_addr"},
		{"index": "2213_6","template": "ip_addr"},
		{"index": "2213_1","template": "combobox", "commands": templates_commands.on_off_values()},
		{"index": "221B_2","template": "ip_addr need_restart"},
		{"index": "221B_3","template": "ip_addr"},
		{"index": "221B_4","template": "ip_addr"},
		{"index": "221B_5","template": "ip_addr"},
		{"index": "221B_6","template": "ip_addr"},
		{"index": "2221_2","template": "change_value", "commands": templates_commands.rstp_port_status()},
		{"index": "2221_3","template": "change_value", "commands": templates_commands.rstp_port_status()},
		{"index": "2223_1","template": "boolean_type"},
		{"index": "2223_10","template": "combobox", "commands": templates_commands.true_false_auto()},
		{"index": "2223_11","template": "combobox", "commands": templates_commands.off_on_auto()},
		{"index": "2223_14","template": "combobox", "commands": templates_commands.true_false_auto()},
		{"index": "2223_15","template": "combobox", "commands": templates_commands.off_on_auto()},
		{"index": "2301_1","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2301_2","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2301_3","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2301_4","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2301_5","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2301_6","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2301_7","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2301_8","template": "change_value", "commands": templates_commands.canopen_node_status()},
		{"index": "2343_1","template": "boolean_type"},
		{"index": "3000_5","template": "change_value", "commands": templates_commands.report_flag()},
		{"index": "3001_1","template": "boolean_type"},
		{"index": "3001_2","template": "combobox", "commands": templates_commands.report_period()},
		{"index": "3001_3","template": "date"},
		{"index": "4C03_1","template": "string_command"},
		{"index": "5000_2","template": "datetime_simple"},
		{"index": "5000_3","template": "ip_addr"},
		{"index": "5001_1","template": "change_value", "commands": templates_commands.user_app_status()},
		{"index": "5002_1","template": "combobox", "commands": templates_commands.appsw_cmd()},
	]}

	exports.get_multiply_templates = function() { return multiply_templates }
	exports.add_multiply_templates = function(template)
	{
		multiply_templates.push(template)
	}

	let multiply_templates = [{
		"type": "subindex multiply",
		"count": 32, 
		"templates":[
			{"index": "23A4", "template": "mbtcp_client"},
			{"index": "23A1", "template":  "mbtcp_client_status", "connection_status": templates_commands.connection_status()},
	]},{
		"type": "subindex multiply",
		"count": 64, 
		"templates":[
			{"index": "1003", "template": "error_field"},
	]},{
		"type": "subindex multiply",
		"count": 127, 
		"templates":[
			{"index": "1016","template": "consumer_heartbeat"}
	]},{
		"type": "index multiply", 
		"count": 512, 
		"multiply_coefficient": 1,
		"templates":[
			{"index": "1400_7", "template": "bit_value", "commands": templates_commands.rpdo_status()}
	]},{
		"type": "index multiply", 
		"count": 12, 
		"multiply_coefficient": 0x100,
		"templates":[
			{"index": "4003_1", "template": "string_command"}
	]}]

// RPDO Mapping
	for (var index = 0x1600; index <= 0x16FF; index++) {
		for (var subi = 1; subi < 12; subi++) {
			data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_${subi}`,"template": "pdo_mapping"})
		}
	}
// TPDO Mapping
	for (var index = 0x1A00; index <= 0x1AFF; index++) {
		for (var subi = 1; subi < 12; subi++) {
			data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_${subi}`,"template": "pdo_mapping"})
		}
	}
// RPDO COB_ID
	for (var index = 0x1400; index <= 0x15FF; index++) {
		data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_1`,"template": "pdo_cob_id",
		"enable": templates_commands.pdo_cob_id_enable(),
		"messages": templates_commands.pdo_cob_id_messages()})
	}
// TPDO COB_ID
	for (var index = 0x1800; index <= 0x19FF; index++) {
		data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_1`,"template": "pdo_cob_id",
		"enable": templates_commands.pdo_cob_id_enable(),
		"messages": templates_commands.pdo_cob_id_messages()})
	}
// Communication (CAN, Serial and Ethernet)
	for (var interface_number = 0; interface_number < 3; interface_number++){
		var eds_index = 0x2143 + interface_number*4
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_1`,"template": "boolean_type"})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_2`,"template": "combobox", "commands": templates_commands.baudrate()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_4`,"template": "combobox", "commands": templates_commands.parity()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_5`,"template": "combobox", "commands": templates_commands.stopbits()})
		var eds_index = 0x2103 + interface_number*4
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_1`,"template": "boolean_type"})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_2`,"template": "combobox", "commands": templates_commands.CAN_speed()})
		var eds_index = 0x2333 + interface_number*4
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_1`,"template": "boolean_type"})
		var eds_index = 0x2383 + interface_number*4
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_1`,"template": "boolean_type"})
		var eds_index = 0x2323 + interface_number*4
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_1`,"template": "boolean_type"})
	}
	for (var interface_number = 0; interface_number < 3; interface_number++) {
		for (var subi = 1; subi <= 64; subi++) {
		    var index = 0x2311 + interface_number*4
    		data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_${subi}`,"template": "change_value", "commands": templates_commands.canopen_NMT_status()})
        }
    }
// Modules (boards)
	for (var board_number = 1; board_number < 9; board_number++) {
		//var eds_index = 0x3F03 + board_number*0x100
		//var template = {"index": `${eds_index.toString(16).toUpperCase()}_1`,"template": "restore_params"}
		//data_type_template.templates.push(template)
		for (var eds_subindex = 1; eds_subindex < 9; eds_subindex++) {
			var eds_index = 0x3F39 + board_number*0x100
			var template = {"index": `${eds_index.toString(16).toUpperCase()}_${eds_subindex}`,"template": "combobox", "commands": templates_commands.sensor_type_all()}
			data_type_template.templates.push(template)
		}
	}
// PM Modules
	for (var board_number = 0; board_number < 8; board_number++) {
		var eds_index = 0x4060 + board_number*0x100
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_1`,"template": "combobox", "commands": templates_commands.connection_scheme()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_2`,"template": "combobox", "commands": templates_commands.current_range()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_3`,"template": "combobox", "commands": templates_commands.current_diff_range()})
    }
// Energy Profiles
	data_type_template.templates.push({"index": "3000_2","template": "datetime_simple"})
	data_type_template.templates.push({"index": "3000_3","template": "datetime_simple"})
	data_type_template.templates.push({"index": "3000_4","template": "datetime_simple"})
//	data_type_template.templates.push({"index": "3001_3","template": "date"})
	for (var board_number = 0; board_number < 8; board_number++) {
      	for (var pm_profile = 0; pm_profile < (160 + 1); pm_profile++) {
            var index = 0x3002 + (board_number * 0x100) + pm_profile
            data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_1`,"template": "datetime_simple"})
		    data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_2`,"template": "datetime_simple"})
		    data_type_template.templates.push({"index": `${index.toString(16).toUpperCase()}_3`,"template": "hex"})
        }
    }
// Modbus Client (Master)
    const serial_port_number = 3
    const serial_port_requests = 128
    const ports_req_offset = 0x300
    const tcp_port_requests = 256
// RTU Client
	for (var serial_port_i = 0; serial_port_i < serial_port_number; serial_port_i++){
        var port_index = 0x5100 + (ports_req_offset * serial_port_i)
	    for (var request_per_port = 0; request_per_port < serial_port_requests; request_per_port++){
		    var eds_index = port_index + request_per_port*2
		    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_3`, "template": "change_value",  "commands": templates_commands.request_status()})
		    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_11`, "template": "combobox",     "commands": templates_commands.mb_functions()})
		    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_14`, "template": "combobox",     "commands": templates_commands.req_trigger_type()})
		    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_16`, "template": "change_value", "commands": templates_commands.byte_and_word_order()})
			data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_21`, "template": "datetime_with_nanosec_simple"})
	    	data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_22`, "template": "datetime_with_nanosec_simple"})
            eds_index += 1
		    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_2`, "template": "change_value", "commands": templates_commands.data_status()})
        }
        //TODO DRY!!!
        // 383's' Request
	    eds_index = port_index + 0x2FE
	    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_3`, "template": "change_value",  "commands": templates_commands.request_status()})
	    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_11`, "template": "combobox",     "commands": templates_commands.mb_functions()})
	    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_14`, "template": "combobox",     "commands": templates_commands.req_trigger_type()})
	    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_16`, "template": "change_value", "commands": templates_commands.byte_and_word_order()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_21`, "template": "datetime_with_nanosec_simple"})
	    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_22`, "template": "datetime_with_nanosec_simple"})
        eds_index += 1
	    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_2`, "template": "change_value", "commands": templates_commands.data_status()})
    }
// TCP Client
	for (var request_per_port = 0; request_per_port < tcp_port_requests; request_per_port++){
		var eds_index = 0x5A00 + request_per_port*2
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_3`, "template": "change_value",  "commands": templates_commands.request_status()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_11`, "template": "combobox",     "commands": templates_commands.mb_functions()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_14`, "template": "combobox",     "commands": templates_commands.req_trigger_type()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_16`, "template": "change_value", "commands": templates_commands.byte_and_word_order()})
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_21`, "template": "datetime_with_nanosec_simple"})
	    data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_22`, "template": "datetime_with_nanosec_simple"})

        eds_index += 1
		data_type_template.templates.push({"index": `${eds_index.toString(16).toUpperCase()}_2`, "template": "change_value", "commands": templates_commands.data_status()})
    }

	exports.response_lenght = function() { return response_lenght;}
	exports.queryTimeout = function() { return queryTimeout;}
	exports.data_type_template = function() { return data_type_template;}
	//exports.default_checkbox_values = function() { return templates_commands.default_checkbox_values();}
})(this.configuration_expert = {});
