//remove the named variables from the environment and free memory.
clear;


//include files with functions which are used
exec XMLfunctions.sci;
exec TXTfunctions.sci;
exec DialogsFunctions.sci;
exec XMLTable.sci;
exec XMLMath.sci;
exec XMLTest.sci;
exec XMLVisualization.sci;
exec XMLSimulation.sci;
exec JSBSimManager.sci;
exec ControllerDesignMethods.sci;
exec peak_detect.sci;



//definition of global objects
global xmlAutopilotNew;
xmlAutopilotNew = "<?xml version=""1.0""?><!-- JSBSim Autopilot file was generated by Control System Designer for JSBSim (Tomas Vogeltanz ©2016-) --><autopilot name=""Autopilot""></autopilot>";
global xmlAutopilot;
xmlAutopilot = xmlReadStr(xmlAutopilotNew);
global xmlAutopilotFilePath;
xmlAutopilotFilePath = emptystr();
global xmlAutopilotFileName;
xmlAutopilotFileName = emptystr();
//xmlAutopilotFlightGearNew = "<?xml version=""1.0""?><!-- FlightGear autopilot file was generated by Control System Designer for JSBSim (Tomas Vogeltanz ©2016-) --><PropertyList></PropertyList>";
//xmlAutopilotFlightGear = xmlReadStr(xmlAutopilotFlightGearNew);

global xmlResetNew;
xmlResetNew = "<?xml version=""1.0""?><!-- JSBSim Reset file was generated by Control System Designer for JSBSim (Tomas Vogeltanz ©2016-) --><initialize name=""reset-v1""></initialize>";
xmlReset = xmlReadStr(xmlResetNew);
global xmlResetFilePath;
xmlResetFilePath = emptystr();
global xmlResetFileName;
xmlResetFileName = emptystr();

global xmlAircraftFilePath;
xmlAircraftFilePath = emptystr();
global xmlAircratFileName;
xmlAircratFileName = emptystr();

global xmlSimulationNew;
xmlSimulationNew = "<?xml version=""1.0""?><?xml-stylesheet type=""text/xsl"" href=""http://jsbsim.sf.net/JSBSimScript.xsl""?><!-- JSBSim Simulation file was generated by Control System Designer for JSBSim (Tomas Vogeltanz ©2016-) --><runscript name=""""></runscript>";
global xmlSimulation;
xmlSimulation = emptystr();
global xmlSimulationFilePath;
xmlSimulationFilePath = emptystr();
global xmlSimulationFileName;
xmlSimulationFileName = emptystr();

global xmlSimulationStartNew;
xmlSimulationStartNew = "<?xml version=""1.0""?><!-- Simulation Start file was generated by Control System Designer for JSBSim (Tomas Vogeltanz ©2016-) --><simulation_start></simulation_start>";
global xmlSimulationStart;
xmlSimulationStart = emptystr();
global xmlSimulationStartFilePath;
xmlSimulationStartFilePath = emptystr();
global xmlSimulationStartFileName;
xmlSimulationStartFileName = emptystr();

global xmlControllerAdjustmentDefinitionNew;
xmlControllerAdjustmentDefinitionNew = "<?xml version=""1.0""?><!-- Control Design Start file was generated by Control System Designer for JSBSim (Tomas Vogeltanz ©2016-) --><control_design_start></control_design_start>";
global xmlControllerAdjustmentDefinition;
xmlControllerAdjustmentDefinition = emptystr();
global xmlControllerAdjustmentDefinitionFilePath;
xmlControllerAdjustmentDefinitionFilePath = emptystr();
global xmlControllerAdjustmentDefinitionFileName;
xmlControllerAdjustmentDefinitionFileName = emptystr();


//read xml file with channel template definition
global xmlChannel;
xmlChannel = xmlRead("templates" + filesep() + "channel.xml");


//selected channel (0 (none) is default)
global xmlChannelSelected;
xmlChannelSelected = 0;

global xmlChannelSelectedVisualComponentsList;
xmlChannelSelectedVisualComponentsList = list();


//components available in <global> section
componentsGlobalStrings = [gettext("property")];    //gettext("documentation") 

//components available in channel sections
componentsChannelStrings = [gettext("fcs_function") gettext("switch") gettext("summer") gettext("pid") gettext("pure_gain") gettext("sensor") gettext("lag_filter") gettext("lead_lag_filter") gettext("washout_filter") gettext("second_order_filter") gettext("deadband") gettext("aerosurface_scale") gettext("kinematic") gettext("actuator") gettext("integrator") gettext("accelerometer") gettext("scheduled_gain")];    //gettext("documentation") 


//read file whit internal and custom properties which are available
global propertiesAvailable;
propertiesAvailable = ReadInternalAndCustomProperties();





// This GUI file was generated by guibuilder version 3.0
//////////
global fig_size_x;
fig_size_x = 1062;//1600;
global fig_size_y;
fig_size_y = 600;//900;
f=figure( 'figure_position',[150,100], 'figure_size',[fig_size_x, fig_size_y], 'menubar','none', 'auto_resize','on', 'background',[33], 'figure_name','Control System Designer for JSBSim' );
//////////
//because of "menubar", "none" property, the menus don't have to be deleted; i.e. there are no menus
//delmenu(f.figure_id,gettext('File'))
//delmenu(f.figure_id,gettext('?'))
//delmenu(f.figure_id,gettext('Tools'))
//delmenu(f.figure_id,gettext('Edit'))
////add main menu items
//DiagramMenu = uimenu(f, 'label', 'Diagram',  'tag', 'Diagram');
////create items on the menu bars - create sub menus
//SaveDiagramAsSubMenu = uimenu(DiagramMenu,  'label', 'Save As',  'tag', 'SaveDiagramAs',  'callback', "SaveDiagramAsSubMenu_callback(handles)");
//EditDiagramPropertiesSubMenu = uimenu(DiagramMenu,  'label', 'Edit Properties',  'tag', 'EditDiagramProperties',  'callback', "EditDiagramPropertiesSubMenu_callback(handles)");
//add main menu items
CSVprocessingMenuMain = uimenu(f, 'label', 'CSV Processing',  'tag', 'CSVprocessingMenuMain');
ControlComponentAdjustmentMenuMain = uimenu(f, 'label', 'Control Component Adjustment',  'tag', 'ControlComponentAdjustmentMenuMain');
HelpMenuMain = uimenu(f, 'label', 'Help',  'tag', 'HelpMenuMain');
//ControlComponentAnalysisMenuMain = uimenu(f, 'label', 'Control Component Analysis',  'tag', 'ControlComponentAnalysisMenuMain');
//create items on the menu bars
//create sub menus
OpenJSBSimOutputCSVMenu = uimenu(CSVprocessingMenuMain,  'label', 'Open CSV JSBSim output',  'tag', 'OpenJSBSimOutputCSVMenu',  'callback', "OpenJSBSimOutputCSV_callback(handles)");
SetControlComponentUsingZieglerNicholsCriticalParametersTablesMenu = uimenu(ControlComponentAdjustmentMenuMain,  'label', 'Set rule of Ziegler-Nichols method with critical parameters',  'tag', 'SetControlComponentUsingZieglerNicholsCriticalParametersTablesMenu',  'callback', "SetControlComponentUsingZieglerNicholsCriticalParametersTables_callback(handles)");
GetAllControlComponentAdjustmentsUsingZieglerNicholsCriticalParametersTablesMenu = uimenu(ControlComponentAdjustmentMenuMain,  'label', 'Get all adjustments using Ziegler-Nichols method with critical parameters',  'tag', 'GetAllControlComponentAdjustmentsUsingZieglerNicholsCriticalParametersTablesMenu',  'callback', "GetAllControlComponentAdjustmentsUsingZieglerNicholsCriticalParametersTables_callback(handles)");
//AnalyzeStabilityOfControlComponentMenu = uimenu(ControlComponentAnalysisMenuMain,  'label', 'Analyze Stability of Control Component',  'tag', 'AnalyzeStabilityOfControlComponentMenu',  'callback', "AnalyzeStabilityOfControlComponent_callback(handles)");
AboutApplicationMenu = uimenu(HelpMenuMain,  'label', 'About Application',  'tag', 'AboutApplicationMenu',  'callback', "AboutApplication_callback(handles)");


toolbar(f.figure_id,'off')
initial_channels = strcat([gettext("<global>")], "|");
initial_components = [];
initial_componentsUsed = [];
handles.dummy = 0;

handles.Channels=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',[1],'Max',[1],'Min',[0],'Position',[0.050,0.50,0.23,0.40],'Relief','default','SliderStep',[0.01,0.1],'String',initial_channels,'Style','listbox','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','Channels','Callback','Channels_callback(handles)')
handles.Components=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',[1],'Max',[1],'Min',[0],'Position',[0.288,0.50,0.13,0.40],'Relief','default','SliderStep',[0.01,0.1],'String',initial_components,'Style','listbox','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','Components','Callback','Components_callback(handles)')
handles.ComponentsUsed=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',[1],'Max',[1],'Min',[0],'Position',[0.448,0.50,0.30,0.40],'Relief','default','SliderStep',[0.01,0.1],'String',initial_componentsUsed,'Style','listbox','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','ComponentsUsed','Callback','ComponentsUsed_callback(handles)')

handles.AddChannel=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.050,0.44,0.0616854,0.0583039],'Relief','default','SliderStep',[0.01,0.1],'String','Add','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','AddChannel','Callback','AddChannel_callback(handles)')
handles.EditChannel=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.12,0.44,0.0616854,0.0583039],'Relief','default','SliderStep',[0.01,0.1],'String','Edit','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','EditChannel','Callback','EditChannel_callback(handles)')
handles.DelChannel=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.19,0.44,0.0616854,0.0583039],'Relief','default','SliderStep',[0.01,0.1],'String','Del','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','DelChannel','Callback','DelChannel_callback(handles)')

handles.AddComponents=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.288,0.44,0.0616854,0.0583039],'Relief','default','SliderStep',[0.01,0.1],'String','Add','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','AddComponents','Callback','AddComponents_callback(handles)')

handles.EditComponentsUsed=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.448,0.44,0.0616854,0.0583039],'Relief','default','SliderStep',[0.01,0.1],'String','Edit','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','EditComponentsUsed','Callback','EditComponentsUsed_callback(handles)')
handles.DelComponentsUsed=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.518,0.44,0.0616854,0.0583039],'Relief','default','SliderStep',[0.01,0.1],'String','Del','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','DelComponentsUsed','Callback','DelComponentsUsed_callback(handles)')
handles.UPComponentsUsed=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Lucida Console','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.65,0.44,0.05,0.058],'Relief','default','SliderStep',[0.01,0.1],'String','▲','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','UPComponentsUsed','Callback','UPComponentsUsed_callback(handles)')
handles.DOWNComponentsUsed=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Lucida Console','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.70,0.44,0.05,0.058],'Relief','default','SliderStep',[0.01,0.1],'String','▼','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','DOWNComponentsUsed','Callback','DOWNComponentsUsed_callback(handles)')

//handles.ImageController=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.047191,0.0512367,0.9033708,0.3515901],'Relief','default','SliderStep',[0.01,0.1],'String','Controller','Style','image','Value',[1,1,0,0,0],'VerticalAlignment','middle','Visible','on','Tag','ImageController','Callback','ImageController_callback(handles)')
drawlater();    //delay drawing axes entity
handles.ImageController = newaxes(f);
handles.ImageController.axes_bounds = [0.046,0.57,0.85,0.39];
handles.ImageController.clip_state = "clipgrf";
handles.ImageController.margins = [0 0 0 0];
handles.ImageController.axes_visible = "off";
handles.ImageController.auto_scale = "off";
handles.ImageController.zoom_box = [];
handles.ImageController.font_size = handles.ImageController.font_size + 1;
//handles.ImageController.font_style = 4;
//handles.ImageController.auto_ticks = ["off","off","off"];
//handles.ImageController.x_ticks = tlist(["ticks", "locations", "labels"], [0;0.2;0.4;0.6;0.8], ["0";"0.2";"0.4";"0.6";"0.8"]);
//handles.ImageController.y_ticks = tlist(["ticks", "locations", "labels"], [0;0.2;0.4;0.6;0.8], ["0";"0.2";"0.4";"0.6";"0.8"]);
//handles.ImageController.data_bounds = [0,0;2,2];
//handles.ImageController.auto_margins = "on";
//handles.ImageController.arc_drawing_method = "nurbs"; //"nurbs" "lines"
//handles.ImageController.grid_style = [3,3];
drawnow();  //draw axes entity

handles.NewAutopilot=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.050,0.917,0.0722472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','New','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','NewAutopilot','Callback','NewAutopilot_callback(handles)')
handles.OpenAutopilot=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.128,0.917,0.0722472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','Open','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','OpenAutopilot','Callback','OpenAutopilot_callback(handles)')
handles.SaveAutopilot=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.208,0.917,0.0722472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','Save','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','SaveAutopilot','Callback','SaveAutopilot_callback(handles)')
//handles.SaveAutopilotFlightGear=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.288,0.917,0.1022472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','Export-FG','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','SaveAutopilotFlightGear','Callback','SaveAutopilotFlightGear_callback(handles)')

handles.ParametersInitial=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.448,0.917,0.1222472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','Initial Parameters','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','ParametersInitial','Callback','ParametersInitial_callback(handles)')
handles.SimulationDefinition=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.578,0.917,0.1222472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','Define Simulation','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','SimulationDefinition','Callback','SimulationDefinition_callback(handles)')
handles.PIDDesignStart=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.708,0.917,0.1222472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','Start PID Design','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','PIDDesignStart','Callback','PIDDesignStart_callback(handles)')
handles.SimulationStart=uicontrol(f,'unit','normalized','BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.838,0.917,0.1222472,0.0742049],'Relief','default','SliderStep',[0.01,0.1],'String','Start Simulation','Style','pushbutton','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','SimulationStart','Callback','SimulationStart_callback(handles)')



//////////
// Callbacks are defined as below. Please do not delete the comments as it will be used in coming version
//////////



function Components_callback(handles)
//Write your callback for  Components  here
    
    //nothing
    
endfunction



function Channels_callback(handles)
//Write your callback for  Channels  here

    channelChoiceGlobalString = "<global>";  //everything which is not channel belongs to 'global' (autopilot) tag (e.g. property)
    stringSelected = handles.Channels.String(handles.Channels.Value);
    
    global xmlAutopilot;
    if xmlAutopilot.root.name == "autopilot" then
        
        
        //if global tag was selected
        if stringSelected == channelChoiceGlobalString then
            
            //set components available for global section
            handles.Components.String = componentsGlobalStrings;
            
        else
            
            //set components available for channel sections
            handles.Components.String = componentsChannelStrings;
            
        end
        
        
        if length(xmlAutopilot.root.children) > 0 then
        
            children = xmlAutopilot.root.children;
            
            ComponentsUsedChoices = [];
            
            //if global tag was selected
            if stringSelected == channelChoiceGlobalString then
                
                //selected <global> channel
                global xmlChannelSelected;
                xmlChannelSelected = xmlAutopilot.root;
                
                //properties in global (e.g. property) excluding channel and comment tag
                for i = 1 : 1 : length(children)
                    //find elements whitch have property tag
                    if (children.name(i) == "property") then
                    //find elements whitch does not have channel tag or are not comments or documentations
                    //if ((children.name(i) ~= "channel") & (children.name(i) ~= "comment") & (children.name(i) ~= "documentation")) then
                        
                        //add name of the element property (the contain attribute) to string
                        //addString = "";
                        //if length(children(i).attributes) > 0 then
                        //    addString = "   value:" + children(i).attributes.value;
                        //end
                        ComponentsUsedChoices(size(ComponentsUsedChoices, 1) + 1) = "<" + children(i).name + "> " + children(i).content;// + addString;
                        
                    end
                end 
            
            else
                
                for i = 1 : 1 : length(children)
                    //find elements with 'channel' tag
                    if children.name(i) == "channel" then
                        //find the selected element
                        if children(i).attributes.name == stringSelected then
                            
                            //selected this specific channel
                            global xmlChannelSelected;
                            xmlChannelSelected = children(i);
                            
                            components = children(i).children;
                            for j = 1 : 1 : length(components)
                                //add name of the element channel (the name attribute) to choices string (excluding comment and documentation tag - comments and documentations can be included if necessary (it may be useful))
                                if ((components(j).name ~= "comment") & (components(j).name ~= "documentation") & (components(j).name ~= "text")) then 
                                    ComponentsUsedChoices(size(ComponentsUsedChoices, 1) + 1) = "<" + components(j).name + "> " + components(j).attributes.name;
                                end
                            end
                            
                        end
                    end
                end 
            
            end
            
            //change data in listboxes
            handles.ComponentsUsed.String = ComponentsUsedChoices;
            //draw controller using selected XML channel
            ImageControllerDrawing(xmlChannelSelected);
            
        else
            
            //selected empty channel
            global xmlChannelSelected;
            xmlChannelSelected = xmlAutopilot.root;
            
        end
    else
    
        messagebox("Wrong format! The XML file is not a valid autopilot file!", "modal", "error");
        
    end
    

endfunction



function ComponentsUsed_callback(handles)
//Write your callback for  ComponentsUsed  here
    
    if handles.ComponentsUsed.Value > 0 & handles.Channels.String(handles.Channels.Value) ~= "<global>" then
        
        stringSelected = handles.ComponentsUsed.String(handles.ComponentsUsed.Value);
        
        //decode the name (actually the name attribute) of the used component
        indexesSymbolOfNameBeginning=strindex(stringSelected, '> ');
        stringSelectedXMLName=part(stringSelected, indexesSymbolOfNameBeginning(1)+2:length(stringSelected));
        
        //highlight the selected component in the drawed schema and cancel the preivous highlight if any
        global xmlChannelSelectedVisualComponentsList;
        HighlightSelectedVisualComponent(handles.ImageController, xmlChannelSelectedVisualComponentsList, stringSelectedXMLName);
        
    end
    
endfunction



function AddChannel_callback(handles)
//Write your callback for  AddChannel  here
    
    global xmlAutopilot;
    //read xml file with channel template definition
    global xmlChannel;
    CheckAndDeleteXMLDoc(xmlChannel);
    xmlChannel = xmlRead("templates" + filesep() + "channel.xml");
    errorString=ValidateXMLdocument(xmlChannel);
    
    
    //check whether it has 'channel' tag
    if xmlChannel.root.name == "channel" then
        
        
        rootChannel = xmlChannel.root;
        
        
        //get attribute names and values
        //xmlName function retrieve the name of the elements/attributes
        labels = xmlName(rootChannel.attributes);
        values = [];
        for i = 1 : 1 : length(rootChannel.attributes)
            values(size(values, 1) + 1) = rootChannel.attributes(i);
        end
        //transpose matrix with values
        values = values';
        
        //show mDialog for editation of channel attributes/properties (add labels and textBox elements with default values into dialog)
        valuesOut = x_mdialog('enter channel properties', labels, values);
        
        //if cancel button was not clicked
        if valuesOut ~= [] then
            
            
            //set all new values in attributes
            //example:
            //mag = evstr(valuesOut(1))
            //frq = evstr(valuesOut(2))
            //ph  = evstr(valuesOut(3))
            for i = 1 : 1 : length(rootChannel.attributes)
                rootChannel.attributes(i) = valuesOut(i);
            end
            
            
//            //change all white spaces (ie. ' ') to underscore (ie. '_') char
//            rootChannel.attributes.name = strsubst(rootChannel.attributes.name, " ", "_");
            //change all '<' and '>' to underscore (ie. '_') char ('<' and '>' are reserved chars in our application)
            rootChannel.attributes.name = strsubst(rootChannel.attributes.name, "<", "_");
            rootChannel.attributes.name = strsubst(rootChannel.attributes.name, ">", "_");
            //check wheter the name is not empty or it is different from reserved name "<global>"
            if rootChannel.attributes.name == "" | rootChannel.attributes.name == "<global>" | strsubst(rootChannel.attributes.name, " ", "") == emptystr() then
                messagebox("This is not possible name!", "modal", "error");
                return
            end
            
            //add new channel in XML autopilot
            if xmlAutopilot.root.name == "autopilot" then
                
                
                children = xmlAutopilot.root.children;
                
                
                //check whether the new name of channel is in the current list of channels
                //if so, stop this function
                for i = 1 : 1 : length(children)
                    
                    if rootChannel.attributes.name == children(i).attributes.name then
                        messagebox("This name is already used!", "modal", "error");
                        return
                    end
                    
                end
                
                
                //add new child to XML children elements in autopilot
                indexNew = length(children) + 1;
                children(indexNew) = xmlChannel;
                rootChannel = children(indexNew);
                
                
                //change data in listboxes
                //add name of the element channel (the name attribute) to choices string
                channelsChoices = handles.Channels.String;
                channelsChoices(size(channelsChoices, 2) + 1) = rootChannel.attributes.name;
                handles.Channels.String = channelsChoices;
                handles.Components.String = [];
                handles.ComponentsUsed.String = [];
                
                //selected channel (0 (none) is default)
                global xmlChannelSelected;
                xmlChannelSelected = 0;
                
                //Clear current axes schema
                ClearAxesSchema(handles.ImageController);
                
            else
            
                messagebox("Wrong format! The XML file is not a valid autopilot file!", "modal", "error");
                
            end
        
        
        end
    
    
    else
    
        messagebox("Wrong format! The XML file ""templates" + filesep() + "channel.xml"" is not a valid channel file!", "modal", "error");
        
    end
    

endfunction



function EditChannel_callback(handles)
    
    if handles.Channels.Value > 0 then
        
        stringSelected = handles.Channels.String(handles.Channels.Value);
        
        global xmlAutopilot;
        if xmlAutopilot.root.name == "autopilot" then
            
            //if there is a child and global tag was not selected
            if length(xmlAutopilot.root.children) > 0 & stringSelected ~= "<global>" then
                
                
                children = xmlAutopilot.root.children;
                for i = 1 : 1 : length(children)
                    
                    //find elements which have channel tag
                    if children.name(i) == "channel" then
                        
                        //find element with the selected name
                        if children(i).attributes.name == stringSelected then
                            
                            
                            //get attribute names and values
                            //xmlName function retrieve the name of the elements/attributes
                            labels = xmlName(children(i).attributes);
                            values = [];
                            for j = 1 : 1 : length(children(i).attributes)
                                values(size(values, 1) + 1) = children(i).attributes(j);
                            end
                            //transpose matrix with values
                            values = values';
                            
                            //show mDialog for editation of channel attributes/properties (add labels and textBox elements with values into dialog)
                            valuesOut = x_mdialog('edit channel properties', labels, values);
                            
                            //if cancel button was not clicked
                            if valuesOut ~= [] then
                                
                                
//                                //change all white spaces (ie. ' ') to underscore (ie. '_') char
//                                valuesOut = strsubst(valuesOut, " ", "_");
                                //change all '<' and '>' to underscore (ie. '_') char ('<' and '>' are reserved chars in our application)
                                valuesOut = strsubst(valuesOut, "<", "_");
                                valuesOut = strsubst(valuesOut, ">", "_");
                                indexNameInValueOut = 0;
                                for j = 1 : 1 : length(labels)
                                    //find name in labels and set its index
                                    if convstr(strsubst(labels(j), " ", ""), 'l') == "name" then
                                        indexNameInValueOut = j;
                                        break;
                                    end
                                end
                                
                                
                                //if name was found in properties of channel
                                if indexNameInValueOut > 0 then
                                    
                                    //check wheter the name is not empty or it is different from reserved name "<global>"
                                    if valuesOut(indexNameInValueOut) == emptystr() | valuesOut(indexNameInValueOut) == "<global>" | strsubst(valuesOut(indexNameInValueOut), " ", "") == emptystr() then
                                        messagebox(["This is not possible name!" ; "label: " + labels(indexNameInValueOut) ; "value: " + valuesOut(indexNameInValueOut) ], "modal", "error");
                                        return
                                    end
                                    
                                    //check whether the set name of channel is in the current list of channels ('i' index must be different from 'j' index)
                                    //if so, stop this function
                                    for j = 1 : 1 : length(children)
                                        if i ~= j then
                                            if valuesOut(indexNameInValueOut) == children(j).attributes.name then
                                                messagebox("This name is already used!", "modal", "error");
                                                return
                                            end
                                        end
                                    end
                                end
                                
                                
                                //set all new values in attributes
                                for j = 1 : 1 : length(children(i).attributes)
                                    children(i).attributes(j) = valuesOut(j);
                                end
                                
                                
                                
//                                //load and add properties
//                                global propertiesAvailable;
//                                propertiesAvailable = ReadInternalAndCustomProperties();
//                                //add properties from XML file to list with properties
//                                propertiesAvailable = AddPropertiesFromLoadedXMLToPropertiesAvailable(xmlAutopilot, propertiesAvailable);
                                
                                
                                //if name was found in properties of channel
                                if indexNameInValueOut > 0 then
                                    
                                    //edit data in listboxes (Channels, Components and ComponentsUsed)
                                    channelsString = handles.Channels.String;
                                    //selectedChannelsValue = handles.Channels.Value;
                                    channelsString(handles.Channels.Value) = valuesOut(indexNameInValueOut);
                                    handles.Channels.String = channelsString;
                                    //handles.Channels.Value = selectedChannelsValue;
                                    handles.Components.String = [];
                                    handles.ComponentsUsed.String = [];
                                    //Clear current axes schema
                                    ClearAxesSchema(handles.ImageController);
                                end
                                
                                return;
                                
                                
                            end
                            
                        end
                        
                    end
                    
                end
                
            end
            
        else
            
            messagebox("Wrong format! The XML file is not a valid autopilot file!", "modal", "error");
            
        end
        
        
    end
    
endfunction



function DelChannel_callback(handles)
//Write your callback for  DelChannel  here
    
    
    if handles.Channels.Value > 0 then
        
        stringSelected = handles.Channels.String(handles.Channels.Value);
        
        global xmlAutopilot;
        if xmlAutopilot.root.name == "autopilot" then
            
            //if there is a child and global tag was not selected
            if length(xmlAutopilot.root.children) > 0 & stringSelected ~= "<global>" then
                
                
                children = xmlAutopilot.root.children;
                for i = 1 : 1 : length(children)
                    
                    //find elements which have channel tag
                    if children.name(i) == "channel" then
                        
                        //find element with the selected name
                        if children(i).attributes.name == stringSelected then
                            
                            //delete channel from the XML
                            xmlRemove(children(i));
                            
                            
                            //load and add properties
                            global propertiesAvailable;
                            propertiesAvailable = ReadInternalAndCustomProperties();
                            //add properties from XML file to list with properties
                            propertiesAvailable = AddPropertiesFromLoadedXMLToPropertiesAvailable(xmlAutopilot, propertiesAvailable);
                            
                            
                            //delete data in listboxes (Channels, Components and ComponentsUsed)
                            channelsString = handles.Channels.String;
                            channelsString(handles.Channels.Value) = [];
                            handles.Channels.String = channelsString;
                            handles.Components.String = [];
                            handles.ComponentsUsed.String = [];
                            //Clear current axes schema
                            ClearAxesSchema(handles.ImageController);
                            
                            break;
                        
                        end
                    
                    end
                
                end
                
            end
            
        else
        
            messagebox("Wrong format! The XML file is not a valid autopilot file!", "modal", "error");
            
        end
    
    
    end
    
    
endfunction



function AddComponents_callback(handles)
//Write your callback for  AddComponents  here
    
    
    
    //load a component template from a proper XML file in the folder: "templates\Components" depending on the selection
    //if there are components and a channel is selected (is not 0 (none))
    global xmlChannelSelected;
    //disp(xmlChannelSelected);
    //disp(typeof(xmlChannelSelected));
    if handles.Components.Value > 0 & typeof(xmlChannelSelected) == "XMLElem" then
        
        //disp('xmlChannelSelected is XMLElem type');
        
        stringSelected = handles.Components.String(handles.Components.Value);
        //read xml file with the specific component template definition
        xmlComponent = xmlRead("templates" + filesep() + "Components" + filesep() + "" + stringSelected + ".xml");
        errorString=ValidateXMLdocument(xmlComponent);
        //disp("templates\Components\" + stringSelected + ".xml");
        
        //read xml file with the specific empty component definition (without attributes and elements)
        xmlComponentOut = xmlRead("templates" + filesep() + "Components_withoutAttributes" + filesep() + "" + stringSelected + ".xml");
        errorString=ValidateXMLdocument(xmlComponentOut);
        
        
        
        //check whether it is not 'property' or 'comment' element
        //and decode the loaded component template
        if xmlComponent.root.name ~= "property" & xmlComponent.root.name ~= "comment" & xmlComponent.root.name ~= "documentation" then
            
            
            //<>debug only
            //disp('xmlComponent is NOT property, comment or documentation');
            //disp("          """ + xmlComponent.root.name + """          ");
            
            
            rootComponent = xmlComponent.root;
            labels = ["name*"];    //add name label with asterisk; i.e. '*' because it is required
            values = [rootComponent.attributes.name];   //add name from name attribute
            possibleInputTypesList = [""];
            optionals = [%f];    //add optional/required information
            canRepeats = [%f];    //add information whether the element can repeat
            contentCanRepeats = [%f];    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
            canIncludeTestss = [%f];    //add information whether the content of the element can include tests (<>only for test (in switch))
            
            testValueIndexInDialog = 0;
            testTestIndexInDialog = 0;
            
            //get children names, attributes and values
            childrenComponent = rootComponent.children;
            for i = 1 : 1 : length(childrenComponent)
                
                //if the element is comment, ignore it and continue at the beginning of this for cycle
                if childrenComponent(i).name == "comment" then
                    continue;
                end
                
                
                //check all information attributes and process them
                attributeNames = xmlName(childrenComponent(i).attributes);
                [optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).attributes);
                
                
                //check all attributes and if they are not those specific predefined, add them
                for j = 1 : 1 : length(childrenComponent(i).attributes)
                    
                    if attributeNames(j) ~= "optional" & attributeNames(j) ~= "canrepeat" & attributeNames(j) ~= "contentcanrepeat" & attributeNames(j) ~= "canincludetests" then
                        
                        //<>debug only
                        //disp("only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes");
                        
                        //get index of value attribute in dialog (for test element in switch component only)
                        if childrenComponent(i).name == "test" & attributeNames(j) == "value" then
                            testValueIndexInDialog = size(values, 2) + 1;
                        end
                        
                        //process attribute and add it to labels and values (only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes)
                        //add default strings to text boxes in dialog
                        values(1, size(values, 2) + 1) = SetIDinValue(childrenComponent(i).attributes(j));
                        //add information about input to label in dialog (the magic word "<attribute>" defines that the value has to be put in attributes, not in children of the element)
                        labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + attributeTag + "_" + attributeNames(j) + asterisk + semicolon + " (" + childrenComponent(i).attributes(j) + ")";
                        possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).attributes(j);
                        
                        //add all information attributes
                        optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                        canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat -> note: XML attributes cannot repeat, i.e. %f
                        contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch)) -> note: XML attributes don't have any content to repeat, i.e. %f
                        canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch)) -> note: XML attributes cannot include tests, i.e. %f
                        
                        
                    end
                    
                end
                
                
                //if the element has only one child (text), add it to labels and values
                if length(childrenComponent(i).children) == 1 & childrenComponent(i).children(1).name == "text" then
                    
                    //<>debug only
                    //disp("one child");
                    //disp(childrenComponent(i).name);
                    //disp(childrenComponent(i).content);
                    
                    //if the element is NOT table (only scheduled_gain component contains table element)
                    if childrenComponent(i).name ~= "table" then
                        
                        //get index of test element in dialog (for test element in switch component only)
                        if childrenComponent(i).name == "test" then
                            testTestIndexInDialog = size(values, 2) + 1;
                        end
                        
                        //add default strings to text boxes in dialog
                        values(1, size(values, 2) + 1) = SetIDinValue(childrenComponent(i).content);
                        //add information about input to label in dialog
                        labels(1, size(labels, 2) + 1) = childrenComponent(i).name + asterisk + semicolon + " (" + childrenComponent(i).content + ")";
                        possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).content;
                        
                        //add all information attributes
                        optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                        canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
                        contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
                        canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                        
                    end
                    
                    
                //else if the element has more children elements (e.g. clipto), add them to labels and values
                elseif length(childrenComponent(i).children) > 0 then
                    
                    //<>debug only
                    //disp(childrenComponent(i).name);
                    
                    //if the first child has not-text children (for kinematic only)
                    if length(childrenComponent(i).children(1).children) > 0 & childrenComponent(i).children(1).children(1).name ~= "text" then
                        
                        //check all information attributes and process them
                        attributeNames = xmlName(childrenComponent(i).children(1).attributes);
                        [optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).children(1).attributes);
                        
                        //got through children of first child of component's children :-)
                        for k = 1 : 1 : length(childrenComponent(i).children(1).children)
                            
                            //<>debug only
                            //disp("more than more (sub)children");
                            //disp(childrenComponent(i).children(1).children(k).name);
                            //disp(childrenComponent(i).children(1).children(k).content);
                            
                            //add default strings to text boxes in dialog
                            values(1, size(values, 2) + 1) = SetIDinValue(childrenComponent(i).children(1).children(k).content);
                            //add information about input to label in dialog
                            labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(1).name + "_" + childrenComponent(i).children(1).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(1).children(k).content + ")";
                            possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).children(1).children(k).content;
                            
                            //add all information attributes
                            optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                            canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
                            contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
                            canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                            
                            
                        end
                        
                        
                    else
                        
                        for k = 1 : 1 : length(childrenComponent(i).children)
                            
                            //<>debug only
                            //disp("more children");
                            //disp(childrenComponent(i).children(k).name);
                            //disp(childrenComponent(i).children(k).content);
                            
                            //add default strings to text boxes in dialog
                            values(1, size(values, 2) + 1) = SetIDinValue(childrenComponent(i).children(k).content);
                            //add information about input to label in dialog
                            labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(k).content + ")";
                            possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).children(k).content;
                            
                            //add all information attributes
                            optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                            canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
                            contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
                            canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                            
                            
                        end
                        
                        
                    end
                    
                    
                //probably only for switch
                //because the code for attribute decoding is above, the following code is redundant
//                else
//                    
//                    //<>debug only
//                    //disp("no child");
//                    //disp(childrenComponent(i).name);
//                    //disp(childrenComponent(i).attributes.value);    //for switch only
//                    
//                    //add default strings to text boxes in dialog
//                    values(1, size(values, 2) + 1) = SetIDinValue(childrenComponent(i).attributes.value);
//                    //add information about input to label in dialog
//                    labels(1, size(labels, 2) + 1) = childrenComponent(i).name + asterisk + semicolon + " (" + childrenComponent(i).attributes.value + ")";
//                    possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).attributes.value;
//                    
//                    //add all information attributes
//                    optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
//                    canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
//                    contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
//                    canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                    
                    
                end
                
                
            end
            
            
            
            
            //add text with a function of a filter when needed
            filterFunctionText = GetFilterFunctionText(rootComponent.name);
            //show mDialog for editation of component attributes/properties (add labels and textBox elements with default values into dialog)
            valuesOut = x_mdialog(['Component: ' + rootComponent.name + filterFunctionText ; "(* means required)" ; "(; means repeatable - separated by semicolon)"], labels, values);
            
            
            //if cancel button was not clicked
            if valuesOut ~= [] then
                
                global propertiesAvailable;
                
                //check if all inputs were set properly
                inputsSetPropery = [];
                for i = 2 : 1 : size(possibleInputTypesList, 2)
                    inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), possibleInputTypesList(i), propertiesAvailable, optionals(i), canRepeats(i));
                end
                //check number of output test values and number of tests if necessary
                testError = emptystr();
                if testValueIndexInDialog > 0 & testTestIndexInDialog > 0 then
                    inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckTestNValuesNTests(valuesOut(testValueIndexInDialog), valuesOut(testTestIndexInDialog));
                    if inputsSetPropery(size(inputsSetPropery, 1)) == %f then
                        testError = "The number of values are not same as number of tests!";
                    else
                        testError = emptystr();
                    end
                end
                
                
                while strsubst(valuesOut(1), " ", "") == "" | part(strsubst(valuesOut(1), " ", ""), 1) == "-" | strindex(valuesOut(1), ";") ~= [] | FindPropertyInPropertiesAvailable(strsubst(valuesOut(1), " ", ""), propertiesAvailable) | and(inputsSetPropery) == %f
                    
                    
                    //show mDialog again because error occurs -> Required fields are empty, set incorrectly (e.g. must be number) or the name identifier of the component is already used!
                    valuesOut = x_mdialog(['Component: ' + rootComponent.name + filterFunctionText ; "(* means required)" ; "(; means repeatable - separated by semicolon)" ; "Required fields are empty, fields are set incorrectly (e.g. must be number or has to be in property list), or the name identifier of the component is already used!" ; testError], labels, valuesOut');
                    
                    
                    if valuesOut == [] then




                        return;
                    end
                    
                    //check if all inputs were set properly
                    inputsSetPropery = [];
                    for i = 2 : 1 : size(possibleInputTypesList, 2)
                        inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), possibleInputTypesList(i), propertiesAvailable, optionals(i), canRepeats(i));
                    end
                    //check number of output test values and number of tests if necessary
                    testError = emptystr();
                    if testValueIndexInDialog > 0 & testTestIndexInDialog > 0 then
                        inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckTestNValuesNTests(valuesOut(testValueIndexInDialog), valuesOut(testTestIndexInDialog));
                        if inputsSetPropery(size(inputsSetPropery, 1)) == %f then
                            testError = "The number of values are not same as number of tests!";
                        else
                            testError = emptystr();
                        end
                    end
                    
                    
                end
                
                
                
                
                //add elements and values to the XML component and insert it to the selected channel
                //set component name from dialog to name attribute
                xmlComponentOut.root.attributes.name = strsubst(valuesOut(1), " ", "");
                
                
                containsTableElement = %f;
                valuesOutIndex = 2;
                //almost same code as in the generation of the dialog above
                for i = 1 : 1 : length(childrenComponent)
                    
                    
                    //if the element is comment, ignore it and continue at the beginning of this for cycle
                    if childrenComponent(i).name == "comment" then
                        //add comment to output XML element and continue in loop
                        xmlAppend(xmlComponentOut.root, childrenComponent(i));
                        continue;
                    end
                    
                    //tells whether main element was already created (if this element is optional, and the attributes and sub-elements are empty, the main element will not be created)
                    mainElementWasCreatedAlready = %f;
                    
                    
                    
                    //check all information attributes and process them
                    attributeNames = xmlName(childrenComponent(i).attributes);
                    //[optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).attributes);
                    //array for series of values in attribute (for test element only)
                    testAttributeValues = [];
                    
                    //check all attributes and if they are not those specific predefined, add them
                    for j = 1 : 1 : length(childrenComponent(i).attributes)
                        
                        if attributeNames(j) ~= "optional" & attributeNames(j) ~= "canrepeat" & attributeNames(j) ~= "contentcanrepeat" & attributeNames(j) ~= "canincludetests" then
                            
                            //<>debug only
                            //disp("only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes");
                            
                            //process attribute and add it from XML template and input values to XML element (only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes)
                            valueWithoutWhiteSpaces = strsubst(valuesOut(valuesOutIndex), " ", "");
                            //if the attribute contains any string, add it
                            if valueWithoutWhiteSpaces ~= "" then
                                
                                //if the element is test (only switch component contains test element)
                                if childrenComponent(i).name == "test" then
                                    //if the current attribute is "value"
                                    if attributeNames(j) == "value" then
                                        
                                        //get test values in attribute separated by semicolon
                                        testAttributeValues = tokens(valueWithoutWhiteSpaces, ";");
                                        
                                    else
                                        
                                        disp("The current attribute: """ + attributeNames(j) + """ of ""test"" element is not supported in code!");
                                        
                                    end
                                    
                                    
                                else
                                    
                                    //create new child element in root element when it was not already created
                                    if mainElementWasCreatedAlready == %f then
                                        
                                        xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                        mainElementWasCreatedAlready = %t;
                                        
                                    end
                                    
                                    //add attribute and input value from dialog to XML element
                                    xmlSetAttributes(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), [attributeNames(j) valueWithoutWhiteSpaces]);
                                    
                                    
                                end
                                
                                
                            elseif optionals(valuesOutIndex) == %f then
                                
                                messagebox("Non-optional attribute: """ + attributeNames(j) + """ of the element type: """ + childrenComponent(i).name + """ was not set!", "modal", "error");
                                return;
                                
                            end
                            
                            valuesOutIndex = valuesOutIndex + 1;
                            
                            
//                            //information about input in label of dialog ("<attribute>" defines that the value has to be put in attributes, not in children of the element)
//                            labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + attributeTag + "_" + attributeNames(j) + asterisk + semicolon + " (" + childrenComponent(i).attributes(j) + ")";
                            
                            
                        end
                        
                    end
                    
                    
                    
                    //if the element has only one child (text)
                    if length(childrenComponent(i).children) == 1 & childrenComponent(i).children(1).name == "text" then
                        
                        //<>debug only
                        //disp("one child");
                        //disp(childrenComponent(i).name);
                        //disp(childrenComponent(i).content);
                        
                        //if the element is NOT table (only scheduled_gain component contains table element)
                        if childrenComponent(i).name ~= "table" then
                            
                            
                            
                            //if the input value is true or false in Scilab format, convert it to the JSBSim format
                            if valuesOut(valuesOutIndex) == "%t" | valuesOut(valuesOutIndex) == "%f" then// valuesOut(valuesOutIndex) == %t | valuesOut(valuesOutIndex) == %f then
                                
                                valuesOut(valuesOutIndex) = ConvertBooleanStringToTrueFalseString(valuesOut(valuesOutIndex));
                                
                            end
                            
                            //process element and add it from XML template and input values to content of the XML element
                            valueWithoutWhiteSpaces = strsubst(valuesOut(valuesOutIndex), " ", "");
                            if canRepeats(valuesOutIndex) == %t then
                                
                                valueWithoutWhiteSpaces = tokens(valueWithoutWhiteSpaces, ";");
                                
                            end
                            
                            
                            //if the element contains any string, add it
                            if valueWithoutWhiteSpaces ~= [] & valueWithoutWhiteSpaces ~= "" then
                                
                                
                                //if the element is function (only fcs_function component contains function element)
                                if childrenComponent(i).name == "function" then
                                    
                                    
                                    //create new child element in root element when it was not already created //or it can be created multiple times and this is not the first iteration
                                    if mainElementWasCreatedAlready == %f then //| (canRepeats(valuesOutIndex) == %t & j > 1) then
                                        
                                        xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                        mainElementWasCreatedAlready = %t;
                                        
                                    end
                                    
                                    
                                    
                                    
                                    
                                    
                                    //find the table tag in function if any
                                    tableTag = "table";
                                    outXMLTableElementsList = list();
                                    //get all table tag strings from string equation if any
                                    tableStringsList = GetTableStringsFromStringEquation(valueWithoutWhiteSpaces, tableTag);
                                    //if any table tag was found, process it
                                    if length(tableStringsList) > 0 then
                                        
                                        
                                        //create empty list with XML table elements (we are adding new xml function element, there has been no table yet)
                                        tableXMLElementsList = list();
                                        //decode or create default data from table XML elements
                                        [tableStringsMatricesList, tableTitleArraysList, tablePropertyRowsList, tablePropertyColumnsList, tablesPropertyTableList] = DecodeOrCreateXMLTables(tableXMLElementsList, tableStringsList, emptystr());
                                        
                                        
                                        //if all lists have same length, everything is OK
                                        if length(tableStringsList) == length(tableStringsMatricesList) & length(tableStringsList) == length(tableTitleArraysList) & length(tableStringsList) == length(tablePropertyRowsList) & length(tableStringsList) == length(tablePropertyColumnsList) & length(tableStringsList) == length(tablesPropertyTableList) then
                                            
                                            //show table dialogs for all table strings in list with decoded or defaultly created structures
                                            for x = 1 : 1 : length(tableStringsList)
                                                
                                                
                                                //show table dialog with decoded values
                                                [outTableStringMatrices, outTableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable] = DialogTableOkCancel(tableStringsMatricesList(x), tableTitleArraysList(x), tablePropertyRowsList(x), tablePropertyColumnsList(x), tablesPropertyTableList(x), propertiesAvailable);
                                                
                                                //if there is any output
                                                if outTableStringMatrices ~= [] & outTableStringMatrices ~= list() then
                                                    
                                                    //encode string data from dialog to XML table
                                                    outXMLTable = EncodeXMLTable(outTableStringMatrices, outTableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable);
                                                    //if there is no error
                                                    if outXMLTable ~= [] then
                                                        
                                                        //add table element to the list of XML table elements
                                                        outXMLTableElementsList($+1) = outXMLTable;
                                                        
                                                    else
                                                        messagebox(["Table no. " + string(x) + " was not set properly!" ; "row property: """ + outPropertyRow + """" ; "column property: """ + outPropertyColumn + """" ; "table property: " + outPropertyTable + """" ], "modal", "error");  // ; "Table Titles: " ; outTableTitleArray ; "Table Data: " ; outTableStringMatrices
                                                    end
                                                    
                                                    
                                                else
                                                    
                                                    //otherwise, cancel was clicked (or some error occured?)
                                                    return;
                                                    
                                                end
                                                
                                                
                                            end
                                            
                                        else
                                            
                                            messagebox(["Tables were not loaded properly!" ; "The number of proposed tables is not equal to the number of decoded/created tables" ; "rows properties: """ + tablePropertyRowsList + """" ; "columns properties: """ + tablePropertyColumnsList + """" ; "tables properties: " + tablesPropertyTableList + """" ; "Tables Titles: " ; tableTitleArraysList ; "Tables Data: " ; tableStringsMatricesList ; ], "modal", "error");
                                            return;
                                            
                                        end
                                        
                                        
                                    end
                                    
                                    
                                    

                                    //convert string to XML function element
                                    XMLMathFunctionsElement = StringEquationToXMLMathFunc(valueWithoutWhiteSpaces, propertiesAvailable, outXMLTableElementsList);
                                    //check if conversion was successful
                                    if XMLMathFunctionsElement ~= [] then
                                        
                                        //add new XML function element child to the output XML function element
                                        xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), XMLMathFunctionsElement.root.children(1));
                                        
                                    else
                                        
                                        messagebox(["Function was not converted properly!" ; "Name of Element: """ + childrenComponent(i).name + """" ; "(Wrong) Element Value: """ + valueWithoutWhiteSpaces + """"], "modal", "error");
                                        return;
                                        
                                    end
                                    
                                    
                                    
                                //else if the element is test (only switch component contains test element)
                                elseif childrenComponent(i).name == "test" then
                                    
                                    //get value with white spaces
                                    valueOriginal = valuesOut(valuesOutIndex);
                                    if canRepeats(valuesOutIndex) == %t then

                                        valueOriginal = tokens(valuesOut(valuesOutIndex), ";");
                                    end
                                    
                                    
                                    if size(testAttributeValues, 1) == size(valueOriginal, 1) then
                                        
                                        for j = 1 : 1 : size(valueOriginal, 1)
                                            
                                            
                                            //convert string to XML test element
                                            XMLTestElement = StringEquationToXMLTest(valueOriginal(j), childrenComponent(i).name, propertiesAvailable);
                                            //check if conversion was successful
                                            if XMLTestElement ~= [] then
                                                
                                                //add value in attribute from dialog to XML element
                                                xmlSetAttributes(XMLTestElement.root, ["value" testAttributeValues(j)]);
                                                //add new XML test element to the output XML switch component
                                                xmlAppend(xmlComponentOut.root, XMLTestElement.root);
                                                
                                                //just for sure, it has probably no other meaning here
                                                mainElementWasCreatedAlready = %t;
                                                
                                                
                                            else
                                                
                                                messagebox(["Test was not converted properly!" ; "Number of Test: " + string(j) ; "(Wrong) Element Value: """ + valueOriginal(j) + """"], "modal", "error");
                                                return;
                                                
                                            end
                                            
                                            
                                        end
                                        
                                    else
                                        
                                        messagebox("The number of output test values (" + string(size(testAttributeValues, 1)) + ") is different from the number of tests: (" + string(size(valueOriginal, 1)) + ")!", "modal", "error");
                                        return;
                                        
                                    end
                                    
                                    
                                    
                                else
                                    
                                    
                                    for j = 1 : 1 : size(valueWithoutWhiteSpaces, 1)
                                        
                                        //create new child element in root element when it was not already created or it can be created multiple times and this is not the first iteration
                                        if mainElementWasCreatedAlready == %f | (canRepeats(valuesOutIndex) == %t & j > 1) then
                                            
                                            xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                            mainElementWasCreatedAlready = %t;
                                            
                                        end
                                        
                                        //add input value from dialog to content of the XML element
                                        xmlComponentOut.root.children(length(xmlComponentOut.root.children)).content = valueWithoutWhiteSpaces(j);
                                        
                                    end
                                
                                
                                end
                                
                                
                                
                            elseif optionals(valuesOutIndex) == %f then
                                
                                messagebox("Non-optional element type: """ + childrenComponent(i).name + """ was not set!", "modal", "error");
                                return;
                                
                            end
                            
                            valuesOutIndex = valuesOutIndex + 1;
                            
                            
                        else
                            
                            containsTableElement = %t;
                            
                        end
                        
                        
                        
                    //else if the element has more children elements (e.g. clipto)
                    elseif length(childrenComponent(i).children) > 0 then
                        
                        //<>debug only
                        //disp(childrenComponent(i).name);
                        
                        
                        //if the first child has not-text children (for kinematic only)
                        if length(childrenComponent(i).children(1).children) > 0 & childrenComponent(i).children(1).children(1).name ~= "text" then
                            
                            //check all information attributes and process them
                            //attributeNames = xmlName(childrenComponent(i).children(1).attributes);
                            //[optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).children(1).attributes);
                            
                            multiChildrenValues = list();
                            //got through children of first child of component's children :-)
                            for k = 1 : 1 : length(childrenComponent(i).children(1).children)
                                
                                //<>debug only
                                //disp("more than more (sub)children");
                                //disp(childrenComponent(i).children(1).children(k).name);
                                //disp(childrenComponent(i).children(1).children(k).content);
                                
                                
                                //process element
                                valueWithoutWhiteSpaces = strsubst(valuesOut(valuesOutIndex), " ", "");
                                if canRepeats(valuesOutIndex) == %t then
                                    
                                    valueWithoutWhiteSpaces = tokens(valueWithoutWhiteSpaces, ";");
                                    
                                end
                                
                                
                                //if the element contains any string, add it
                                if valueWithoutWhiteSpaces ~= [] & valueWithoutWhiteSpaces ~= "" then
                                    
                                    multiChildrenValues(0) = valueWithoutWhiteSpaces;
                                    
                                elseif optionals(valuesOutIndex) == %f then
                                    
                                    messagebox("Non-optional element type: """ + childrenComponent(i).children(1).children(k).name + """ was not set!", "modal", "error");
                                    return;
                                    
                                end
                                
                                //if there are more than one sub element
                                if length(multiChildrenValues) > 1 then
                                    
                                    //if the last two lists don't have same size
                                    if size(multiChildrenValues(length(multiChildrenValues) - 1), 1) ~= size(multiChildrenValues(length(multiChildrenValues)), 1) then
                                        
                                        messagebox("Element type: """ + childrenComponent(i).children(1).children(k-1).name + """ and element type: """ + childrenComponent(i).children(1).children(k).name + """ don"'t have same size!", "modal", "error");
                                        return;
                                        
                                    end
                                    
                                end
                                
                                valuesOutIndex = valuesOutIndex + 1;

                                
                            end
                            
                            
                            //add elements to output XML component
                            if length(multiChildrenValues) > 0 then
                                
                                for k = 1 : 1 : size(multiChildrenValues(1), 1)
                                    
                                    for j = 1 : 1 : size(multiChildrenValues, 1)
                                        
                                        valueWithoutWhiteSpaces = multiChildrenValues(j)(k);
                                        
                                        //create new child element in root element when it was not already created
                                        if mainElementWasCreatedAlready == %f then
                                            
                                            //add main XML element
                                            xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                            mainElementWasCreatedAlready = %t;
                                            
                                        end
                                        //for absolutely first iteration add subchild (i.e. there is only one subchild)
                                        if k == 1 & j == 1 then
                                            
                                            //add sub element to main XML element
                                            xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), xmlElement(xmlComponentOut, childrenComponent(i).children(1).name));
                                            
                                        end
                                        
                                        //add sub-sub element to sub element of main XML element :-)
                                        xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(1), xmlElement(xmlComponentOut, childrenComponent(i).children(1).children(j).name));
                                        
                                        //add an input value from dialog to content of the XML element
                                        xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(1).children(size(xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(1).children , 1)).content = valueWithoutWhiteSpaces;
                                        
                                        
                                        //add information about input to label in dialog
                                        //labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(1).name + "_" + childrenComponent(i).children(1).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(1).children(k).content + ")";
                                        
                                        
                                    end
                                    
                                end
                                
                                
                            elseif optionals(valuesOutIndex - 1) == %f then
                                
                                messagebox("Any children element of non-optional element type: """ + childrenComponent(i).children(1).name + """ was not set!", "modal", "error");
                                return;
                                
                            end
                            
                            
                            
                        //otherwise, the component is not "kinematic" (doesn't have sub-sub children)
                        else
                            
                            
                            for k = 1 : 1 : length(childrenComponent(i).children)
                                
                                //<>debug only
                                //disp("more children");
                                //disp(childrenComponent(i).children(k).name);
                                //disp(childrenComponent(i).children(k).content);
                                
                                //process element and add it from XML template and input values to content of the XML element
                                valueWithoutWhiteSpaces = strsubst(valuesOut(valuesOutIndex), " ", "");
                                
                                //if the element contains any string, add it
                                if valueWithoutWhiteSpaces ~= "" then
                                    
                                    //create new child element in root element when it was not already created or it can be created multiple times and this is not the first iteration
                                    if mainElementWasCreatedAlready == %f then
                                        
                                        xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                        mainElementWasCreatedAlready = %t;
                                        
                                    end
                                    
                                    //add sub element to main XML element
                                    xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), xmlElement(xmlComponentOut, childrenComponent(i).children(k).name));
                                    
                                    //add input value from dialog to content of the XML element
                                    xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(length(xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children)).content = valueWithoutWhiteSpaces;
                                    
                                    
                                elseif optionals(valuesOutIndex) == %f then
                                    
                                    messagebox("Sub element: """ + childrenComponent(i).children(k).name + """ of non-optional element type: """ + childrenComponent(i).name + """ was not set!", "modal", "error");
                                    return;
                                    
                                end
                                
                                valuesOutIndex = valuesOutIndex + 1;
                                
                                
                                //add information about input to label in dialog
                                //labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(k).content + ")";
                            
                            
                            end
                            
                            
                        end
                        
                        
                    end
                    
                    
                end
                
                
                
                
                //if component contains table element (for scheduled_gain only)
                if containsTableElement == %t then
                    
                    //show table dialog with default values
                    global defaultTableString;
                    [tableStringMatrices, tableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable] = DialogTableOkCancel(list(defaultTableString), emptystr(), emptystr(), emptystr(), emptystr(), propertiesAvailable);
                    
                    //if there is any output
                    if tableStringMatrices ~= [] & tableStringMatrices ~= list() then
                        
                        //encode string data from dialog to XML table
                        outXMLTable = EncodeXMLTable(tableStringMatrices, tableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable);
                        //if there is no error
                        if outXMLTable ~= [] then
                            //add XML table to current created component
                            xmlAppend(xmlComponentOut.root, outXMLTable.root);
                        else
                            messagebox(["Table was not set properly!" ; "row property: """ + outPropertyRow + """" ; "column property: """ + outPropertyColumn + """" ; "table property: " + outPropertyTable + """" ; "Table Titles: " ; tableTitleArray ; "Table Data: " ; tableStringMatrices ], "modal", "error");
                        end
                        
                        
                    else
                        
                        //otherwise, cancel was clicked (or some error occured?)
                        return;
                        
                    end
                    
                    
                end
                
                
                
                
                //add element name (attribute "name") of the component to propertiesAvailable
                name = xmlComponentOut.root.attributes.name;
                propertiesAvailable(size(propertiesAvailable, 1) + 1) = name;
                
                //add XML element (a component) to global selected channel
                xmlChannelSelected.children(length(xmlChannelSelected.children) + 1) = xmlComponentOut;
                
                //call callback for Channels to refresh list of used components
                Channels_callback(handles);
                
                
            end
            
            
            
            
        //check whether it is 'property' element
        //and decode the loaded component template
        elseif xmlComponent.root.name == "property"
            
            
            //debug only
            //disp('xmlComponent is property');
            
            rootComponent = xmlComponent.root;
            
            //get attribute names and values
            //xmlName function retrieve the name of the elements/attributes
            labels = xmlName(rootComponent.attributes);
            labels(1, size(labels, 2) + 1) = "name*";    //add name label with asterisk; i.e. '*' because it is required (for property and similar components only)
            values = [];
            for i = 1 : 1 : length(rootComponent.attributes)
                //add empty strings to text boxes in dialog
                values(1, size(values, 2) + 1) = emptystr();
                //add information about input to label in dialog
                labels(i) = labels(i) + " (" + rootComponent.attributes(i) + ")";
            end
            values(1, size(values, 1) + 1) = rootComponent.content;    //add name from content (for property and similar components only)
            
            
            //show mDialog for editation of component attributes/properties (add labels and textBox elements with default values into dialog)
            valuesOut = x_mdialog(['Component: ' + rootComponent.name ; "(* means required)" ; "(; means repeatable - separated by semicolon)"], labels, values);
            
            
            //if cancel button was not clicked
            if valuesOut ~= [] then
                
                global propertiesAvailable;
                
                //check if all inputs were set properly
                inputsSetPropery = [];
                for i = 1 : 1 : length(rootComponent.attributes)
                   inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), rootComponent.attributes(i), propertiesAvailable, %t, %f);
                end
                
                
                while strsubst(valuesOut(size(valuesOut, 1)), " ", "") == "" | part(strsubst(valuesOut(size(valuesOut, 1)), " ", ""), 1) == "-" | strindex(valuesOut(size(valuesOut, 1)), ";") ~= [] | FindPropertyInPropertiesAvailable(strsubst(valuesOut(size(valuesOut, 1)), " ", ""), propertiesAvailable) | and(inputsSetPropery) == %f
                    
                    //show mDialog again because error occurs -> Required fields are empty, set incorrectly (e.g. must be number) or the name identifier of the component is already used!
                    valuesOut = x_mdialog(['Component: ' + rootComponent.name ; "(* means required)" ; "(; means repeatable - separated by semicolon)" ; "Required fields are empty, fields are set incorrectly (e.g. must be number or has to be in property list), or the name identifier of the component is already used!"], labels, valuesOut');
                    
                    if valuesOut == [] then
                        return;
                    end
                    
                    //check if all inputs were set properly
                    inputsSetPropery = [];
                    for i = 1 : 1 : length(rootComponent.attributes)
                        inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), rootComponent.attributes(i), propertiesAvailable, %t, %f);
                    end
                    
                end
                
                
                
                //set values from dialog to not required atributtes
                attributesNames = xmlName(rootComponent.attributes);
                for i = 1 : 1 : length(rootComponent.attributes)
                    //if attribute was used, copy it with value
                    if strsubst(valuesOut(i), " ", "") ~= "" then
                        xmlSetAttributes(xmlComponentOut.root.attributes, [attributesNames(i) strsubst(valuesOut(i), " ", "")]);
                    end
                end
                //set property name from dialog to content
                xmlComponentOut.root.content = strsubst(valuesOut(size(valuesOut, 1)), " ", "");
                
                
                
                //add property name (content) of the property to propertiesAvailable
                name = xmlComponentOut.root.content;
                propertiesAvailable(size(propertiesAvailable, 1) + 1) = name;
                
                //add XML element (property) to global selected channel
                xmlChannelSelected.children(length(xmlChannelSelected.children) + 1) = xmlComponentOut;
                
                //call callback for Channels to refresh list of used components
                Channels_callback(handles);
                
                
            end
            
            
        end
        
        
        CheckAndDeleteXMLDoc(xmlComponent);
        
        
    end
    
    
    
endfunction










function EditComponentsUsed_callback(handles)
//Write your callback for  EditComponentsUsed  here
    
    
    
    //load a component template from a proper XML file in the folder: "templates\Components" depending on the selection
    //if there are used components and a channel is selected (is not 0 (none))
    global xmlChannelSelected;
    //disp(xmlChannelSelected);
    //disp(typeof(xmlChannelSelected));
    if handles.ComponentsUsed.Value > 0 & typeof(xmlChannelSelected) == "XMLElem" then
        
        //disp('xmlChannelSelected is XMLElem type');
        
        stringSelected = handles.ComponentsUsed.String(handles.ComponentsUsed.Value);


        
        
        //decode the component type from the string
        indexesSymbolOfTypeBeginning=strindex(stringSelected, '<');
        indexesSymbolOfTypeEnd=strindex(stringSelected, '>');
        stringSelectedXMLType=part(stringSelected, indexesSymbolOfTypeBeginning(1)+1:indexesSymbolOfTypeEnd(1)-1);
        
        //decode the name (actually the name attribute) of the used component
        indexesSymbolOfNameBeginning=strindex(stringSelected, '> ');
        stringSelectedXMLName=part(stringSelected, indexesSymbolOfNameBeginning(1)+2:length(stringSelected));
        
        
        //read xml file with the specific component template definition
        xmlComponent = xmlRead("templates" + filesep() + "Components" + filesep() + "" + stringSelectedXMLType + ".xml");
        errorString=ValidateXMLdocument(xmlComponent);
        //disp("templates\Components\" + stringSelected + ".xml");
        
        //read xml file with the specific empty component definition (without attributes and elements)
        xmlComponentOut = xmlRead("templates" + filesep() + "Components_withoutAttributes" + filesep() + "" + stringSelectedXMLType + ".xml");
        errorString=ValidateXMLdocument(xmlComponentOut);
        
        
        //find index of the selected XML element in the selected channel
        xmlElementIndexSelected=FindXMLElementIndexInFirstChildrenOfXMLElement(xmlChannelSelected, stringSelectedXMLType, stringSelectedXMLName);
        if xmlElementIndexSelected == 0 then
            messagebox("Selected component was not found!", "modal", "error");
            return;
        end
        //<>debug only
        //disp("XML element index of the selected component is: " + string(xmlElementIndexSelected));
        
        
        //check whether it is not 'property' or 'comment' element
        //and decode the loaded component template and get values from XML element component
        if xmlComponent.root.name ~= "property" & xmlComponent.root.name ~= "comment" & xmlComponent.root.name ~= "documentation" then
            
            //<>debug only
            //disp('xmlComponent is NOT property, comment or documentation');
            //disp("          """ + xmlComponent.root.name + """          ");
            
            
            rootComponent = xmlComponent.root;
            labels = ["name*"];    //add name label with asterisk; i.e. '*' because it is required
            values = [xmlChannelSelected.children(xmlElementIndexSelected).attributes.name];   //add name from name attribute
            possibleInputTypesList = [""];
            optionals = [%f];    //add optional/required information
            canRepeats = [%f];    //add information whether the element can repeat
            contentCanRepeats = [%f];    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
            canIncludeTestss = [%f];    //add information whether the content of the element can include tests (<>only for test (in switch))
            
            testValueIndexInDialog = 0;
            testTestIndexInDialog = 0;
            
            
            //set default values for table (scheduled_gain component only)
            global defaultTableString;
            tableStringMatrices = list(defaultTableString);
            tableTitleArray = emptystr();
            tablePropertyRow = emptystr();
            tablePropertyColumn = emptystr();
            tablePropertyTable = emptystr();
            containsTableElement = %f;
            
            
            //get children names, attributes and values
            childrenComponent = rootComponent.children;
            for i = 1 : 1 : length(childrenComponent)
                
                //if the element is comment, ignore it and continue at the beginning of this for cycle
                if childrenComponent(i).name == "comment" then
                    continue;
                end
                
                
                //check all information attributes and process them
                attributeNames = xmlName(childrenComponent(i).attributes);
                [optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).attributes);
                
                
                //check all attributes and if they are not those specific predefined, add them
                for j = 1 : 1 : length(childrenComponent(i).attributes)
                    
                    if attributeNames(j) ~= "optional" & attributeNames(j) ~= "canrepeat" & attributeNames(j) ~= "contentcanrepeat" & attributeNames(j) ~= "canincludetests" then
                        
                        //<>debug only
                        //disp("only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes");
                        
                        //get index of value attribute in dialog (for test element in switch component only)
                        if childrenComponent(i).name == "test" & attributeNames(j) == "value" then
                            testValueIndexInDialog = size(values, 2) + 1;
                        end
                        
                        //process attribute and add it to labels and values (only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes)
                        //get values to text boxes in dialog
                        values(1, size(values, 2) + 1) = GetXMLValueOrAttribute(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name, attributeNames(j));
                        //values(1, size(values, 2) + 1) = SetIDinValue(childrenComponent(i).attributes(j));
                        //add information about input to label in dialog (the magic word "<attribute>" defines that the value has to be put in attributes, not in children of the element)
                        labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + attributeTag + "_" + attributeNames(j) + asterisk + semicolon + " (" + childrenComponent(i).attributes(j) + ")";
                        possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).attributes(j);
                        
                        //add all information attributes
                        optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                        canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat -> note: XML attributes cannot repeat, i.e. %f
                        contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch)) -> note: XML attributes don't have any content to repeat, i.e. %f
                        canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch)) -> note: XML attributes cannot include tests, i.e. %f
                        
                        
                    end
                    
                end
                
                

                //if the element has only one child (text), add it to labels and values
                if length(childrenComponent(i).children) == 1 & childrenComponent(i).children(1).name == "text" then
                    
                    //<>debug only
                    //disp("one child");
                    //disp(childrenComponent(i).name);
                    //disp(childrenComponent(i).content);
                    
                    //if the element is NOT table (only scheduled_gain component contains table element)
                    if childrenComponent(i).name ~= "table" then
                        
                        //set default string value
                        stringWithValue = emptystr();
                        //if the element is function (only fcs_function component contains function element)
                        if childrenComponent(i).name == "function" then
                            
                            //find function element with data in loaded XML component
                            xmlElementIndex = FindXMLElementIndexesInFirstChildrenOfXMLElement(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name);
                            //if the element was found
                            if xmlElementIndex ~= [] then
                                //decode XML function element and convert it to string (note: there should be only one index found, i.e. one function element)
                                stringWithValue = XMLMathFuncToStringEquation(xmlChannelSelected.children(xmlElementIndexSelected).children(xmlElementIndex(1)));
                            end
                            
                            
                        //else if the element is test (only switch component contains test element)
                        elseif childrenComponent(i).name == "test" then
                            
                            //get index of test element in dialog
                            testTestIndexInDialog = size(values, 2) + 1;
                            
                            //find function element with data in loaded XML component
                            xmlElementIndexes = FindXMLElementIndexesInFirstChildrenOfXMLElement(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name);
                            //if the element was found
                            if xmlElementIndexes ~= [] then
                                //decode XML function element and convert it to string (note: there can be more than one index found, i.e. more than one test element)
                                //go through all indexes
                                for j = 1 : 1 : length(xmlElementIndexes)
                                    
                                    stringTest = XMLTestToStringEquation(xmlChannelSelected.children(xmlElementIndexSelected).children(xmlElementIndexes(j)), childrenComponent(i).name);
                                    if stringTest ~= emptystr() then
                                        stringWithValue = AddSemicolonWithTwoWhiteSpacesToNotEmptyString(stringWithValue);
                                        stringWithValue = stringWithValue + stringTest;
                                        //disp("Test function: " + stringWithValue);  //<>debug only
                                    end
                                    
                                end
                            end
                            
                            
                        else
                            stringWithValue = GetXMLValueOrAttribute(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name, "-<XMLContentText>");
                        end
                        //disp(stringWithValue); //<>debug only
                        //add strings from content, attribute, or special decoded XML content to text boxes in dialog
                        values(1, size(values, 2) + 1) = stringWithValue;
                        //disp(childrenComponent(i).name + asterisk + semicolon + " (" + childrenComponent(i).content + ")"); //<>debug only
                        //add information about input to label in dialog
                        labels(1, size(labels, 2) + 1) = childrenComponent(i).name + asterisk + semicolon + " (" + childrenComponent(i).content + ")";
                        possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).content;
                        
                        //add all information attributes
                        optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                        canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
                        contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
                        canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                        
                        
                    //otherwise, XML element is table, so decode the data
                    else
                        
                        xmlElementIndex = FindXMLElementIndexesInFirstChildrenOfXMLElement(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name);
                        //if the element was found
                        if xmlElementIndex ~= [] then
                            
                            containsTableElement = %t;
                            
                            //get table XML element - there should be only and exactly one table
                            tableXMLElement = xmlChannelSelected.children(xmlElementIndexSelected).children(xmlElementIndex(1));
                            //decode data from table XML element
                            [tableStringMatrices, tableTitleArray, tablePropertyRow, tablePropertyColumn, tablePropertyTable] = DecodeXMLTable(tableXMLElement);


                            
                            
                            //if there is no main output
                            if tableStringMatrices == [] | tableStringMatrices == list() | tablePropertyRow == emptystr() then
                                
                                messagebox(["Table was not loaded properly!" ; "row property: """ + tablePropertyRow + """" ; "column property: """ + tablePropertyColumn + """" ; "table property: " + tablePropertyTable + """" ; "Table Titles: " ; tableTitleArray ; "Table Data: " ; tableStringMatrices ], "modal", "error");
                                return;
                                
                            end
                            
                        end
                        
                    end
                    
                    
                //else if the element has more children elements (e.g. clipto), add them to labels and values
                elseif length(childrenComponent(i).children) > 0 then
                    
                    //<>debug only
                    //disp(childrenComponent(i).name);
                    
                    //if the first child has not-text children (for kinematic only)
                    if length(childrenComponent(i).children(1).children) > 0 & childrenComponent(i).children(1).children(1).name ~= "text" then
                        
                        //check all information attributes and process them
                        attributeNames = xmlName(childrenComponent(i).children(1).attributes);
                        [optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).children(1).attributes);
                        
                        //got through children of first child of component's children :-)


                        for k = 1 : 1 : length(childrenComponent(i).children(1).children)
                            
                            //<>debug only
                            //disp("more than more (sub)children");
                            //disp(childrenComponent(i).children(1).children(k).name);
                            //disp(childrenComponent(i).children(1).children(k).content);
                            
                            //add default strings to text boxes in dialog
                            values(1, size(values, 2) + 1) = GetXMLValueOrAttribute(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name, childrenComponent(i).children(1).children(k).name);
                            //add information about input to label in dialog
                            labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(1).name + "_" + childrenComponent(i).children(1).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(1).children(k).content + ")";
                            possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).children(1).children(k).content;
                            
                            //add all information attributes
                            optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                            canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
                            contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
                            canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                            
                            
                        end
                        
                        
                    else
                        
                        for k = 1 : 1 : length(childrenComponent(i).children)
                            
                            //<>debug only
                            //disp("more children");
                            //disp(childrenComponent(i).children(k).name);
                            //disp(childrenComponent(i).children(k).content);
                            
                            //add default strings to text boxes in dialog
                            values(1, size(values, 2) + 1) = GetXMLValueOrAttribute(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name, childrenComponent(i).children(k).name);
                            //add information about input to label in dialog
                            labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(k).content + ")";
                            possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).children(k).content;
                            
                            ////<>debug only
                            //disp([labels(1, size(labels, 2)) + "  """ + values(1, size(values, 2)) + """" ; ]);
                            
                            //add all information attributes
                            optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
                            canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
                            contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
                            canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                            
                            
                        end
                        
                        
                    end
                    
                    
                //probably only for switch
                //because the code for attribute decoding is above, the following code is redundant
//                else
//                    
//                    //<>debug only
//                    //disp("no child");
//                    //disp(childrenComponent(i).name);
//                    //disp(childrenComponent(i).attributes.value);    //for switch only
//                    
//                    //add default strings to text boxes in dialog
//                    values(1, size(values, 2) + 1) = SetIDinValue(childrenComponent(i).attributes.value);
//                    //add information about input to label in dialog
//                    labels(1, size(labels, 2) + 1) = childrenComponent(i).name + asterisk + semicolon + " (" + childrenComponent(i).attributes.value + ")";
//                    possibleInputTypesList(1, size(possibleInputTypesList, 2) + 1) = childrenComponent(i).attributes.value;
//                    
//                    //add all information attributes
//                    optionals(1, size(optionals, 2) + 1) = optional;    //add optional/required information
//                    canRepeats(1, size(canRepeats, 2) + 1) = canRep;    //add information whether the element can repeat
//                    contentCanRepeats(1, size(contentCanRepeats, 2) + 1) = contentCanRep;    //add information whether the content of the element can repeat (<>only for table (in scheduled_gain) and test (in switch))
//                    canIncludeTestss(1, size(canIncludeTestss, 2) + 1) = canInclTest;    //add information whether the content of the element can include tests (<>only for test (in switch))
                    
                    
                end
                
                
            end
            
            
            
            
            //add text with a function of a filter when needed
            filterFunctionText = GetFilterFunctionText(rootComponent.name);

            //show mDialog for editation of component attributes/properties (add labels and textBox elements with default values into dialog)
            valuesOut = x_mdialog(['Component: ' + rootComponent.name + filterFunctionText ; "(* means required)" ; "(; means repeatable - separated by semicolon)"], labels, values);
            
            
            //if cancel button was not clicked
            if valuesOut ~= [] then
                
                global propertiesAvailable;
                
                //check if all inputs were set properly
                inputsSetPropery = [];
                for i = 2 : 1 : size(possibleInputTypesList, 2)
                    inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), possibleInputTypesList(i), propertiesAvailable, optionals(i), canRepeats(i));
                end
                //check number of output test values and number of tests if necessary
                testError = emptystr();
                if testValueIndexInDialog > 0 & testTestIndexInDialog > 0 then
                    inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckTestNValuesNTests(valuesOut(testValueIndexInDialog), valuesOut(testTestIndexInDialog));
                    if inputsSetPropery(size(inputsSetPropery, 1)) == %f then
                        testError = "The number of values are not same as number of tests!";
                    else
                        testError = emptystr();
                    end
                end
                
                
                while strsubst(valuesOut(1), " ", "") == "" | part(strsubst(valuesOut(1), " ", ""), 1) == "-" | strindex(valuesOut(1), ";") ~= [] | (FindPropertyInPropertiesAvailable(strsubst(valuesOut(1), " ", ""), propertiesAvailable) & strsubst(valuesOut(1), " ", "") ~= xmlChannelSelected.children(xmlElementIndexSelected).attributes.name) | and(inputsSetPropery) == %f
                    
                    
                    //show mDialog again because error occurs -> Required fields are empty, set incorrectly (e.g. must be number) or the name identifier of the component is already used!
                    valuesOut = x_mdialog(['Component: ' + rootComponent.name + filterFunctionText ; "(* means required)" ; "(; means repeatable - separated by semicolon)" ; "Required fields are empty, fields are set incorrectly (e.g. must be number or has to be in property list), or the name identifier of the component is already used!" ; testError], labels, valuesOut');
                    
                    
                    if valuesOut == [] then
                        return;
                    end
                    
                    //check if all inputs were set properly
                    inputsSetPropery = [];
                    for i = 2 : 1 : size(possibleInputTypesList, 2)
                        inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), possibleInputTypesList(i), propertiesAvailable, optionals(i), canRepeats(i));
                    end
                    //disp(string(testValueIndexInDialog) + " " + string(testTestIndexInDialog)); //debug only
                    //check number of output test values and number of tests if necessary
                    testError = emptystr();
                    if testValueIndexInDialog > 0 & testTestIndexInDialog > 0 then
                        inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckTestNValuesNTests(valuesOut(testValueIndexInDialog), valuesOut(testTestIndexInDialog));
                        if inputsSetPropery(size(inputsSetPropery, 1)) == %f then
                            testError = "The number of values are not same as number of tests!";
                        else
                            testError = emptystr();
                        end
                    end
                    
                    
                end
                
                
                
                
                //add elements and values to the XML component and insert it to the selected channel
                //set component name from dialog to name attribute
                xmlComponentOut.root.attributes.name = strsubst(valuesOut(1), " ", "");
                
                
                valuesOutIndex = 2;
                //almost same code as in the generation of the dialog above
                for i = 1 : 1 : length(childrenComponent)
                    
                    
                    //if the element is comment, ignore it and continue at the beginning of this for cycle
                    if childrenComponent(i).name == "comment" then
                        //add comment to output XML element and continue in loop
                        xmlAppend(xmlComponentOut.root, childrenComponent(i));
                        continue;
                    end
                    
                    //tells whether main element was already created (if this element is optional, and the attributes and sub-elements are empty, the main element will not be created)
                    mainElementWasCreatedAlready = %f;
                    
                    
                    //check all information attributes and process them
                    attributeNames = xmlName(childrenComponent(i).attributes);
                    //[optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).attributes);
                    //array for series of values in attribute (for test element only)
                    testAttributeValues = [];
                    
                    //check all attributes and if they are not those specific predefined, add them
                    for j = 1 : 1 : length(childrenComponent(i).attributes)
                        
                        if attributeNames(j) ~= "optional" & attributeNames(j) ~= "canrepeat" & attributeNames(j) ~= "contentcanrepeat" & attributeNames(j) ~= "canincludetests" then
                            
                            //<>debug only
                            //disp("only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes");
                            
                            //process attribute and add it from XML template and input values to XML element (only switch, sensor, and accelerometer (and subelements test and table) have active/adjustable attributes)
                            valueWithoutWhiteSpaces = strsubst(valuesOut(valuesOutIndex), " ", "");
                            //if the attribute contains any string, add it
                            if valueWithoutWhiteSpaces ~= "" then
                                
                                //if the element is test (only switch component contains test element)
                                if childrenComponent(i).name == "test" then
                                    //if the current attribute is "value"
                                    if attributeNames(j) == "value" then
                                        
                                        //get test values in attribute separated by semicolon
                                        testAttributeValues = tokens(valueWithoutWhiteSpaces, ";");
                                        
                                    else
                                        
                                        disp("The current attribute: """ + attributeNames(j) + """ of ""test"" element is not supported in code!");
                                        
                                    end
                                    
                                    
                                else
                                    
                                    //create new child element in root element when it was not already created
                                    if mainElementWasCreatedAlready == %f then
                                        
                                        xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                        mainElementWasCreatedAlready = %t;
                                        
                                    end
                                    
                                    
                                    //add attribute and input value from dialog to XML element
                                    xmlSetAttributes(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), [attributeNames(j) valueWithoutWhiteSpaces]);
                                    
                                    
                                end
                                
                                
                            elseif optionals(valuesOutIndex) == %f then
                                
                                messagebox("Non-optional attribute: """ + attributeNames(j) + """ of the element type: """ + childrenComponent(i).name + """ was not set!", "modal", "error");
                                return;
                                
                            end
                            
                            valuesOutIndex = valuesOutIndex + 1;
                            
                            
//                            //information about input in label of dialog ("<attribute>" defines that the value has to be put in attributes, not in children of the element)
//                            labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + attributeTag + "_" + attributeNames(j) + asterisk + semicolon + " (" + childrenComponent(i).attributes(j) + ")";
                            
                            
                        end
                        
                    end
                    
                    
                    
                    //if the element has only one child (text)
                    if length(childrenComponent(i).children) == 1 & childrenComponent(i).children(1).name == "text" then
                        
                        //<>debug only
                        //disp("one child");
                        //disp(childrenComponent(i).name);
                        //disp(childrenComponent(i).content);
                        
                        //if the element is NOT table (only scheduled_gain component contains table element)
                        if childrenComponent(i).name ~= "table" then
                            
                            //if the input value is true or false in Scilab format, convert it to the JSBSim format
                            if valuesOut(valuesOutIndex) == "%t" | valuesOut(valuesOutIndex) == "%f" then// valuesOut(valuesOutIndex) == %t | valuesOut(valuesOutIndex) == %f then
                                
                                valuesOut(valuesOutIndex) = ConvertBooleanStringToTrueFalseString(valuesOut(valuesOutIndex));
                                
                            end
                            
                            //process element and add it from XML template and input values to content of the XML element
                            valueWithoutWhiteSpaces = valuesOut(valuesOutIndex);
                            if childrenComponent(i).name ~= "test" then
                                valueWithoutWhiteSpaces = strsubst(valueWithoutWhiteSpaces, " ", "");
                            end
                            if canRepeats(valuesOutIndex) == %t then
                                valueWithoutWhiteSpaces = tokens(valueWithoutWhiteSpaces, ";");
                            end
                            
                            
                            //if the element contains any string, add it
                            if valueWithoutWhiteSpaces ~= [] & valueWithoutWhiteSpaces ~= "" then
                                
                                
                                //if the element is function (only fcs_function component contains function element)
                                if childrenComponent(i).name == "function" then
                                    
                                    
                                    //create new child element in root element when it was not already created //or it can be created multiple times and this is not the first iteration
                                    if mainElementWasCreatedAlready == %f then //| (canRepeats(valuesOutIndex) == %t & j > 1) then
                                        
                                        xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                        mainElementWasCreatedAlready = %t;
                                        
                                    end
                                    
                                    
                                    
                                    //find the table tag in function if any
                                    tableTag = "table";
                                    outXMLTableElementsList = list();
                                    //get all table tag strings from string equation if any
                                    tableStringsList = GetTableStringsFromStringEquation(valueWithoutWhiteSpaces, tableTag);
                                    //if any table tag was found, process it
                                    if length(tableStringsList) > 0 then
                                        
                                        //find function element with data in loaded XML component (note: there should be only one index found, i.e. one function element)
                                        xmlElementIndex = FindXMLElementIndexesInFirstChildrenOfXMLElement(xmlChannelSelected.children(xmlElementIndexSelected), childrenComponent(i).name);
                                        //if the element was found (it should be found)
                                        tableXMLElementsList = list();
                                        if xmlElementIndex ~= [] then
                                            //get all tables from XML function element 
                                            tableXMLElementsList = GetTablesFromXMLFunctionElement(xmlChannelSelected.children(xmlElementIndexSelected).children(xmlElementIndex(1)));
                                        end
                                        
                                        
                                        //decode or create default data from table XML elements
                                        [tableStringsMatricesList, tableTitleArraysList, tablePropertyRowsList, tablePropertyColumnsList, tablesPropertyTableList] = DecodeOrCreateXMLTables(tableXMLElementsList, tableStringsList, emptystr());
                                        
                                        
                                        //if all lists have same length, everything is OK
                                        if length(tableStringsList) == length(tableStringsMatricesList) & length(tableStringsList) == length(tableTitleArraysList) & length(tableStringsList) == length(tablePropertyRowsList) & length(tableStringsList) == length(tablePropertyColumnsList) & length(tableStringsList) == length(tablesPropertyTableList) then
                                            
                                            //show table dialogs for all table strings in list with decoded or defaultly created structures
                                            for x = 1 : 1 : length(tableStringsList)
                                                
                                                
                                                //show table dialog with decoded values
                                                [outTableStringMatrices, outTableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable] = DialogTableOkCancel(tableStringsMatricesList(x), tableTitleArraysList(x), tablePropertyRowsList(x), tablePropertyColumnsList(x), tablesPropertyTableList(x), propertiesAvailable);
                                                
                                                //if there is any output
                                                if outTableStringMatrices ~= [] & outTableStringMatrices ~= list() then
                                                    
                                                    //encode string data from dialog to XML table
                                                    outXMLTable = EncodeXMLTable(outTableStringMatrices, outTableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable);
                                                    //if there is no error
                                                    if outXMLTable ~= [] then
                                                        
                                                        //add table element to the list of XML table elements
                                                        outXMLTableElementsList($+1) = outXMLTable;
                                                        
                                                    else
                                                        messagebox(["Table no. " + string(x) + " was not set properly!" ; "row property: """ + outPropertyRow + """" ; "column property: """ + outPropertyColumn + """" ; "table property: " + outPropertyTable + """" ], "modal", "error");  // ; "Table Titles: " ; outTableTitleArray ; "Table Data: " ; outTableStringMatrices
                                                    end
                                                    
                                                    
                                                else
                                                    
                                                    //otherwise, cancel was clicked (or some error occured?)
                                                    return;
                                                    
                                                end
                                                
                                                
                                            end
                                            
                                        else
                                            
                                            messagebox(["Tables were not loaded properly!" ; "The number of proposed tables is not equal to the number of decoded/created tables" ; "rows properties: """ + tablePropertyRowsList + """" ; "columns properties: """ + tablePropertyColumnsList + """" ; "tables properties: " + tablesPropertyTableList + """" ; "Tables Titles: " ; tableTitleArraysList ; "Tables Data: " ; tableStringsMatricesList ; ], "modal", "error");
                                            return;
                                            
                                        end
                                        
                                        
                                    end
//                                    //<>debug only
//                                    for x = 1 : 1 : length(outXMLTableElementsList)
//                                        disp([ typeof(outXMLTableElementsList(x)) ; outXMLTableElementsList(x).root.name ; outXMLTableElementsList(x)]);
//                                    end
                                    
                                    
                                    
                                    //convert string to XML function element
                                    XMLMathFunctionsElement = StringEquationToXMLMathFunc(valueWithoutWhiteSpaces, propertiesAvailable, outXMLTableElementsList);
                                    //check if conversion was successful
                                    if XMLMathFunctionsElement ~= [] then
                                        
                                        //add new XML function element child to the output XML function element
                                        xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), XMLMathFunctionsElement.root.children(1));
                                        
                                    else
                                        
                                        messagebox(["Function was not converted properly!" ; "Name of Element: """ + childrenComponent(i).name + """" ; "(Wrong) Element Value: """ + valueWithoutWhiteSpaces + """"], "modal", "error");
                                        return;
                                        
                                    end
                                    
                                    
                                    
                                //else if the element is test (only switch component contains test element)
                                elseif childrenComponent(i).name == "test" then
                                    
                                    //get value with white spaces
                                    valueOriginal = valuesOut(valuesOutIndex);
                                    if canRepeats(valuesOutIndex) == %t then
                                        valueOriginal = tokens(valuesOut(valuesOutIndex), ";");
                                    end
                                    
                                    if size(testAttributeValues, 1) == size(valueOriginal, 1) then
                                        
                                        for j = 1 : 1 : size(valueOriginal, 1)
                                            
                                            
                                            //convert string to XML test element
                                            XMLTestElement = StringEquationToXMLTest(valueOriginal(j), childrenComponent(i).name, propertiesAvailable);
                                            //check if conversion was successful
                                            if XMLTestElement ~= [] then
                                                
                                                //add value in attribute from dialog to XML element
                                                xmlSetAttributes(XMLTestElement.root, ["value" testAttributeValues(j)]);
                                                //add new XML test element to the output XML switch component
                                                xmlAppend(xmlComponentOut.root, XMLTestElement.root);
                                                
                                                //just for sure, it has probably no other meaning here
                                                mainElementWasCreatedAlready = %t;
                                                
                                                
                                            else
                                                
                                                messagebox(["Test was not converted properly!" ; "Number of Test: " + string(j) ; "(Wrong) Element Value: """ + valueOriginal(j) + """"], "modal", "error");
                                                return;
                                                
                                            end
                                            
                                            
                                        end
                                        
                                    else
                                        
                                        messagebox("The number of output test values (" + string(size(testAttributeValues, 1)) + ") is different from the number of tests: (" + string(size(valueOriginal, 1)) + ")!", "modal", "error");
                                        return;
                                        
                                    end
                                    
                                    
                                    
                                else
                                    
                                    
                                    for j = 1 : 1 : size(valueWithoutWhiteSpaces, 1)
                                        
                                        //create new child element in root element when it was not already created or it can be created multiple times and this is not the first iteration
                                        if mainElementWasCreatedAlready == %f | (canRepeats(valuesOutIndex) == %t & j > 1) then
                                            
                                            xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));

                                            mainElementWasCreatedAlready = %t;
                                            
                                        end
                                        
                                        //add input value from dialog to content of the XML element
                                        xmlComponentOut.root.children(length(xmlComponentOut.root.children)).content = valueWithoutWhiteSpaces(j);
                                        
                                    end
                                    
                                    
                                end
                                
                                
                                
                            elseif optionals(valuesOutIndex) == %f then
                                
                                messagebox("Non-optional element type: """ + childrenComponent(i).name + """ was not set!", "modal", "error");
                                return;
                                
                            end
                            
                            valuesOutIndex = valuesOutIndex + 1;
                            
                            
                        end
                        
                        
                        
                    //else if the element has more children elements (e.g. clipto)
                    elseif length(childrenComponent(i).children) > 0 then
                        
                        //<>debug only
                        //disp(childrenComponent(i).name);
                        
                        
                        //if the first child has not-text children (for kinematic only)
                        if length(childrenComponent(i).children(1).children) > 0 & childrenComponent(i).children(1).children(1).name ~= "text" then
                            
                            //check all information attributes and process them
                            //attributeNames = xmlName(childrenComponent(i).children(1).attributes);
                            //[optional, asterisk, canRep, semicolon, contentCanRep, canInclTest] = GetInformationAttributes(attributeNames, childrenComponent(i).children(1).attributes);
                            
                            multiChildrenValues = list();
                            //got through children of first child of component's children :-)
                            for k = 1 : 1 : length(childrenComponent(i).children(1).children)
                                
                                //<>debug only
                                //disp("more than more (sub)children");
                                //disp(childrenComponent(i).children(1).children(k).name);
                                //disp(childrenComponent(i).children(1).children(k).content);
                                
                                
                                //process element
                                valueWithoutWhiteSpaces = strsubst(valuesOut(valuesOutIndex), " ", "");
                                if canRepeats(valuesOutIndex) == %t then
                                    
                                    valueWithoutWhiteSpaces = tokens(valueWithoutWhiteSpaces, ";");
                                    
                                end
                                
                                

                                //if the element contains any string, add it
                                if valueWithoutWhiteSpaces ~= [] & valueWithoutWhiteSpaces ~= "" then
                                    
                                    multiChildrenValues(0) = valueWithoutWhiteSpaces;
                                    
                                elseif optionals(valuesOutIndex) == %f then
                                    
                                    messagebox("Non-optional element type: """ + childrenComponent(i).children(1).children(k).name + """ was not set!", "modal", "error");
                                    return;
                                    
                                end
                                
                                //if there are more than one sub element
                                if length(multiChildrenValues) > 1 then
                                    
                                    //if the last two lists don't have same size
                                    if size(multiChildrenValues(length(multiChildrenValues) - 1), 1) ~= size(multiChildrenValues(length(multiChildrenValues)), 1) then
                                        
                                        messagebox("Element type: """ + childrenComponent(i).children(1).children(k-1).name + """ and element type: """ + childrenComponent(i).children(1).children(k).name + """ don"'t have same size!", "modal", "error");
                                        return;
                                        
                                    end
                                    
                                end
                                
                                valuesOutIndex = valuesOutIndex + 1;
                                
                            end
                            
                            
                            //add elements to output XML component
                            if length(multiChildrenValues) > 0 then
                                
                                for k = 1 : 1 : size(multiChildrenValues(1), 1)
                                    
                                    for j = 1 : 1 : size(multiChildrenValues, 1)
                                        
                                        valueWithoutWhiteSpaces = multiChildrenValues(j)(k);
                                        
                                        //create new child element in root element when it was not already created
                                        if mainElementWasCreatedAlready == %f then
                                            
                                            //add main XML element
                                            xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                            mainElementWasCreatedAlready = %t;
                                            
                                        end
                                        //for absolutely first iteration add subchild (i.e. there is only one subchild)
                                        if k == 1 & j == 1 then
                                            
                                            //add sub element to main XML element
                                            xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), xmlElement(xmlComponentOut, childrenComponent(i).children(1).name));

                                            
                                        end
                                        
                                        //add sub-sub element to sub element of main XML element :-)
                                        xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(1), xmlElement(xmlComponentOut, childrenComponent(i).children(1).children(j).name));
                                        
                                        //add an input value from dialog to content of the XML element
                                        xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(1).children(size(xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(1).children , 1)).content = valueWithoutWhiteSpaces;
                                        
                                        
                                        //add information about input to label in dialog
                                        //labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(1).name + "_" + childrenComponent(i).children(1).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(1).children(k).content + ")";
                                        
                                        
                                    end
                                    
                                end
                                
                                
                            elseif optionals(valuesOutIndex - 1) == %f then
                                
                                messagebox("Any children element of non-optional element type: """ + childrenComponent(i).children(1).name + """ was not set!", "modal", "error");
                                return;
                                
                            end
                            
                            
                            
                        //otherwise, the component is not "kinematic" (doesn't have sub-sub children)
                        else
                            
                            
                            for k = 1 : 1 : length(childrenComponent(i).children)
                                
                                //<>debug only
                                //disp("more children");
                                //disp(childrenComponent(i).children(k).name);
                                //disp(childrenComponent(i).children(k).content);
                                



                                //process element and add it from XML template and input values to content of the XML element
                                valueWithoutWhiteSpaces = strsubst(valuesOut(valuesOutIndex), " ", "");
                                
                                //if the element contains any string, add it
                                if valueWithoutWhiteSpaces ~= "" then
                                    
                                    //create new child element in root element when it was not already created or it can be created multiple times and this is not the first iteration
                                    if mainElementWasCreatedAlready == %f then
                                        
                                        xmlAppend(xmlComponentOut.root, xmlElement(xmlComponentOut, childrenComponent(i).name));
                                        mainElementWasCreatedAlready = %t;
                                        
                                    end
                                    
                                    //add sub element to main XML element

                                    xmlAppend(xmlComponentOut.root.children(length(xmlComponentOut.root.children)), xmlElement(xmlComponentOut, childrenComponent(i).children(k).name));
                                    
                                    //add input value from dialog to content of the XML element
                                    xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children(length(xmlComponentOut.root.children(length(xmlComponentOut.root.children)).children)).content = valueWithoutWhiteSpaces;
                                    
                                    
                                elseif optionals(valuesOutIndex) == %f then
                                    
                                    messagebox("Sub element: """ + childrenComponent(i).children(k).name + """ of non-optional element type: """ + childrenComponent(i).name + """ was not set!", "modal", "error");
                                    return;
                                    
                                end
                                
                                valuesOutIndex = valuesOutIndex + 1;
                                
                                
                                //add information about input to label in dialog
                                //labels(1, size(labels, 2) + 1) = childrenComponent(i).name + "_" + childrenComponent(i).children(k).name + asterisk + semicolon + " (" + childrenComponent(i).children(k).content + ")";
                            
                            
                            end
                            
                            
                        end
                        
                        
                    end
                    
                    
                end
                
                
                
                
                //if component contains table element (for scheduled_gain only)
                if containsTableElement == %t then
                    
                    //show table dialog with decoded values
                    [outTableStringMatrices, outTableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable] = DialogTableOkCancel(tableStringMatrices, tableTitleArray, tablePropertyRow, tablePropertyColumn, tablePropertyTable, propertiesAvailable);
                    
                    //if there is any output
                    if outTableStringMatrices ~= [] & outTableStringMatrices ~= list() then
                        
                        //encode string data from dialog to XML table
                        outXMLTable = EncodeXMLTable(outTableStringMatrices, outTableTitleArray, outPropertyRow, outPropertyColumn, outPropertyTable);
                        //if there is no error
                        if outXMLTable ~= [] then
                            //add XML table to output component
                            xmlAppend(xmlComponentOut.root, outXMLTable.root);
                        else
                            messagebox(["Table no. " + string(x) + " was not set properly!" ; "row property: """ + outPropertyRow + """" ; "column property: """ + outPropertyColumn + """" ; "table property: " + outPropertyTable + """" ], "modal", "error");  // ; "Table Titles: " ; outTableTitleArray ; "Table Data: " ; outTableStringMatrices
                        end
                        
                        
                    else
                        
                        //otherwise, cancel was clicked (or some error occured?)
                        return;
                        
                    end
                    
                    
                end
                
                
                
                


                //edit element name (attribute "name") of the component in propertiesAvailable
                indexOldNameInProperties = find(propertiesAvailable == xmlChannelSelected.children(xmlElementIndexSelected).attributes.name);
                propertiesAvailable(indexOldNameInProperties) = xmlComponentOut.root.attributes.name;
                
                //change XML element (a component) at specific index in global selected channel
                xmlChannelSelected.children(xmlElementIndexSelected) = xmlComponentOut;
                
                
                //call callback for Channels to refresh list of used components
                Channels_callback(handles);
                
                
            end
            
            
            
            
        //check whether it is 'property' element
        //and decode the loaded component template
        elseif xmlComponent.root.name == "property"
            
            
            //debug only
            //disp('xmlComponent is property');
            
            rootComponent = xmlComponent.root;
            
            //get attribute names and values
            //xmlName function retrieve the name of the elements/attributes
            labels = xmlName(rootComponent.attributes);
            labels(1, size(labels, 2) + 1) = "name*";    //add name label with asterisk; i.e. '*' because it is required (for property and similar components only)
            values = [];
            //add strings from attributes (if any) to text boxes in dialog
            for i = 1 : 1 : length(rootComponent.attributes)
                //evaluate the string expression to scilab code
                inputValue = evstr("xmlChannelSelected.children(xmlElementIndexSelected).attributes." + labels(i));
                //if evaluation of the string expression failed
                if inputValue == [] then
                    values(1, size(values, 2) + 1) = emptystr();    //attribute doesn't exist
                else
                    values(1, size(values, 2) + 1) = inputValue;    //attribute exists
                end
                //add information about input to label in dialog
                labels(i) = labels(i) + " (" + rootComponent.attributes(i) + ")";
            end
            values(1, size(values, 1) + 1) = xmlChannelSelected.children(xmlElementIndexSelected).content;    //add name from content (for property and similar components only)
            
            
            
            //show mDialog for editation of component attributes/properties (add labels and textBox elements with default values into dialog)
            valuesOut = x_mdialog(['Component: ' + rootComponent.name ; "(* means required)" ; "(; means repeatable - separated by semicolon)"], labels, values);
            
            

            //if cancel button was not clicked
            if valuesOut ~= [] then
                
                global propertiesAvailable;
                
                //check if all inputs were set properly
                inputsSetPropery = [];

                for i = 1 : 1 : length(rootComponent.attributes)
                   inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), rootComponent.attributes(i), propertiesAvailable, %t, %f);
                end
                
                
                while strsubst(valuesOut(size(valuesOut, 1)), " ", "") == "" | part(strsubst(valuesOut(size(valuesOut, 1)), " ", ""), 1) == "-" | strindex(valuesOut(size(valuesOut, 1)), ";") ~= [] | (FindPropertyInPropertiesAvailable(strsubst(valuesOut(size(valuesOut, 1)), " ", ""), propertiesAvailable) & strsubst(valuesOut(size(valuesOut, 1)), " ", "") ~= xmlChannelSelected.children(xmlElementIndexSelected).content) | and(inputsSetPropery) == %f
                    
                    //show mDialog again because error occurs -> Required fields are empty, set incorrectly (e.g. must be number) or the name identifier of the component is already used!
                    valuesOut = x_mdialog(['Component: ' + rootComponent.name ; "(* means required)" ; "(; means repeatable - separated by semicolon)" ; "Required fields are empty, fields are set incorrectly (e.g. must be number or has to be in property list), or the name identifier of the component is already used!"], labels, valuesOut');
                    
                    if valuesOut == [] then
                        return;
                    end
                    
                    //check if all inputs were set properly
                    inputsSetPropery = [];
                    for i = 1 : 1 : length(rootComponent.attributes)
                        inputsSetPropery(size(inputsSetPropery, 1) + 1) = CheckCorrectValuesType(valuesOut(i), rootComponent.attributes(i), propertiesAvailable, %t, %f);
                    end
                    
                end
                
                
                
                //set values from dialog to not required atributtes
                attributesNames = xmlName(rootComponent.attributes);
                for i = 1 : 1 : length(rootComponent.attributes)
                    //if attribute was used, copy it with value
                    if strsubst(valuesOut(i), " ", "") ~= "" then
                        xmlSetAttributes(xmlComponentOut.root.attributes, [attributesNames(i) strsubst(valuesOut(i), " ", "")]);
                    end
                end
                //set property name from dialog to content
                xmlComponentOut.root.content = strsubst(valuesOut(size(valuesOut, 1)), " ", "");
                
                
                
                //edit property name (content) of the property in propertiesAvailable
                indexOldNameInProperties = find(propertiesAvailable == xmlChannelSelected.children(xmlElementIndexSelected).content);
                propertiesAvailable(indexOldNameInProperties) = xmlComponentOut.root.content;
                
                //change XML element (property) at specific index in global selected channel
                xmlChannelSelected.children(xmlElementIndexSelected) = xmlComponentOut;
                
                
                //call callback for Channels to refresh list of used components
                Channels_callback(handles);
                
                
            end
            
            
        end
        
        
        CheckAndDeleteXMLDoc(xmlComponent);
        
        
    end
    
    
    
endfunction



function DelComponentsUsed_callback(handles)
//Write your callback for  DelComponentsUsed  here
    
    
    if handles.ComponentsUsed.Value > 0 then
        
        stringSelectedChannels = handles.Channels.String(handles.Channels.Value);
        stringSelectedComponentsUsed = handles.ComponentsUsed.String(handles.ComponentsUsed.Value);
        
        global xmlAutopilot;
        if xmlAutopilot.root.name == "autopilot" then
            
            //if there is a child and global tag was not selected
            if length(xmlAutopilot.root.children) > 0 & stringSelectedComponentsUsed ~= [] then
                
                if stringSelectedChannels ~= "<global>" then
                
                    children = xmlAutopilot.root.children;
                    for i = 1 : 1 : length(children)
                        
                        //find elements which have channel tag
                        if children.name(i) == "channel" then
                            
                            //find element with the selected name in channels
                            if children(i).attributes.name == stringSelectedChannels then
                                
                                if length(children(i).children) > 0 then
                                    
                                    childrenComponentsUsed = children(i).children;
                                    for j = 1 : 1 : length(childrenComponentsUsed)
                                        
                                        //edit the string in listbox to 'element name only' string
                                        stringSelectedCompUsedNameOnly = strncpy(stringSelectedComponentsUsed, length(stringSelectedComponentsUsed));
                                        
                                        if strindex(stringSelectedCompUsedNameOnly, "<" + childrenComponentsUsed(j).name + "> ") ~= [] then
                                            
                                            //replace type name of the XML element to empty string (i.e. delete the string with the XML type name)
                                            stringSelectedCompUsedNameOnly = strsubst(stringSelectedCompUsedNameOnly, "<" + childrenComponentsUsed.name(j) + "> ", "");
                                            
                                            //find element with the selected name in components
                                            if childrenComponentsUsed(j).attributes.name == stringSelectedCompUsedNameOnly then
                                                
                                                //delete channel from the XML
                                                xmlRemove(childrenComponentsUsed(j));
                                                
                                                
                                                //load and add properties
                                                global propertiesAvailable;
                                                propertiesAvailable = ReadInternalAndCustomProperties();
                                                //add properties from XML file to list with properties
                                                propertiesAvailable = AddPropertiesFromLoadedXMLToPropertiesAvailable(xmlAutopilot, propertiesAvailable);
                                                
                                                
                                                //delete data in listbox (ComponentsUsed)
                                                componentsUsedString = handles.ComponentsUsed.String;

                                                componentsUsedString(handles.ComponentsUsed.Value) = [];
                                                handles.ComponentsUsed.String = componentsUsedString;
                                                
                                                //draw controller using selected XML channel
                                                ImageControllerDrawing(xmlChannelSelected);
                                                
                                                break;
                                                
                                            end
                                        
                                        end
                                        
                                    end
                                
                                    break;
                                
                                end
                            
                            end
                        
                        end
                        
                    end
                    
                else
                    
                    children = xmlAutopilot.root.children;
                    for i = 1 : 1 : length(children)
                        
                        //find elements which doesn't have channel and comment tag
                        if children.name(i) ~= "channel" & children.name(i) ~= "comment" & children.name(i) ~= "documentation" then
                            
                            //edit the string in listbox to 'element name only' string
                            stringSelectedCompUsedNameOnly = strncpy(stringSelectedComponentsUsed, length(stringSelectedComponentsUsed));
                            
                            if strindex(stringSelectedCompUsedNameOnly, "<" + children.name(i) + "> ") ~= [] then
                                
                                //replace type name of the XML element to empty string  (i.e. delete the string with the XML type name)
                                stringSelectedCompUsedNameOnly = strsubst(stringSelectedCompUsedNameOnly, "<" + children.name(i) + "> ", "");
                                //if there is value number, delete it
                                //indexValue = strindex(stringSelectedCompUsedNameOnly,"   value:");
                                //if indexValue ~= [] then
                                //    stringSelectedCompUsedNameOnly = strncpy(stringSelectedCompUsedNameOnly, indexValue-1);
                                //end
                                
                                //find element with the selected name
                                if children(i).content == stringSelectedCompUsedNameOnly then
                                    
                                    //delete channel from the XML
                                    xmlRemove(children(i));
                                    
                                    
                                    //load and add properties
                                    global propertiesAvailable;
                                    propertiesAvailable = ReadInternalAndCustomProperties();

                                    //add properties from XML file to list with properties
                                    propertiesAvailable = AddPropertiesFromLoadedXMLToPropertiesAvailable(xmlAutopilot, propertiesAvailable);
                                    
                                    
                                    //delete data in listbox (ComponentsUsed)
                                    componentsUsedString = handles.ComponentsUsed.String;
                                    componentsUsedString(handles.ComponentsUsed.Value) = [];
                                    handles.ComponentsUsed.String = componentsUsedString;
                                    
                                    //draw controller using selected XML channel
                                    ImageControllerDrawing(xmlChannelSelected);
                                    
                                    break;
                                
                                end
                            
                            end
                            
                        end
                        
                    end
                    
                end
                
            end
            
        else
        
            messagebox("Wrong format! The XML file is not a valid autopilot file!", "modal", "error");
            
        end
    
    
    end
    
    
endfunction



function UPComponentsUsed_callback(handles)
    
    global xmlChannelSelected;
    //if there is some component above the selected
    if handles.ComponentsUsed.Value > 0 & handles.ComponentsUsed.Value - 1 > 0 & typeof(xmlChannelSelected) == "XMLElem" then
        
        
        //string of selected component
        stringSelected = handles.ComponentsUsed.String(handles.ComponentsUsed.Value);
        
        //decode the component type from the string
        indexesSymbolOfTypeBeginning=strindex(stringSelected, '<');
        indexesSymbolOfTypeEnd=strindex(stringSelected, '>');
        stringSelectedXMLType=part(stringSelected, indexesSymbolOfTypeBeginning(1)+1:indexesSymbolOfTypeEnd(1)-1);
        
        //decode the name (actually the name attribute) of the used component
        indexesSymbolOfNameBeginning=strindex(stringSelected, '> ');
        stringSelectedXMLName=part(stringSelected, indexesSymbolOfNameBeginning(1)+2:length(stringSelected));
        
        //find the selected element in the channel
        xmlElementIndexSelected = FindXMLElementIndexInFirstChildrenOfXMLElement(xmlChannelSelected, stringSelectedXMLType, stringSelectedXMLName);
        if xmlElementIndexSelected == 0 then
            messagebox("Selected component was not found!", "modal", "error");
            return;
        end
        
        
        
        //string of component above the selected
        stringSelectedAbove = handles.ComponentsUsed.String(handles.ComponentsUsed.Value-1);
        
        //decode the component type from the string
        indexesSymbolOfTypeBeginning=strindex(stringSelectedAbove, '<');
        indexesSymbolOfTypeEnd=strindex(stringSelectedAbove, '>');
        stringSelectedXMLTypeAbove=part(stringSelectedAbove, indexesSymbolOfTypeBeginning(1)+1:indexesSymbolOfTypeEnd(1)-1);
        
        //decode the name (actually the name attribute) of the used component
        indexesSymbolOfNameBeginning=strindex(stringSelectedAbove, '> ');
        stringSelectedXMLNameAbove=part(stringSelectedAbove, indexesSymbolOfNameBeginning(1)+2:length(stringSelectedAbove));
        
        //find the selected element in the channel
        xmlElementIndexSelectedAbove = FindXMLElementIndexInFirstChildrenOfXMLElement(xmlChannelSelected, stringSelectedXMLTypeAbove, stringSelectedXMLNameAbove);
        if xmlElementIndexSelectedAbove == 0 then
            messagebox("Component above selected was not found!", "modal", "error");
            return;
        end
        
        
        
        //switch the selected component with the component above
        componentSelectedString = xmlDump(xmlChannelSelected.children(xmlElementIndexSelected));
        docComponentSelected = xmlReadStr(componentSelectedString);
        componentSelected = docComponentSelected.root;
//        //<>debug only
//        disp(componentSelected);
//        disp(xmlDump(componentSelected));
        
        componentSelectedAboveString = xmlDump(xmlChannelSelected.children(xmlElementIndexSelectedAbove));
        docComponentSelectedAbove = xmlReadStr(componentSelectedAboveString);
        componentSelectedAbove = docComponentSelectedAbove.root;
//        //<>debug only
//        disp(componentSelectedAbove);
//        disp(xmlDump(componentSelectedAbove));
        
        xmlChannelSelected.children(xmlElementIndexSelected) = componentSelectedAbove;
        xmlChannelSelected.children(xmlElementIndexSelectedAbove) = componentSelected;
        
        
        
//        //change order of strings in ComponentsUsed handle
//        handles.ComponentsUsed.String(handles.ComponentsUsed.Value) = stringSelectedAbove;
//        handles.ComponentsUsed.String(handles.ComponentsUsed.Value-1) = stringSelected;
        
        //refresh channel but select the curent selected component after switch
        newSelectedValue = handles.ComponentsUsed.Value - 1;
        Channels_callback(handles);
        handles.ComponentsUsed.Value = newSelectedValue;
        //refresh the selected visual component in schema
        ComponentsUsed_callback(handles);
        
        
    end
    
endfunction



function DOWNComponentsUsed_callback(handles)
    
    global xmlChannelSelected;
    //if there is some component below the selected
    if handles.ComponentsUsed.Value > 0 & handles.ComponentsUsed.Value + 1 <= size(handles.ComponentsUsed.String, 2) & typeof(xmlChannelSelected) == "XMLElem" then
        
        
        //string of selected component
        stringSelected = handles.ComponentsUsed.String(handles.ComponentsUsed.Value);
        
        //decode the component type from the string
        indexesSymbolOfTypeBeginning=strindex(stringSelected, '<');
        indexesSymbolOfTypeEnd=strindex(stringSelected, '>');
        stringSelectedXMLType=part(stringSelected, indexesSymbolOfTypeBeginning(1)+1:indexesSymbolOfTypeEnd(1)-1);
        
        //decode the name (actually the name attribute) of the used component
        indexesSymbolOfNameBeginning=strindex(stringSelected, '> ');
        stringSelectedXMLName=part(stringSelected, indexesSymbolOfNameBeginning(1)+2:length(stringSelected));
        
        //find the selected element in the channel
        xmlElementIndexSelected = FindXMLElementIndexInFirstChildrenOfXMLElement(xmlChannelSelected, stringSelectedXMLType, stringSelectedXMLName);
        if xmlElementIndexSelected == 0 then
            messagebox("Selected component was not found!", "modal", "error");
            return;
        end
        
        
        
        //string of component below the selected
        stringSelectedBelow = handles.ComponentsUsed.String(handles.ComponentsUsed.Value+1);
        
        //decode the component type from the string
        indexesSymbolOfTypeBeginning=strindex(stringSelectedBelow, '<');
        indexesSymbolOfTypeEnd=strindex(stringSelectedBelow, '>');
        stringSelectedXMLTypeBelow=part(stringSelectedBelow, indexesSymbolOfTypeBeginning(1)+1:indexesSymbolOfTypeEnd(1)-1);
        
        //decode the name (actually the name attribute) of the used component
        indexesSymbolOfNameBeginning=strindex(stringSelectedBelow, '> ');
        stringSelectedXMLNameBelow=part(stringSelectedBelow, indexesSymbolOfNameBeginning(1)+2:length(stringSelectedBelow));
        
        //find the selected element in the channel
        xmlElementIndexSelectedBelow = FindXMLElementIndexInFirstChildrenOfXMLElement(xmlChannelSelected, stringSelectedXMLTypeBelow, stringSelectedXMLNameBelow);
        if xmlElementIndexSelectedBelow == 0 then
            messagebox("Component below selected was not found!", "modal", "error");
            return;
        end
        
        
        
        //switch the selected component with the component below
        componentSelectedString = xmlDump(xmlChannelSelected.children(xmlElementIndexSelected));
        docComponentSelected = xmlReadStr(componentSelectedString);
        componentSelected = docComponentSelected.root;
//        //<>debug only
//        disp(componentSelected);
//        disp(xmlDump(componentSelected));
        
        componentSelectedBelowString = xmlDump(xmlChannelSelected.children(xmlElementIndexSelectedBelow));
        docComponentSelectedBelow = xmlReadStr(componentSelectedBelowString);
        componentSelectedBelow = docComponentSelectedBelow.root;
//        //<>debug only
//        disp(componentSelectedBelow);
//        disp(xmlDump(componentSelectedBelow));
        
        xmlChannelSelected.children(xmlElementIndexSelected) = componentSelectedBelow;
        xmlChannelSelected.children(xmlElementIndexSelectedBelow) = componentSelected;
        
        
        
//        //change order of strings in ComponentsUsed handle
//        handles.ComponentsUsed.String(handles.ComponentsUsed.Value) = stringSelectedBelow;
//        handles.ComponentsUsed.String(handles.ComponentsUsed.Value+1) = stringSelected;
        
        //refresh channel but select the curent selected component after switch
        newSelectedValue = handles.ComponentsUsed.Value + 1;
        Channels_callback(handles);
        handles.ComponentsUsed.Value = newSelectedValue;
        //refresh the selected visual component in schema
        ComponentsUsed_callback(handles);
        
        
    end
    
endfunction



//function ImageController_callback(handles)
////Write your callback for  ImageController  here
//    
//    //nothing
//    
//endfunction

function ImageControllerDrawing(xmlChannel)
    
    global xmlChannelSelectedVisualComponentsList;
    //delete all items in the global list
    while length(xmlChannelSelectedVisualComponentsList) > 0
        xmlChannelSelectedVisualComponentsList(1) = null();
    end
    xmlChannelSelectedVisualComponentsList = DrawControllerOfXMLChannel(handles.ImageController, xmlChannel);
    
//    //<>debug only
//    disp(handles.ImageController);
    
//    //<>debug only
//    handles.ImageController.font_size = 3;
//    //handles.ImageController.FontName = "Serif";
//    handles.ImageController.font_style = 4;
//    position_x = 0.0;
//    position_y = 0.0;
//    plot2d(0,0,[0,0],"010"," ",[0,0,1,1]);
//    str = ["Scilab is not Matlab" ; "That is true!"];
//    r2 = xstringl(position_x, position_y, str, handles.ImageController.font_style, handles.ImageController.font_size);
//    xrects(r2);
//    xstring(r2(1), r2(2)-r2(4), str)
    
endfunction



//function SaveDiagramAsSubMenu_callback(handles)
////Write your callback for  SaveDiagramAsSubMenu_callback  here
//    
//    
//    //show save dialog for diagram save
//    [fileName, pathName, filterIndex] = uiputfile( ["*.bmp","BMP files" ; "*.emf","EMF files" ; "*.eps","EPS files" ; "*.gif","GIF files" ; "*.pdf","PDF files" ; "*.png","PNG files" ; "*.ppm","PPM files" ; "*.ps","PS files" ; "*.svg","SVG files"], "", "Save file with diagram of current control system" );
//    
//    //check if cancel button was not clicked
//    if fileName ~= "" & pathName ~= "" & filterIndex ~= 0 then
//        
//        DiagramSaveDialogID = 77777777;
//        screensizePX = get(0, "screensize_px");   //<> <>
//        fDiagram = figure(DiagramSaveDialogID, "menubar", "none", 'figure_position',[387,32], 'figure_size',[screensizePX(3), screensizePX(4)], 'figure_name','Temporary window for diagram saving');

//        copyImageController = newaxes(fDiagram);
//        copyImageController.axes_bounds = [0.0,0.0,0.85,0.39]; //<> <>
//        copyImageController.clip_state = "clipgrf";
//        copyImageController.margins = [0 0 0 0];
//        copyImageController.axes_visible = "off";
//        copyImageController.auto_scale = "off";
//        copyImageController.zoom_box = [];
//        global xmlChannelSelected;
//        DrawControllerOfXMLChannel(copyImageController, xmlChannelSelected);
//        //<> <>?
//        //copyImageController.axes_bounds = [0.0,0.0,1.0,1.0];
//        select filterIndex
//        case 1 then
//            xs2bmp(DiagramSaveDialogID, fileName);
//        case 2 then
//            xs2emf(DiagramSaveDialogID, fileName);
//        case 3 then
//            xs2eps(DiagramSaveDialogID, fileName);
//        case 4 then
//            xs2gif(DiagramSaveDialogID, fileName);
//        case 5 then
//            xs2pdf(DiagramSaveDialogID, fileName);
//        case 6 then
//            xs2png(DiagramSaveDialogID, fileName);
//        case 7 then
//            xs2ppm(DiagramSaveDialogID, fileName);
//        case 8 then
//            xs2ps(DiagramSaveDialogID, fileName);
//        case 9 then
//            xs2svg(DiagramSaveDialogID, fileName);
//        end
//        
//    end
//    
//    
//endfunction



//function EditDiagramPropertiesSubMenu_callback(handles)
////Write your callback for  EditDiagramPropertiesSubMenu_callback  here
//    
//    
//    //<> <>
//    
//    
//endfunction




function NewAutopilot_callback(handles)
//Write your callback for  NewAutopilot_callback  here
    
    global xmlAutopilot;
    //delete XML Objects for autopilots
    CheckAndDeleteXMLDoc(xmlAutopilot);
    //create new empty autopilot XML file for JSBSim (read it from xml file with default new JSBSim autopilot)
    xmlAutopilot = xmlRead("templates" + filesep() + "autopilot_new.xml");
//    global xmlAutopilotNew;
//    xmlAutopilot = xmlReadStr(xmlAutopilotNew);
    
    errorString=ValidateXMLdocument(xmlAutopilot);
    
    global xmlAutopilotFilePath;
    global xmlAutopilotFileName;
    xmlAutopilotFilePath = emptystr();
    xmlAutopilotFileName = emptystr();
    
//    //create new empty autopilot XML file for FlightGear
//    //xmlAutopilotFlightGear = xmlReadStr(xmlAutopilotFlightGearNew);
//    
//    //read file whit internal and custom properties which are available
//    global propertiesAvailable;
//    propertiesAvailable = ReadInternalAndCustomProperties();
//    
//    //reset data in listboxes
//    channelsChoices = ["<global>"];
//    handles.Channels.String = channelsChoices;
//    handles.Components.String = [];
//    handles.ComponentsUsed.String = [];
//    
//    //selected channel (0 (none) is default)
//    global xmlChannelSelected;
//    xmlChannelSelected = 0;
//    
//    //Clear current axes schema
//    ClearAxesSchema(handles.ImageController);
//    
    
    
    if xmlAutopilot.root.name == "autopilot" then
        
        children = xmlAutopilot.root.children;
        
        channelsChoices = ["<global>"];  //everything which is not channel belongs to 'global' (autopilot) tag (e.g. property)
        
        for i = 1 : 1 : length(children)
            //find elements with 'channel' tag
            if children.name(i) == "channel" then
                //add name of the element channel (the name attribute) to choices string
                channelsChoices(size(channelsChoices, 1) + 1) = children(i).attributes.name
            end
        end
        
        //load and add properties
        global propertiesAvailable;
        propertiesAvailable = ReadInternalAndCustomProperties();
        //add properties from XML file to list with properties
        propertiesAvailable = AddPropertiesFromLoadedXMLToPropertiesAvailable(xmlAutopilot, propertiesAvailable);
        
        //change data in listboxes
        handles.Channels.String = channelsChoices;
        handles.Components.String = [];
        handles.ComponentsUsed.String = [];
        
        //selected channel (0 (none) is default)
        global xmlChannelSelected;
        xmlChannelSelected = 0;
        
        //Clear current axes schema
        ClearAxesSchema(handles.ImageController);
        
    else
        
        messagebox("Wrong format! The default new XML file is not a valid autopilot file (check templates" + filesep() + "autopilot_new.xml)!", "modal", "error");
        
    end
    
    
endfunction



function OpenAutopilot_callback(handles)
//Write your callback for  OpenAutopilot  here
    
    global xmlAutopilot;
    global xmlAutopilotFilePath;
    global xmlAutopilotFileName;
    
    //show open dialog for JSBSim autopilot
    //<>zmenit "aircraft\V-TS v1-532\Systems" na "aircraft"
    [fileName, pathName, filterIndex] = uigetfile( ["*.xml","XML files"], "aircraft\V-TS v1-532\Systems", "Open file with JSBSim autopilot", %f );
    
    //check if cancel button was not clicked
    if fileName ~= "" & pathName ~= "" & filterIndex ~= 0 then
        
        CheckAndDeleteXMLDoc(xmlAutopilot);
        //read xml file with JSBSim autopilot
        pathOpenWhole = pathName + filesep() + fileName;
        xmlAutopilot = xmlRead(pathOpenWhole);
        errorString=ValidateXMLdocument(xmlAutopilot);
        
        if xmlAutopilot.root.name == "autopilot" then
            
            children = xmlAutopilot.root.children;
            
            channelsChoices = ["<global>"];  //everything which is not channel belongs to 'global' (autopilot) tag (e.g. property)
            
            for i = 1 : 1 : length(children)
                //find elements with 'channel' tag
                if children.name(i) == "channel" then
                    //add name of the element channel (the name attribute) to choices string
                    channelsChoices(size(channelsChoices, 1) + 1) = children(i).attributes.name
                end
            end
            
            //load and add properties
            global propertiesAvailable;
            propertiesAvailable = ReadInternalAndCustomProperties();
            //add properties from XML file to list with properties
            propertiesAvailable = AddPropertiesFromLoadedXMLToPropertiesAvailable(xmlAutopilot, propertiesAvailable);
            
            //change data in listboxes
            handles.Channels.String = channelsChoices;
            handles.Components.String = [];
            handles.ComponentsUsed.String = [];
            
            //selected channel (0 (none) is default)
            global xmlChannelSelected;
            xmlChannelSelected = 0;
            
            xmlAutopilotFilePath = pathOpenWhole;
            xmlAutopilotFileName = GetFileNameWithoutExtension(fileName, ".xml");
            
            //Clear current axes schema
            ClearAxesSchema(handles.ImageController);
            
        else
            
            messagebox("Wrong format! The XML file is not a valid autopilot file!", "modal", "error");
            
        end
        
    end
    
    
endfunction



function SaveAutopilot_callback(handles)
//Write your callback for  SaveAutopilot  here
    
    global xmlAutopilot;
    global xmlAutopilotFilePath;
    global xmlAutopilotFileName;
    
    //show save dialog for JSBSim autopilot
    //<>zmenit "aircraft\V-TS v1-532\Systems" na "aircraft"
    [fileName, pathName, filterIndex] = uiputfile( ["*.xml","XML files"], "aircraft\V-TS v1-532\Systems", "Save file with JSBSim autopilot" );
    
    //check if cancel button was not clicked
    if fileName ~= "" & pathName ~= "" & filterIndex ~= 0 then
        
        
        //xmlAutopilot = xmlRead("http://www.w3.org/TR/2009/REC-xml-names-20091208/xml-names-10-3e.xml");
        if exists("xmlAutopilot") == 1 then
            if typeof(xmlAutopilot) == "XMLDoc" then
                if xmlIsValidObject(xmlAutopilot) == %t then
                    
                    pathSaveWhole = pathName + filesep() + fileName;
                    xmlWrite(xmlAutopilot, pathSaveWhole, %t);// + ".xml", %t);
                    
                    xmlAutopilotFilePath = pathSaveWhole;
                    xmlAutopilotFileName = GetFileNameWithoutExtension(fileName, ".xml");
                    
                    messagebox("Autopilot was saved sucessfully!", "modal", "info");
                end
            end
        end
        
    end
    
endfunction




//function SaveAutopilotFlightGear_callback(handles)
////Write your callback for  SaveAutopilotFlightGear  here
//    
//    
//    //<> <>
//    
//    
//endfunction




function ParametersInitial_callback(handles)
//Write your callback for  ParametersInitial  here
    
    
    global xmlReset;
    global xmlResetFilePath;
    global xmlResetFileName;
    rootResetName = "initialize";
    
    
    //ask about operation with reset file
    answerMsgResetFileOperation = messagebox(["Do you want to open a reset file or edit the current one?"], "Reset file operation", "question", ["Open" "Edit" "New" "Cancel"], "modal");
    
    //if a reset file should be opened or the current reset file should be edited
    if answerMsgResetFileOperation == 1 | answerMsgResetFileOperation == 2 & xmlResetFilePath ~= emptystr() then
        
        
        
        //if user wants to open a reset file
        if answerMsgResetFileOperation == 1 then
            
            //show open dialog for JSBSim reset file
            //<>zmenit "aircraft\V-TS v1-532" na "aircraft"
            [fileNameOpen, pathNameOpen, filterIndexOpen] = uigetfile( ["*.xml","XML files"], "aircraft\V-TS v1-532", "Open file with JSBSim reset information", %f );
            
            //check if cancel button was not clicked
            if fileNameOpen ~= "" & pathNameOpen ~= "" & filterIndexOpen ~= 0 then
                
                
                pathNameOpenWhole = pathNameOpen + filesep() + fileNameOpen;
                xmlResetTemporary = xmlRead(pathNameOpenWhole);
                errorString = ValidateXMLdocument(xmlResetTemporary);
                
                if xmlResetTemporary.root.name == rootResetName then
                    
                    //if the currently opened reset file contains any children element
                    if length(xmlResetTemporary.root.children) > 0 then
                        
                        //erase memory with empty reset template xml file and switch to the loaded file
                        CheckAndDeleteXMLDoc(xmlReset);
                        xmlReset = xmlResetTemporary;
                        
                        xmlResetFilePath = pathNameOpenWhole;
                        xmlResetFileName = GetFileNameWithoutExtension(fileNameOpen, ".xml");
                        
                    else
                        messagebox("Wrong format! The opened XML reset file does not contain any children XML elements!", "modal", "error");
                        CheckAndDeleteXMLDoc(xmlResetTemporary);
                        return;
                    end
                    
                else
                    messagebox("Wrong format! The opened XML file is not a valid reset file!", "modal", "error");
                    CheckAndDeleteXMLDoc(xmlResetTemporary);
                    return;
                end
                
            //otherwise, the cancel button was clicked in open dialog, end the function
            else
                
                return;
                
            end
            
        end
        
        
        global xmlResetNew;
        xmlResetTemplate = xmlReadStr(xmlResetNew);
        //if the root name element of the currently opened/edited xml reset file is "initialize", it is valid JSBSim reset file
        if xmlReset.root.name == rootResetName then
            //if the currently opened reset file contains any children element
            if length(xmlReset.root.children) > 0 then
                
                
                //disp(xmlReset.root.attributes.version); //<>debug only
                xmlResetVersion = xmlReset.root.attributes.version;
                //if a reset file version should be 1
                if xmlResetVersion == [] | strsubst(xmlResetVersion, " ", "") == "1" then
                    //disp("version 1"); //<>debug only
                    //erase memory with empty reset template xml file and load template file
                    CheckAndDeleteXMLDoc(xmlResetTemplate);
                    xmlResetTemplate = xmlRead("templates" + filesep() + "Simulation" + filesep() + "reset-v1.xml");
                //else if a reset file version should be 2
                elseif strsubst(xmlResetVersion, " ", "") == "2" then
                    //disp("version 2"); //<>debug only
                    //erase memory with empty reset template xml file and load template file
                    CheckAndDeleteXMLDoc(xmlResetTemplate);
                    xmlResetTemplate = xmlRead("templates" + filesep() + "Simulation" + filesep() + "reset-v2.xml");
                //otherwise, some error occurred because this situation cannot happen
                else
                    messagebox("The choice of new reset file version is not supported!", "modal", "error")
                    return;
                end
                errorString=ValidateXMLdocument(xmlResetTemplate);
                
                
                //if the root name element of xml template reset file is "initialize", it is valid JSBSim template reset file
                if xmlResetTemplate.root.name == rootResetName then
                    //if the template reset file contains any children element
                    if length(xmlResetTemplate.root.children) > 0 then
                        
                        
                        //decode labels and values from template
                        [labelsTemplate, possibleInputTypesList] = DecodeInitialParametersLabelsValues(xmlResetTemplate);
                        //decode labels and values used in edit dialog (from opened file or from data in memory)
                        [labels, values] = DecodeInitialParametersLabelsValues(xmlReset);
                        
                        //join labels and values to one piece
                        [outLabels, outValues, possibleInputTypesList]=JoinResetFileAndTemplate(labels, values, labelsTemplate, possibleInputTypesList);
                        
                        //include information about possible inputs to labels
                        outLabels = GetLabelsWithPossibleInputInformation(outLabels, possibleInputTypesList);
                        
                        if outLabels ~= [] & outValues ~= [] & possibleInputTypesList ~= [] then
                            
                            //show dialog for editation, check the validity of data content and save the reset file if selected
                            [xmlResetFilePath, xmlResetFileName] = ShowCheckSaveResetParametersDialog(xmlReset, outLabels, outValues, possibleInputTypesList, [], []);
                            
                        else
                            messagebox("Wrong format! No labels, values, or possible input types were found and joined!", "modal", "error");
                        end
                        
                        
                    else
                        messagebox("Wrong format! The template XML reset file does not contain any children XML elements (check templates" + filesep() + "Simulation" + filesep() + "reset-v1.xml and templates" + filesep() + "Simulation" + filesep() + "reset-v2.xml)!", "modal", "error");
                    end
                    
                else
                    messagebox("Wrong format! The template XML file is not a valid reset file (check templates" + filesep() + "Simulation" + filesep() + "reset-v1.xml and templates" + filesep() + "Simulation" + filesep() + "reset-v2.xml)!", "modal", "error");
                end
                
                
            else
                messagebox("Wrong format! The currently opened XML reset file does not contain any children XML elements!", "modal", "error");
            end
        else
            messagebox("Wrong format! The currently opened XML file is not a valid reset file!", "modal", "error");
        end
        
        
        //erase memory with reset template xml file
        CheckAndDeleteXMLDoc(xmlResetTemplate);
        
        
        
    //else if the new reset file should be defined
    elseif answerMsgResetFileOperation == 3 | answerMsgResetFileOperation == 2 & xmlResetFilePath == emptystr() then
        
        
        
        //ask about version of reset file
        answerMsgResetFileVersion = messagebox(["In which version should new reset file be?"], "New reset file version", "question", ["Version 1" "Version 2" "Cancel"], "modal");
        
        //if the Cancel button was clicked, end this function
        if answerMsgResetFileVersion >= 3 then

            return;
        end
        
        //erase memory with reset xml file
        CheckAndDeleteXMLDoc(xmlReset);
        //if a reset file version should be 1
        if answerMsgResetFileVersion == 1 then
            xmlReset = xmlRead("templates" + filesep() + "Simulation" + filesep() + "reset-v1.xml");
        //else if a reset file version should be 2
        elseif answerMsgResetFileVersion == 2 then
            xmlReset = xmlRead("templates" + filesep() + "Simulation" + filesep() + "reset-v2.xml");
        //otherwise, some error occurred because this situation cannot happen
        else
            messagebox("The choice of new reset file version is not supported!", "modal", "error")
            return;
        end
        errorString=ValidateXMLdocument(xmlReset);
        
        //if the root name element of xml reset file is "initialize", it is valid JSBSim template reset file
        if xmlReset.root.name == rootResetName then
            //if the reset file contains any children element
            if length(xmlReset.root.children) > 0 then
                
                
                //decode labels and values used in dialog
                [labels, values] = DecodeInitialParametersLabelsValues(xmlReset);
                //switch possible input types with values
                possibleInputTypesList = values;
                values = [];
                //set default values to values
                for i = 1 : 1 : size(possibleInputTypesList, 1)
                    values(size(values, 1) + 1) = SetIDinValue(possibleInputTypesList(i));
                end
                //include information about possible inputs to labels
                labels = GetLabelsWithPossibleInputInformation(labels, possibleInputTypesList);
                
                
                if labels ~= [] & values ~= [] & possibleInputTypesList ~= [] then
                    
                    //<>debug only
                    //disp([labels ; values ; possibleInputTypesList]);
                    //disp(labels);
                    //disp("size of labels: " + string(size(labels, 1)) + ", " + string(size(labels, 2)));
                    //disp(values);
                    //disp("size of values: " + string(size(values, 1)) + ", " + string(size(values, 2)));
                    //disp(possibleInputTypesList);
                    
                    //show dialog for editation, check the validity of data content and save the reset file if selected
                    [xmlResetFilePath, xmlResetFileName] = ShowCheckSaveResetParametersDialog(xmlReset, labels, values, possibleInputTypesList, [], []);
                    
                    
                else
                    
                    messagebox("Wrong format! No labels, values, or possible input types were found (check templates" + filesep() + "Simulation" + filesep() + "reset-v1.xml and templates" + filesep() + "Simulation" + filesep() + "reset-v2.xml)!", "modal", "error");
                    
                end
                
                
            else
                messagebox("Wrong format! The default new XML reset file does not contain any children XML elements (check templates" + filesep() + "Simulation" + filesep() + "reset-v1.xml and templates" + filesep() + "Simulation" + filesep() + "reset-v2.xml)!", "modal", "error");
            end
            
        else
            messagebox("Wrong format! The default new XML file is not a valid reset file (check templates" + filesep() + "Simulation" + filesep() + "reset-v1.xml and templates" + filesep() + "Simulation" + filesep() + "reset-v2.xml)!", "modal", "error");
        end
        
        
        
    end
    
    
endfunction




function SimulationDefinition_callback(handles)
//Write your callback for  SimulationDefinition  here
    
    global xmlSimulation;
    global xmlSimulationFilePath;
    global xmlSimulationFileName;
    rootSimulationName = "runscript";
    
    global xmlReset;
    global xmlResetFilePath;
    global xmlResetFileName;
    
    global xmlAircraftFilePath;
    global xmlAircratFileName;
    
    global propertiesAvailable;
    
    
    //ask about operation with simulation file
    answerMsgSimulationFileOperation = messagebox(["Do you want to open a simulation file or edit the current one?"], "Simulation file operation", "question", ["Open" "Edit" "New" "Cancel"], "modal");
    
    //if a simulation file should be opened or the current simulation file should be edited
    if answerMsgSimulationFileOperation == 1 | answerMsgSimulationFileOperation == 2 & xmlSimulationFilePath ~= emptystr() then
        
        
        
        //if user wants to open a simulation file
        if answerMsgSimulationFileOperation == 1 then
            
            //show open dialog for JSBSim simulation file
            [fileNameOpen, pathNameOpen, filterIndexOpen] = uigetfile( ["*.xml","XML files"], "scripts", "Open file with JSBSim simulation definition", %f );
            
            //check if cancel button was not clicked
            if fileNameOpen ~= "" & pathNameOpen ~= "" & filterIndexOpen ~= 0 then
                

                
                pathNameOpenWhole = pathNameOpen + filesep() + fileNameOpen;
                xmlSimulationTemporary = xmlRead(pathNameOpenWhole);
                errorString = ValidateXMLdocument(xmlSimulationTemporary);
                
                if xmlSimulationTemporary.root.name == rootSimulationName then
                    
                    //if the currently opened simulation file contains any children element
                    if length(xmlSimulationTemporary.root.children) > 0 then
                        
                        //erase memory with simulation xml file and switch to the loaded file
                        CheckAndDeleteXMLDoc(xmlSimulation);
                        xmlSimulation = xmlSimulationTemporary;
                        
                        xmlSimulationFilePath = pathNameOpenWhole;
                        xmlSimulationFileName = GetFileNameWithoutExtension(fileNameOpen, ".xml");
                        
                    else
                        messagebox("Wrong format! The opened XML simulation file does not contain any children XML elements!", "modal", "error");
                        CheckAndDeleteXMLDoc(xmlSimulationTemporary);
                        return;
                    end
                    
                else
                    messagebox("Wrong format! The opened XML file is not a valid simulation file!", "modal", "error");
                    CheckAndDeleteXMLDoc(xmlSimulationTemporary);
                    return;
                end
                
            //otherwise, the cancel button was clicked in open dialog, end the function
            else
                
                return;
                
            end
            
        end
        
        
        //if the root name element of the currently opened/edited xml simulation file is "runscript", it is valid JSBSim simulation file
        if xmlSimulation.root.name == rootSimulationName then
            //if the currently opened simulation file contains any children element
            if length(xmlSimulation.root.children) > 0 then
                
                //show dialog for simulation definition
                [outXmlSimulation, outXmlResetFilePath, outXmlResetFileName, outXmlAircraftFilePath, outXmlAircraftFileName] = DialogSimulationDefinitionOkCancel(xmlSimulation, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, propertiesAvailable);
                
                if outXmlSimulation ~= [] then
                    xmlSimulation = outXmlSimulation;
                    xmlResetFilePath = outXmlResetFilePath;
                    xmlResetFileName = outXmlResetFileName;
                    //load new xml reset file
                    xmlResetTemp = xmlRead(xmlResetFilePath);
                    if xmlResetTemp ~= [] then
                        xmlReset = xmlResetTemp;
                    else
                        messagebox(["Loading of new reset file (defined by reset path in simulation dialog) failed!" ; "The original reset file is kept."], "modal", "error");
                    end
                    xmlAircraftFilePath = outXmlAircraftFilePath;
                    xmlAircratFileName = outXmlAircraftFileName;
                    //show dialog to save the simulation file if selected
                    [xmlSimulationFilePath, xmlSimulationFileName] = ShowSaveDialogXMLSimulation(xmlSimulation);
                end
                
            else
                messagebox("Wrong format! The currently opened XML simulation file does not contain any children XML elements!", "modal", "error");
            end
        else
            messagebox("Wrong format! The currently opened XML file is not a valid simulation file!", "modal", "error");
        end
        
        
        
    //else if the new simulation file should be defined
    elseif answerMsgSimulationFileOperation == 3 | answerMsgSimulationFileOperation == 2 & xmlSimulationFilePath == emptystr() then
        
        
        
        //erase memory with simulation xml file
        CheckAndDeleteXMLDoc(xmlSimulation);
        //load xml simulation template file
        xmlSimulation = xmlRead("templates" + filesep() + "Simulation_withoutAttributes" + filesep() + "script_template_with_defaults.xml");
        errorString=ValidateXMLdocument(xmlSimulation);
        
        //if the root name element of xml simulation file is "runscript", it is valid JSBSim template simulation file
        if xmlSimulation.root.name == rootSimulationName then
            //if the simulation file contains any children element
            if length(xmlSimulation.root.children) > 0 then
                
                //show dialog for simulation definition
                [outXmlSimulation, outXmlResetFilePath, outXmlResetFileName, outXmlAircraftFilePath, outXmlAircraftFileName] = DialogSimulationDefinitionOkCancel(xmlSimulation, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, propertiesAvailable);
                
                if outXmlSimulation ~= [] then
                    xmlSimulation = outXmlSimulation;
                    xmlResetFilePath = outXmlResetFilePath;
                    xmlResetFileName = outXmlResetFileName;
                    //load new xml reset file
                    xmlResetTemp = xmlRead(xmlResetFilePath);
                    if xmlResetTemp ~= [] then
                        xmlReset = xmlResetTemp;
                    else
                        messagebox(["Loading of new reset file (defined by reset path in simulation dialog) failed!" ; "The original reset file is kept."], "modal", "error");
                    end
                    xmlAircraftFilePath = outXmlAircraftFilePath;
                    xmlAircratFileName = outXmlAircraftFileName;
                    //show dialog to save the simulation file if selected
                    [xmlSimulationFilePath, xmlSimulationFileName] = ShowSaveDialogXMLSimulation(xmlSimulation);
                end
                
            else
                messagebox("Wrong format! The default new XML simulation file does not contain any children XML elements (check templates" + filesep() + "Simulation_withoutAttributes" + filesep() + "script_template_with_defaults.xml)!", "modal", "error");
            end
            
        else
            messagebox("Wrong format! The default new XML file is not a valid simulation file (check templates" + filesep() + "Simulation_withoutAttributes" + filesep() + "script_template_with_defaults.xml)!", "modal", "error");
        end
        
        
        
    end
    
    
endfunction




function PIDDesignStart_callback(handles)
//Write your callback for  PIDDesignStart  here
    
    
    global xmlControllerAdjustmentDefinition;
    global xmlControllerAdjustmentDefinitionFilePath;
    global xmlControllerAdjustmentDefinitionFileName;
    rootControllerAdjustmentDefinition = "control_design_start";
    
    global xmlSimulation;
    global xmlSimulationFilePath;
    global xmlSimulationFileName;
    
    global xmlReset;
    global xmlResetFilePath;
    global xmlResetFileName;
    
    global xmlAutopilot;
    global xmlAutopilotFilePath;
    global xmlAutopilotFileName;
    
    global xmlAircraftFilePath;
    global xmlAircratFileName;
    
    global propertiesAvailable;
    
    
    //ask about operation with controller adjustment definition file
    answerMsgControllerAdjustmentDefinitionFileOperation = messagebox(["Do you want to open a controller adjustment definition file or edit the current one?"], "Control Design start file operation", "question", ["Open" "Edit" "New" "Cancel"], "modal");
    
    //if a controller adjustment definition file should be opened or the current controller adjustment definition file should be edited
    if answerMsgControllerAdjustmentDefinitionFileOperation == 1 | answerMsgControllerAdjustmentDefinitionFileOperation == 2 & xmlControllerAdjustmentDefinitionFilePath ~= emptystr() then
        
        
        
        //if user wants to open a controller adjustment definition file
        if answerMsgControllerAdjustmentDefinitionFileOperation == 1 then
            
            //show open dialog for controller adjustment definition file
            [fileNameOpen, pathNameOpen, filterIndexOpen] = uigetfile( ["*.xml","XML files"], "control_design", "Open file with controller adjustment definition", %f );
            
            //check if cancel button was not clicked
            if fileNameOpen ~= "" & pathNameOpen ~= "" & filterIndexOpen ~= 0 then
                
                
                pathNameOpenWhole = pathNameOpen + filesep() + fileNameOpen;
                xmlControllerAdjustmentDefinitionTemporary = xmlRead(pathNameOpenWhole);
                errorString = ValidateXMLdocument(xmlControllerAdjustmentDefinitionTemporary);
                
                if xmlControllerAdjustmentDefinitionTemporary.root.name == rootControllerAdjustmentDefinition then
                    
                    //if the currently opened controller adjustment definition file contains any children element
                    if length(xmlControllerAdjustmentDefinitionTemporary.root.children) > 0 then
                        
                        //erase memory with controller adjustment definition xml file and switch to the loaded file
                        CheckAndDeleteXMLDoc(xmlControllerAdjustmentDefinition);
                        xmlControllerAdjustmentDefinition = xmlControllerAdjustmentDefinitionTemporary;
                        
                        xmlControllerAdjustmentDefinitionFilePath = pathNameOpenWhole;
                        xmlControllerAdjustmentDefinitionFileName = GetFileNameWithoutExtension(fileNameOpen, ".xml");
                        
                    else
                        messagebox("Wrong format! The opened XML controller adjustment definition file does not contain any children XML elements!", "modal", "error");
                        CheckAndDeleteXMLDoc(xmlControllerAdjustmentDefinitionTemporary);
                        return;
                    end
                    
                else
                    messagebox("Wrong format! The opened XML file is not a valid controller adjustment definition file!", "modal", "error");
                    CheckAndDeleteXMLDoc(xmlControllerAdjustmentDefinitionTemporary);
                    return;
                end
                
            //otherwise, the cancel button was clicked in open dialog, end the function
            else
                
                return;
                
            end
            
        end
        
        
        //if the root name element of the currently opened/edited xml controller adjustment definition file is "control_design_start", it is valid controller adjustment definition file
        if xmlControllerAdjustmentDefinition.root.name == rootControllerAdjustmentDefinition then
            //if the currently opened controller adjustment definition file contains any children element
            if length(xmlControllerAdjustmentDefinition.root.children) > 0 then
                
                //show dialog for controller adjustment definition
                [outXmlControllerAdjustmentDefinition, outXmlSimulation, outXmlReset, outXmlAutopilot, outXmlSimulationFilePath, outXmlSimulationFileName, outXmlResetFilePath, outXmlResetFileName, outXmlAircraftFilePath, outXmlAircraftFileName, outXmlAutopilotFilePath, outXmlAutopilotFileName] = DialogControllerAdjustmentDefinitionOkCancel(xmlControllerAdjustmentDefinition, xmlSimulation, xmlReset, xmlAutopilot, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, xmlAutopilotFilePath, xmlAutopilotFileName, propertiesAvailable);
                
                if outXmlControllerAdjustmentDefinition ~= [] then
                    
                    xmlControllerAdjustmentDefinition = outXmlControllerAdjustmentDefinition;
                    xmlSimulation = outXmlSimulation;
                    xmlReset = outXmlReset;
                    xmlAutopilot = outXmlAutopilot;
                    
                    xmlSimulationFilePath = outXmlSimulationFilePath;
                    xmlSimulationFileName = outXmlSimulationFileName;
                    
                    xmlResetFilePath = outXmlResetFilePath;
                    xmlResetFileName = outXmlResetFileName;
                    
                    xmlAircraftFilePath = outXmlAircraftFilePath;
                    xmlAircratFileName = outXmlAircraftFileName;
                    
                    xmlAutopilotFilePath = outXmlAutopilotFilePath;
                    xmlAutopilotFileName = outXmlAutopilotFileName;
                    
                    //show dialog to save the controller adjustment definition file if selected
                    [xmlControllerAdjustmentDefinitionFilePath, xmlControllerAdjustmentDefinitionFileName] = ShowSaveDialogXMLControllerAdjustmentDefinition(xmlControllerAdjustmentDefinition);
                    
                    
                    //ask whether the controller adjustment process should be started
                    answerMsgControllerAdjustmentPerform = messagebox(["Do you want to start the controller adjustment process as defined in the current controller adjustment definition file?" ; "Warning, this operation may take many minutes or even hours!"], "Perform Controller Adjustment", "question", ["Yes" "No"], "modal");
                    
                    //if user wants to start a controller adjustment process, perform the simulation
                    if answerMsgControllerAdjustmentPerform == 1 then
                        
                        ControllerAdjustmentSimulationExecuteJSBSim(xmlControllerAdjustmentDefinition, xmlSimulation, xmlReset, xmlAutopilot, xmlControllerAdjustmentDefinitionFilePath, xmlControllerAdjustmentDefinitionFileName, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, xmlAutopilotFilePath, xmlAutopilotFileName, propertiesAvailable);
                        
                    end
                    
                    
                end
                
            else
                messagebox("Wrong format! The currently opened XML controller adjustment definition file does not contain any children XML elements!", "modal", "error");
            end
        else
            messagebox("Wrong format! The currently opened XML file is not a valid controller adjustment definition file!", "modal", "error");
        end
        
        
        
    //else if the new controller adjustment definition file should be defined
    elseif answerMsgControllerAdjustmentDefinitionFileOperation == 3 | answerMsgControllerAdjustmentDefinitionFileOperation == 2 & xmlControllerAdjustmentDefinitionFilePath == emptystr() then
        
        
        
        //erase memory with controller adjustment definition xml file
        CheckAndDeleteXMLDoc(xmlControllerAdjustmentDefinition);
        //load xml controller adjustment definition template file
        xmlControllerAdjustmentDefinition = xmlRead("templates" + filesep() + "Control_Design_withoutAttributes" + filesep() + "control_design_start_template.xml");
        errorString=ValidateXMLdocument(xmlControllerAdjustmentDefinition);
        
        //if the root name element of xml controller adjustment definition file is "control_design_start", it is valid template controller adjustment definition file
        if xmlControllerAdjustmentDefinition.root.name == rootControllerAdjustmentDefinition then
            //if the controller adjustment definition file contains any children element
            if length(xmlControllerAdjustmentDefinition.root.children) > 0 then
                
                //show dialog for controller adjustment definition
                [outXmlControllerAdjustmentDefinition, outXmlSimulation, outXmlReset, outXmlAutopilot, outXmlSimulationFilePath, outXmlSimulationFileName, outXmlResetFilePath, outXmlResetFileName, outXmlAircraftFilePath, outXmlAircraftFileName, outXmlAutopilotFilePath, outXmlAutopilotFileName] = DialogControllerAdjustmentDefinitionOkCancel(xmlControllerAdjustmentDefinition, xmlSimulation, xmlReset, xmlAutopilot, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, xmlAutopilotFilePath, xmlAutopilotFileName, propertiesAvailable);
                
                if outXmlControllerAdjustmentDefinition ~= [] then
                    
                    xmlControllerAdjustmentDefinition = outXmlControllerAdjustmentDefinition;
                    xmlSimulation = outXmlSimulation;
                    xmlReset = outXmlReset;
                    xmlAutopilot = outXmlAutopilot;
                    
                    xmlSimulationFilePath = outXmlSimulationFilePath;
                    xmlSimulationFileName = outXmlSimulationFileName;
                    
                    xmlResetFilePath = outXmlResetFilePath;
                    xmlResetFileName = outXmlResetFileName;
                    
                    xmlAircraftFilePath = outXmlAircraftFilePath;
                    xmlAircratFileName = outXmlAircraftFileName;
                    
                    xmlAutopilotFilePath = outXmlAutopilotFilePath;
                    xmlAutopilotFileName = outXmlAutopilotFileName;
                    
                    //show dialog to save the controller adjustment definition file if selected
                    [xmlControllerAdjustmentDefinitionFilePath, xmlControllerAdjustmentDefinitionFileName] = ShowSaveDialogXMLControllerAdjustmentDefinition(xmlControllerAdjustmentDefinition);
                    
                    
                    //ask whether the controller adjustment process should be started
                    answerMsgControllerAdjustmentPerform = messagebox(["Do you want to start the controller adjustment process as defined in the current controller adjustment definition file?" ; "Warning, this operation may take many minutes or even hours!"], "Perform Controller Adjustment", "question", ["Yes" "No"], "modal");
                    
                    //if user wants to start a controller adjustment process, perform the simulation
                    if answerMsgControllerAdjustmentPerform == 1 then
                        
                        ControllerAdjustmentSimulationExecuteJSBSim(xmlControllerAdjustmentDefinition, xmlSimulation, xmlReset, xmlAutopilot, xmlControllerAdjustmentDefinitionFilePath, xmlControllerAdjustmentDefinitionFileName, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, xmlAutopilotFilePath, xmlAutopilotFileName, propertiesAvailable);
                        
                    end
                    
                    
                end
                
            else
                messagebox("Wrong format! The default new XML controller adjustment definition file does not contain any children XML elements (check templates" + filesep() + "Control_Design_withoutAttributes" + filesep() + "control_design_start_template.xml)!", "modal", "error");
            end
            
        else
            messagebox("Wrong format! The default new XML file is not a valid controller adjustment definition file (check templates" + filesep() + "Control_Design_withoutAttributes" + filesep() + "control_design_start_template.xml)!", "modal", "error");
        end
        
        
        
    end
    
    
endfunction




function SimulationStart_callback(handles)
//Write your callback for  SimulationStart  here
    
    
    global xmlSimulationStart;
    global xmlSimulationStartFilePath;
    global xmlSimulationStartFileName;
    rootSimulationStartName = "simulation_start";
    
    global xmlSimulation;
    global xmlSimulationFilePath;
    global xmlSimulationFileName;
    
    global xmlReset;
    global xmlResetFilePath;
    global xmlResetFileName;
    
    global xmlAircraftFilePath;
    global xmlAircratFileName;
    
    global propertiesAvailable;
    
    
    //ask about operation with simulation file
    answerMsgSimulationStartFileOperation = messagebox(["Do you want to open a simulation start file or edit the current one?"], "Simulation start file operation", "question", ["Open" "Edit" "New" "Cancel"], "modal");
    
    //if a simulation start file should be opened or the current simulation start file should be edited
    if answerMsgSimulationStartFileOperation == 1 | answerMsgSimulationStartFileOperation == 2 & xmlSimulationStartFilePath ~= emptystr() then
        
        
        
        //if user wants to open a simulation start file
        if answerMsgSimulationStartFileOperation == 1 then
            
            //show open dialog for simulation start file
            [fileNameOpen, pathNameOpen, filterIndexOpen] = uigetfile( ["*.xml","XML files"], "simulation", "Open file with simulation start information", %f );
            
            //check if cancel button was not clicked
            if fileNameOpen ~= "" & pathNameOpen ~= "" & filterIndexOpen ~= 0 then
                
                
                pathNameOpenWhole = pathNameOpen + filesep() + fileNameOpen;
                xmlSimulationStartTemporary = xmlRead(pathNameOpenWhole);
                errorString = ValidateXMLdocument(xmlSimulationStartTemporary);
                
                if xmlSimulationStartTemporary.root.name == rootSimulationStartName then
                    
                    //if the currently opened simulation start file contains any children element
                    if length(xmlSimulationStartTemporary.root.children) > 0 then
                        
                        //erase memory with simulation start xml file and switch to the loaded file
                        CheckAndDeleteXMLDoc(xmlSimulationStart);
                        xmlSimulationStart = xmlSimulationStartTemporary;
                        
                        xmlSimulationStartFilePath = pathNameOpenWhole;
                        xmlSimulationStartFileName = GetFileNameWithoutExtension(fileNameOpen, ".xml");
                        
                    else
                        messagebox("Wrong format! The opened XML simulation start file does not contain any children XML elements!", "modal", "error");
                        CheckAndDeleteXMLDoc(xmlSimulationStartTemporary);
                        return;
                    end
                    
                else
                    messagebox("Wrong format! The opened XML file is not a valid simulation start file!", "modal", "error");
                    CheckAndDeleteXMLDoc(xmlSimulationStartTemporary);
                    return;
                end
                
            //otherwise, the cancel button was clicked in open dialog, end the function
            else
                
                return;
                
            end
            
        end
        
        
        //if the root name element of the currently opened/edited xml simulation start file is "simulation_start", it is valid simulation start file
        if xmlSimulationStart.root.name == rootSimulationStartName then
            //if the currently opened simulation start file contains any children element
            if length(xmlSimulationStart.root.children) > 0 then
                
                //show dialog for simulation start
                [outXmlSimulationStart, outXmlSimulation, outXmlReset, outXmlSimulationFilePath, outXmlSimulationFileName, outXmlResetFilePath, outXmlResetFileName, outXmlAircraftFilePath, outXmlAircraftFileName] = DialogSimulationStartOkCancel(xmlSimulationStart, xmlSimulation, xmlReset, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, propertiesAvailable);
                
                if outXmlSimulationStart ~= [] then
                    
                    xmlSimulationStart = outXmlSimulationStart;
                    xmlSimulation = outXmlSimulation;
                    xmlReset = outXmlReset;
                    
                    xmlSimulationFilePath = outXmlSimulationFilePath;
                    xmlSimulationFileName = outXmlSimulationFileName;
                    
                    xmlResetFilePath = outXmlResetFilePath;
                    xmlResetFileName = outXmlResetFileName;
                    
                    xmlAircraftFilePath = outXmlAircraftFilePath;
                    xmlAircratFileName = outXmlAircraftFileName;
                    
                    //show dialog to save the simulation start file if selected
                    [xmlSimulationStartFilePath, xmlSimulationStartFileName] = ShowSaveDialogXMLSimulationStart(xmlSimulationStart);
                    
                    
                    //ask whether the simulation should be started
                    answerMsgSimulationPerform = messagebox(["Do you want to start the simulation as defined in the current simulation start file?"], "Perform Simulation", "question", ["Yes" "No"], "modal");
                    
                    //if user wants to start a simulation, perform the simulation
                    if answerMsgSimulationPerform == 1 then
                        
                        global xmlAutopilot;
                        global xmlAutopilotFilePath;
                        global xmlAutopilotFileName;
                        SimulationExecuteJSBSimOrFlightGear(xmlSimulationStart, xmlSimulation, xmlReset, xmlAutopilot, xmlSimulationStartFilePath, xmlSimulationStartFileName, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, xmlAutopilotFilePath, xmlAutopilotFileName);
                        
                    end
                    
                    
                end
                
            else
                messagebox("Wrong format! The currently opened XML simulation start file does not contain any children XML elements!", "modal", "error");

            end
        else
            messagebox("Wrong format! The currently opened XML file is not a valid simulation start file!", "modal", "error");
        end
        
        
        
    //else if the new simulation start file should be defined
    elseif answerMsgSimulationStartFileOperation == 3 | answerMsgSimulationStartFileOperation == 2 & xmlSimulationStartFilePath == emptystr() then
        
        
        
        //erase memory with simulation start xml file
        CheckAndDeleteXMLDoc(xmlSimulationStart);
        //load xml simulation start template file
        xmlSimulationStart = xmlRead("templates" + filesep() + "Simulation_withoutAttributes" + filesep() + "simulation_start_template.xml");
        errorString=ValidateXMLdocument(xmlSimulationStart);
        
        //if the root name element of xml simulation start file is "simulation_start", it is valid template simulation start file
        if xmlSimulationStart.root.name == rootSimulationStartName then
            //if the simulation start file contains any children element
            if length(xmlSimulationStart.root.children) > 0 then
                
                //show dialog for simulation start
                [outXmlSimulationStart, outXmlSimulation, outXmlReset, outXmlSimulationFilePath, outXmlSimulationFileName, outXmlResetFilePath, outXmlResetFileName, outXmlAircraftFilePath, outXmlAircraftFileName] = DialogSimulationStartOkCancel(xmlSimulationStart, xmlSimulation, xmlReset, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, propertiesAvailable);
                
                if outXmlSimulationStart ~= [] then
                    
                    xmlSimulationStart = outXmlSimulationStart;
                    xmlSimulation = outXmlSimulation;
                    xmlReset = outXmlReset;
                    
                    xmlSimulationFilePath = outXmlSimulationFilePath;
                    xmlSimulationFileName = outXmlSimulationFileName;
                    
                    xmlResetFilePath = outXmlResetFilePath;
                    xmlResetFileName = outXmlResetFileName;
                    
                    xmlAircraftFilePath = outXmlAircraftFilePath;
                    xmlAircratFileName = outXmlAircraftFileName;
                    
                    //show dialog to save the simulation start file if selected
                    [xmlSimulationStartFilePath, xmlSimulationStartFileName] = ShowSaveDialogXMLSimulationStart(xmlSimulationStart);
                    
                    
                    //ask whether the simulation should be started
                    answerMsgSimulationPerform = messagebox(["Do you want to start the simulation as defined in the current simulation start file?"], "Perform Simulation", "question", ["Yes" "No"], "modal");
                    
                    //if user wants to start a simulation, perform the simulation
                    if answerMsgSimulationPerform == 1 then
                        
                        global xmlAutopilot;
                        global xmlAutopilotFilePath;
                        global xmlAutopilotFileName;
                        SimulationExecuteJSBSimOrFlightGear(xmlSimulationStart, xmlSimulation, xmlReset, xmlAutopilot, xmlSimulationStartFilePath, xmlSimulationStartFileName, xmlSimulationFilePath, xmlSimulationFileName, xmlResetFilePath, xmlResetFileName, xmlAircraftFilePath, xmlAircratFileName, xmlAutopilotFilePath, xmlAutopilotFileName);
                        
                    end
                    
                    
                end
                
            else
                messagebox("Wrong format! The default new XML simulation start file does not contain any children XML elements (check templates" + filesep() + "Simulation_withoutAttributes" + filesep() + "simulation_start_template.xml)!", "modal", "error");
            end
            
        else
            messagebox("Wrong format! The default new XML file is not a valid simulation start file (check templates" + filesep() + "Simulation_withoutAttributes" + filesep() + "simulation_start_template.xml)!", "modal", "error");
        end
        
        
        
    end
    
    
endfunction




function OpenJSBSimOutputCSV_callback(handles)
    
    
    //show open dialog for JSBSim CSV output
    [fileName, pathName, filterIndex] = uigetfile( ["*.csv","CSV files"], "", "Open file with JSBSim CSV output", %f );
    
    //check if cancel button was not clicked
    if fileName ~= "" & pathName ~= "" & filterIndex ~= 0 then
        
        //read CSV file with JSBSim output
        pathOpenWhole = pathName + filesep() + fileName;
        [CSVHeaderJSBSimOutput, CSVvaluesJSBSimOutput] = ReadAndEvalCSVfile(pathOpenWhole);
        
        if size(CSVHeaderJSBSimOutput, 1) == 1 & CSVvaluesJSBSimOutput ~= [] then
            
            
            //show dialog with parameters of processing of the CSV data and for their plotting
            
            //load xml template file of CSV processing dialog parameters with default values
            xmlCSVProcessingDialog = xmlRead("templates" + filesep() + "Output" + filesep() + "CSV_processing_dialog_with_defaults.xml");
            errorString=ValidateXMLdocument(xmlCSVProcessingDialog);
            if xmlCSVProcessingDialog.root.attributes.time_start ~= [] then
                timeStart = xmlCSVProcessingDialog.root.attributes.time_start;
            else
                timeStart = "0";
            end
            if xmlCSVProcessingDialog.root.attributes.time_end ~= [] then
                timeEnd = xmlCSVProcessingDialog.root.attributes.time_end;
            else
                timeEnd = "%inf";
            end
            if xmlCSVProcessingDialog.root.attributes.number_of_graphs_in_line ~= [] then
                numberOfGraphsInLine = xmlCSVProcessingDialog.root.attributes.number_of_graphs_in_line;
            else
                numberOfGraphsInLine = "1";
            end
            if xmlCSVProcessingDialog.root.attributes.number_of_lines_in_window ~= [] then
                numberOfLinesInWindow = xmlCSVProcessingDialog.root.attributes.number_of_lines_in_window;
            else
                numberOfLinesInWindow = "1";
            end
            timeStartNumber = 0;
            timeEndNumber = %inf;
            numberOfGraphsInLineNumber = 1;
            numberOfLinesInWindowNumber = 1;
            
            
            parametersOK = %f;
            labelMain = ['Set elemental parameters for processing and plotting of CSV data' ; "(All parameters have to be numbers)"];
            labels = [ "Time Start (Cut) [s]" ; "Time End (Cut) [s]" ; "Number of Graphs in Line" ; "Number of Lines in Window" ]
            valuesOut = [ timeStart ; timeEnd ; numberOfGraphsInLine ; numberOfLinesInWindow];
            while parametersOK == %f then
                
                valuesOut = x_mdialog(labelMain, labels, valuesOut);
                if valuesOut ~= [] then
                    
                    
                    errorString = [];
                    //check if values from dialog are numbers
                    isCorrectTimeStart = isnum(valuesOut(1));
                    if isCorrectTimeStart == %t then
                        //convert string to number, if it successful, check value
                        timeStartNumber = strtod(valuesOut(1));
                        if string(timeStartNumber) ~= "Nan" then
                            if timeStartNumber < 0 then
                                errorString(size(errorString, 1) + 1) = "Time Start has to be higher than or equal to 0!";
                            end
                        else
                            errorString(size(errorString, 1) + 1) = "Time Start is not a valid number!";
                        end
                    else
                        errorString(size(errorString, 1) + 1) = "Time Start is not a number!";
                    end
                    isCorrectTimeEnd = isnum(valuesOut(2));
                    if isCorrectTimeEnd == %t then
                        //convert string to number, if it successful, check value
                        timeEndNumber = strtod(valuesOut(2));
                        if string(timeEndNumber) ~= "Nan" then
                            if timeEndNumber <= 0 then
                                errorString(size(errorString, 1) + 1) = "Time End has to be higher than 0!";
                            end
                        elseif convstr(strsubst(valuesOut(2), " ", ""), "l") == "%inf" then
                            timeEndNumber = %inf;
                        else
                            errorString(size(errorString, 1) + 1) = "Time End is not a valid number!";
                        end
                    else
                        errorString(size(errorString, 1) + 1) = "Time End is not a number!";
                    end
                    isCorrectNumberOfGraphsInLine = isnum(valuesOut(3));
                    if isCorrectNumberOfGraphsInLine == %t then
                        //convert string to number, if it successful, check value
                        numberOfGraphsInLineNumber = strtod(valuesOut(3));
                        if string(numberOfGraphsInLineNumber) ~= "Nan" then
                            numberOfGraphsInLineNumber = ceil(numberOfGraphsInLineNumber);
                            if numberOfGraphsInLineNumber <= 0 then
                                errorString(size(errorString, 1) + 1) = "Number of Graphs in Line has to be higher than 0!";
                            end
                        else
                            errorString(size(errorString, 1) + 1) = "Number of Graphs in Line is not a valid number!";
                        end
                    else
                        errorString(size(errorString, 1) + 1) = "Number of Graphs in Line is not a number!";
                    end
                    isCorrectNumberOfLinesInWindow = isnum(valuesOut(4));
                    if isCorrectNumberOfLinesInWindow == %t then
                        //convert string to number, if it successful, check value
                        numberOfLinesInWindowNumber = strtod(valuesOut(4));
                        if string(numberOfLinesInWindowNumber) ~= "Nan" then
                            numberOfLinesInWindowNumber = ceil(numberOfLinesInWindowNumber);
                            if numberOfLinesInWindowNumber <= 0 then
                                errorString(size(errorString, 1) + 1) = "Number of Lines in Window has to be higher than 0!";
                            end
                        else
                            errorString(size(errorString, 1) + 1) = "Number of Lines in Window is not a valid number!";
                        end
                    else
                        errorString(size(errorString, 1) + 1) = "Number of Lines in Window is not a number!";
                    end
                    
                    
                    if size(errorString, 1) > 0 then
                        messagebox(errorString, "modal", "error");
                    else
                        parametersOK = %t;
                        break;
                    end
                    
                else
                    
                    return;
                    
                end
                
            end
            
            
            //calculate number of windows - which depends on number of columns
            numberOfGraphsAll = size(CSVvaluesJSBSimOutput, 2) - 1;
            numberOfGraphsInWindow = numberOfGraphsInLineNumber * numberOfLinesInWindowNumber;
            numberOfWindows = ceil(numberOfGraphsAll / numberOfGraphsInWindow);
            //create and show all figures with a specific number of graphs in one window and with a specific number of graphs in one line
            for i = 1 : 1 : numberOfWindows
                
                //calculate start and end index for graphs' separation
                startIndex = (i - 1) * numberOfGraphsInWindow + 2;  //the first column is ignored because it contains the time data
                endIndex = numberOfGraphsAll + 1;
                if i ~= numberOfWindows then
                    endIndex = i * numberOfGraphsInWindow + 1;
                end
                
                //separate CSV values and CSV headers to parts depending on numberOfGraphsInWindow
                partCSVHeader = cat(2, CSVHeaderJSBSimOutput(:, 1), CSVHeaderJSBSimOutput(:, startIndex:endIndex));
                partCSVvalues = cat(2, CSVvaluesJSBSimOutput(:, 1), CSVvaluesJSBSimOutput(:, startIndex:endIndex));
                
                //create and show one figure with a specific number of graphs in the window and with a specific number of graphs in one line    //figureWith2DPlots = 
                CreateAndShowFigureWithJSBsimResultsIn2DPlots(partCSVHeader, partCSVvalues, timeStartNumber, timeEndNumber, numberOfGraphsInLineNumber);
                
            end
            
            
        else
            
            messagebox("Wrong format! The file is not a valid CSV file!", "modal", "error");
            
        end
        
    end
    
    
endfunction



function SetControlComponentUsingZieglerNicholsCriticalParametersTables_callback(handles)
    
    global xmlAutopilot;
    
    //show dialog with all adjustable control components
    [xmlAutopilotAdjustableComponent] = DialogSelectAdjustableControlComponentOkCancel(xmlAutopilot);
    if xmlAutopilotAdjustableComponent ~= [] then
        
        
        //get selected adjustable control component from autopilot
        [outXmlAutopilotAdjustableComponentFromAutopilot, xmlChannelChildrenIndexAutopilotAdjustableComponent, xmlAutopilotAdjustableComponentIndexChildrenChannel] = GetSelectedAdjustableComponentFromAutopilot(xmlAutopilot, xmlAutopilotAdjustableComponent);
        
        
        //show dialog for selecting a Ziegler-Nichols with critical parameters rule to set the adjustable control component
        [zieglerNicholsRuleName] = DialogZieglerNicholsCriticalParametersTablesOkCancel();
        if zieglerNicholsRuleName ~= [] then
            
            
            //get (or create) xml element of gain, integral, and derivative from the adjustable control component
            [KP_GainXmlElement, KI_IntegralXmlElement, KD_DerivativeXmlElement] = GetKpKiKdXMLelementsFromAdjustableComponentInAutopilot(xmlAutopilot, outXmlAutopilotAdjustableComponentFromAutopilot);
            
            
            //get gain and period values or show dialog for user to put these values
            gainCritical = "Nan";
            T_criticalPeriod = "Nan";
            xmlCriticalGain = FindFirstXMLElementInFirstChildrenOfXMLElement(outXmlAutopilotAdjustableComponentFromAutopilot, "critical_gain");
            xmlCriticalPeriod = FindFirstXMLElementInFirstChildrenOfXMLElement(outXmlAutopilotAdjustableComponentFromAutopilot, "critical_period");
            if xmlCriticalGain ~= [] & xmlCriticalPeriod ~= [] & isnum(xmlCriticalGain.content) == %t & isnum(xmlCriticalPeriod.content) == %t then
                gainCritical = strtod(xmlCriticalGain.content);
                T_criticalPeriod = strtod(xmlCriticalPeriod.content);
            end
            if xmlCriticalGain == [] | xmlCriticalPeriod == [] | string(gainCritical) == "Nan" | string(T_criticalPeriod) == "Nan" then
                
                
                initialGainCritical = "<unknown>";
                initialT_criticalPeriod = "<unknown>";
                if xmlCriticalGain ~= [] & string(gainCritical) ~= "Nan" then
                    initialGainCritical = string(gainCritical);
                end
                if xmlCriticalPeriod ~= [] & string(T_criticalPeriod) ~= "Nan" then
                    initialT_criticalPeriod = string(T_criticalPeriod);
                end
                
                
                parametersOK = %f;
                labelMain = ['Critical Gain or Critical Period (or both) was (were) not found in selected adjustable control component' ; "(All parameters have to be numbers)"];
                labels = [ "Critical Gain" ; "Critical Period [s]" ]
                valuesOut = [ initialGainCritical ; initialT_criticalPeriod ];
                while parametersOK == %f then
                    
                    valuesOut = x_mdialog(labelMain, labels, valuesOut);
                    if valuesOut ~= [] then
                        
                        
                        errorString = [];
                        //check if values from dialog are numbers
                        isGainCritical = isnum(valuesOut(1));
                        if isGainCritical == %t then
                            //convert string to number, if it successful, check value
                            gainCritical = strtod(valuesOut(1));
                            if string(gainCritical) ~= "Nan" then
                                if gainCritical == 0 then
                                    errorString(size(errorString, 1) + 1) = "Critical Gain must NOT be equal to 0!";
                                end
                            else
                                errorString(size(errorString, 1) + 1) = "Critical Gain is not a valid number!";
                            end
                        else
                            errorString(size(errorString, 1) + 1) = "Critical Gain is not a number!";
                        end
                        isCorrectT_criticalPeriod = isnum(valuesOut(2));
                        if isCorrectT_criticalPeriod == %t then
                            //convert string to number, if it successful, check value
                            T_criticalPeriod = strtod(valuesOut(2));
                            if string(T_criticalPeriod) ~= "Nan" then
                                if T_criticalPeriod <= 0 then
                                    errorString(size(errorString, 1) + 1) = "Critical Period has to be higher than 0!";
                                end
                            else
                                errorString(size(errorString, 1) + 1) = "Critical Period is not a valid number!";
                            end
                        else
                            errorString(size(errorString, 1) + 1) = "Critical Period is not a number!";
                        end
                        
                        
                        if size(errorString, 1) > 0 then
                            messagebox(errorString, "modal", "error");
                        else
                            parametersOK = %t;
                            break;
                        end
                        
                    else
                        
                        return;
                        
                    end
                    
                end
                
//                //create critical_gain xml element
//                xmlCriticalGain = FindXMLElementInFirstChildrenOfXMLElementOrCreateIt(xmlAutopilot, outXmlAutopilotAdjustableComponentFromAutopilot, "critical_gain");
//                xmlCriticalGain.content = string(gainCritical);
//                //create critical_period xml element
//                xmlCriticalPeriod = FindXMLElementInFirstChildrenOfXMLElementOrCreateIt(xmlAutopilot, outXmlAutopilotAdjustableComponentFromAutopilot, "critical_period");
//                xmlCriticalPeriod.content = string(T_criticalPeriod);
                
            end
            
            
            //set PID or gain parameters using a selected rule of Ziegler-Nichols method with critical parameters
            SetPIDparametersUsingZieglerNicholsCriticalParametersTables(KP_GainXmlElement, KI_IntegralXmlElement, KD_DerivativeXmlElement, zieglerNicholsRuleName, gainCritical, T_criticalPeriod);
            
            
        end
        
    end
    
endfunction



function GetAllControlComponentAdjustmentsUsingZieglerNicholsCriticalParametersTables_callback(handles)
    
    global xmlAutopilot;
    
    //show dialog with all adjustable control components
    [xmlAutopilotAdjustableComponent] = DialogSelectAdjustableControlComponentOkCancel(xmlAutopilot);
    if xmlAutopilotAdjustableComponent ~= [] then
        
        
        //get selected adjustable control component from autopilot
        [outXmlAutopilotAdjustableComponentFromAutopilot, xmlChannelChildrenIndexAutopilotAdjustableComponent, xmlAutopilotAdjustableComponentIndexChildrenChannel] = GetSelectedAdjustableComponentFromAutopilot(xmlAutopilot, xmlAutopilotAdjustableComponent);
        
        
        
        //get gain and period values or show dialog for user to put these values
        gainCritical = "Nan";
        T_criticalPeriod = "Nan";
        xmlCriticalGain = FindFirstXMLElementInFirstChildrenOfXMLElement(outXmlAutopilotAdjustableComponentFromAutopilot, "critical_gain");
        xmlCriticalPeriod = FindFirstXMLElementInFirstChildrenOfXMLElement(outXmlAutopilotAdjustableComponentFromAutopilot, "critical_period");
        if xmlCriticalGain ~= [] & xmlCriticalPeriod ~= [] & isnum(xmlCriticalGain.content) == %t & isnum(xmlCriticalPeriod.content) == %t then
            gainCritical = strtod(xmlCriticalGain.content);
            T_criticalPeriod = strtod(xmlCriticalPeriod.content);
        end
        if xmlCriticalGain == [] | xmlCriticalPeriod == [] | string(gainCritical) == "Nan" | string(T_criticalPeriod) == "Nan" then
            
            
            initialGainCritical = "<unknown>";
            initialT_criticalPeriod = "<unknown>";
            if xmlCriticalGain ~= [] & string(gainCritical) ~= "Nan" then
                initialGainCritical = string(gainCritical);
            end
            if xmlCriticalPeriod ~= [] & string(T_criticalPeriod) ~= "Nan" then
                initialT_criticalPeriod = string(T_criticalPeriod);
            end
            
            
            parametersOK = %f;
            labelMain = ['Critical Gain or Critical Period (or both) was (were) not found in selected adjustable control component' ; "(All parameters have to be numbers)"];
            labels = [ "Critical Gain" ; "Critical Period [s]" ]
            valuesOut = [ initialGainCritical ; initialT_criticalPeriod ];
            while parametersOK == %f then
                
                valuesOut = x_mdialog(labelMain, labels, valuesOut);
                if valuesOut ~= [] then
                    
                    
                    errorString = [];
                    //check if values from dialog are numbers
                    isGainCritical = isnum(valuesOut(1));
                    if isGainCritical == %t then
                        //convert string to number, if it successful, check value
                        gainCritical = strtod(valuesOut(1));
                        if string(gainCritical) ~= "Nan" then
                            if gainCritical == 0 then
                                errorString(size(errorString, 1) + 1) = "Critical Gain must NOT be equal to 0!";
                            end
                        else
                            errorString(size(errorString, 1) + 1) = "Critical Gain is not a valid number!";
                        end
                    else
                        errorString(size(errorString, 1) + 1) = "Critical Gain is not a number!";
                    end
                    isCorrectT_criticalPeriod = isnum(valuesOut(2));
                    if isCorrectT_criticalPeriod == %t then
                        //convert string to number, if it successful, check value
                        T_criticalPeriod = strtod(valuesOut(2));
                        if string(T_criticalPeriod) ~= "Nan" then
                            if T_criticalPeriod <= 0 then
                                errorString(size(errorString, 1) + 1) = "Critical Period has to be higher than 0!";
                            end
                        else
                            errorString(size(errorString, 1) + 1) = "Critical Period is not a valid number!";
                        end
                    else
                        errorString(size(errorString, 1) + 1) = "Critical Period is not a number!";
                    end
                    
                    
                    if size(errorString, 1) > 0 then
                        messagebox(errorString, "modal", "error");
                    else
                        parametersOK = %t;
                        break;
                    end
                    
                else
                    
                    return;
                    
                end
                
            end
                
//            //create critical_gain xml element
//            xmlCriticalGain = FindXMLElementInFirstChildrenOfXMLElementOrCreateIt(xmlAutopilot, outXmlAutopilotAdjustableComponentFromAutopilot, "critical_gain");
//            xmlCriticalGain.content = string(gainCritical);
//            //create critical_period xml element
//            xmlCriticalPeriod = FindXMLElementInFirstChildrenOfXMLElementOrCreateIt(xmlAutopilot, outXmlAutopilotAdjustableComponentFromAutopilot, "critical_period");
//            xmlCriticalPeriod.content = string(T_criticalPeriod);
            
        end
        
        
        
        //get global list of all rule names of Ziegler-Nichols with critical parameters
        global zieglerNicholsRulesNames;
        if length(zieglerNicholsRulesNames) > 0 then
            
            messageStringArray = [ "The following [P, I, D] adjustments are possible using Ziegler-Nichols method with critical parameters." ; "(""-Inf"" value means that the calculation failed)" ; emptystr() ];
            pidAdjustmentsList = list();
            for i = 1 : 1 : length(zieglerNicholsRulesNames)
                
                //get PID parameters for the specific Ziegler-Nichols rule
                PIDValuesArray = GetPIDparametersUsingZieglerNicholsCriticalParametersTables(zieglerNicholsRulesNames(i), gainCritical, T_criticalPeriod);
                //add PID array with values to complete PID adjustment list
                pidAdjustmentsList($+1) = PIDValuesArray;
                //add information to message string
                messageStringArray(size(messageStringArray, 1) + 1) = "PID values of " + zieglerNicholsRulesNames(i) + ": " + ascii(9) + "[" + strcat(string(PIDValuesArray), ", ") + "]";
                
            end
            
            messageStringArray(size(messageStringArray, 1) + 1) = emptystr();
            //create complete PID matrix with all rules of Ziegler-Nichols adjustment method, for Genetic Algorithm purpose
            pidMatrixCompleteString = "[ ";
            if length(pidAdjustmentsList) > 0 then
                pidMatrixCompleteString = pidMatrixCompleteString + "[" + strcat(string(pidAdjustmentsList(1)), ", ") + "]";
            end
            for i = 2 : 1 : length(pidAdjustmentsList)
                pidMatrixCompleteString = pidMatrixCompleteString + " ; ";
                pidMatrixCompleteString = pidMatrixCompleteString + "[" + strcat(string(pidAdjustmentsList(i)), ", ") + "]";
            end
            pidMatrixCompleteString = pidMatrixCompleteString + " ]";
            messageStringArray(size(messageStringArray, 1) + 1) = "Matrix for initial purpose in Genetic Algorithm:";
            messageStringArray(size(messageStringArray, 1) + 1) = pidMatrixCompleteString;
            
            
            messagebox(messageStringArray, "modal", "info");
            
            
        else
            messagebox("List with Ziegler-Nichols method rules was not loaded properly, check ""templates\Control_Design\ziegler_nichols_rules.xml"" file with the rules!", "modal", "error");
            return;
        end
        
        
    end
    
endfunction



function AboutApplication_callback(handles)
    
    messagebox(["Control System Designer for JSBSim (v 0.6.25)" ; "GNU LESSER GENERAL PUBLIC LICENSE (LGPL) version 3 (see ""GNU LESSER GENERAL PUBLIC LICENSE.txt"" file or ""https://www.gnu.org/licenses/lgpl.txt"")" ; "If you use this application in your project, please, cite the following paper:" ; "Vogeltanz, Tomáš. 2018. Development of Control System Designer for JSBSim FDM. AIP Conference Proceedings, vol. 1978 : 060019. ISSN: 0094-243X. DOI: 10.1063/1.5043721" ; emptystr() ; "Developed by:" ; "Tomas Vogeltanz ©2016-forever" ; "Tomas Bata University" ; "tom.vogeltanz@gmail.com" ; "vogeltanz@utb.cz" ; "https://github.com/vogeltanz" ; emptystr() ; ], "modal", "info");
    
endfunction



//function AnalyzeStabilityOfControlComponent_callback(handles)
//    
//    //<> <>
//    
//endfunction







//initialize new autopilot file
NewAutopilot_callback(handles);

