/*
 * Scone - The Web Enhancement Framework
 * Copyright (c) 2004 Harald Weinreich, Volkert Buchmann, Frank Wollenweber, Torsten Haß
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package scone.usertesttool;

import java.util.ArrayList;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import scone.util.ErrorLog;

/**
 * This object stores information about the current user test task
 *
 * @author Torsten Hass
 * @version 1.1, 11/7/2003
 */
public class Task {
    
    private boolean caseSensitive = true; // Search for xml node names and attribute names should be case sensitive
    private String title = "";
    private String taskName = "";

    private ArrayList components;
    
    private TaskPanel panel = null;
    private UserTestControl utc;
        
    
    /**
     * This constructor searches the xml-document for the n-th task 
     * node, reads its information and creates a Panel out of this 
     * information.
     *
     * @param userTestXml   The xml-node that points to usertest
     * @param taskNumber    The number of the wanted task-node
     * @param utc           The UserTestControl object that will receive the button click events
     */
    public Task (Node userTextXml, int taskNumber, UserTestControl utc) {
        this.utc = utc;
        xmlTaskToPanel(userTextXml, taskNumber);
    }
    
    public Task (Node userTextXml, int taskNumber, UserTestControl utc, boolean caseSensitive) {
        this.utc = utc;
        this.caseSensitive = caseSensitive;
        xmlTaskToPanel(userTextXml, taskNumber);
    }

    public void xmlTaskToPanel (Node userTestXml, int taskNumber) {
        panel = new TaskPanel ();           // A Panel containing one complete Task with all its texts, buttons and input possabilities
        components = new ArrayList();       // List of Component names and Components, that have to be accessed later. e. g. to disable a button


        try {
            NodeList nodeList = userTestXml.getChildNodes();
    
            // look for the n-th task in xml file
            int i = 0;
            int foundTask = 0;
            
            while ((i < nodeList.getLength()) && (foundTask != taskNumber)) {
    //            outputDebugInfo("Task: "+nodeList.item(i).getNodeName());
                if ((nodeList.item(i).getNodeName().equals("task")) ||
                    (nodeList.item(i).getNodeName().toLowerCase().equals("task") && !caseSensitive)) {
                    foundTask++;
                    if (foundTask == taskNumber) {
                    // found the n-th task
                        taskName = getAttribByName("name", nodeList.item(i)); 
                        outputDebugInfo("Task: TaskName=" + taskName);
    //                    outputDebugInfo("Task Nummer "+taskNumber+" gefunden");
                        NodeList nList = nodeList.item(i).getChildNodes();
                        int j = 0;
                        while (j < nList.getLength()) {
                        // walk through the nodes of the n-th task
                            outputDebugInfo("Task:   "+nList.item(j).getNodeName());
                            if (equalsNodeName(nList.item(j), "title")) {
                            // title
                                title = getText(nList.item(j));
                                outputDebugInfo("Task:     Title=" + title);
                            } else if (equalsNodeName(nList.item(j), "text")) {
                            // text
                                int bottomPadding = 10;
                                panel.addHtml(getHtmlText(nList.item(j)), (int)utc.getTaskWindow().getSize().getWidth());
                                try {
                                    bottomPadding = (Integer.parseInt(getAttribByName("bottomPadding", nList.item(j))));
                                    outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", nList.item(j)));
                                } catch (NumberFormatException e) {
                                }
                                if (bottomPadding > 0) {
                                    panel.addPadding(bottomPadding);
                                }
                                outputDebugInfo("Task:     Text=" + getText(nList.item(j)));
                            } else if (equalsNodeName(nList.item(j), "button")) {
                            // Button
                                UTButton button = new UTButton(utc);
                                button.setComponentName(getAttribByName("name", nList.item(j)));
                                getButtonProperties(button, nList.item(j));
                                components.add(button);
                                panel.addItem(button);
                            } else if (equalsNodeName(nList.item(j), "textField")) {
                            // textField
                                UTTextField textField = new UTTextField(utc);
                                textField.setComponentName(getAttribByName("name", nList.item(j)));
                                getTextFieldProperties(textField, nList.item(j));
                                components.add(textField);
                                panel.addItem(textField);
                            } else if (equalsNodeName(nList.item(j), "dropDownBox")) {
                            // DropDownBox
                                UTDropDownBox dropDownBox = new UTDropDownBox(utc);
                                dropDownBox.setComponentName(getAttribByName("name", nList.item(j)));
                                getDropDownBoxProperties(dropDownBox, nList.item(j));
                                components.add(dropDownBox);
                                panel.addItem(dropDownBox);
                            } else if (equalsNodeName(nList.item(j), "slider")) {
                            // JSlider
                                UTSlider slider = new UTSlider(utc);
                                slider.setComponentName(getAttribByName("name", nList.item(j)));
                                getSliderProperties(slider, nList.item(j));
                                components.add(slider);
                                panel.addItem(slider);
                            } else if (equalsNodeName(nList.item(j), "likertScale")) {
                            // likertScale
                                UTLikertScale likertScale = new UTLikertScale();
                                likertScale.setComponentName(getAttribByName("name", nList.item(j)));
                                getLikertScaleProperties(likertScale, nList.item(j));
                                components.add(likertScale);
                                panel.addItem(likertScale);
                            } else if (equalsNodeName(nList.item(j), "useTemplate")) {
                            // useTemplate
                                outputDebugInfo("Task:     useTemplate name=" + getAttribByName("name", nList.item(j)));
                                componentsFromTemplate(nList.item(j).getChildNodes(), getAttribByName("name", nList.item(j)), userTestXml);
                            }
                            j++;
                        }
                    }
                }
                i++;
            }
        } catch (Exception e) {
    //        e.printStackTrace();
            ErrorLog.log(this, "xmlTaskToPanel", "Error while converting xml to Task:\n", e);
        }
    }           
    

    private void componentsFromTemplate (NodeList taskComps, String templateName, Node userTestXml) {
        
        try {
            NodeList nodeList = userTestXml.getChildNodes();         // set nodeList to all layout nodes
            int i=0; 
            boolean found = false;
            while ((i<nodeList.getLength()) && (!found)) {                            // look for the first and only layout section
                if (nodeList.item(i).getNodeName().equals("layout")) {
                    found = true;
                    nodeList = nodeList.item(i).getChildNodes();
                } else {
                    i++;
                }
            }
            if (found) {                                                                                    // if layout section was found
                for (i=0; i<nodeList.getLength(); i++) {                                                    // for every node in layout section
                    if (nodeList.item(i).getNodeName().equals("template") &&                                // if the searched template node is found
                        (getAttribByName("name", nodeList.item(i)).equals(templateName))) {                     
                        if (nodeList.item(i).getChildNodes().getLength() >=1) {                             // if it has 1 or more entries
                            NodeList templateComps = nodeList.item(i).getChildNodes();                      // set templateComps to the list of entries
                            outputDebugInfo("Template gefunden");
                            int j = 0;
                            while (j < templateComps.getLength()) {                                         // for every template entry
                            // walk through the nodes of the template area
                                outputDebugInfo("Task:   "+templateComps.item(j).getNodeName());
                                if (equalsNodeName(templateComps.item(j), "title")) {
                                // title
                                    title = getText(templateComps.item(j));
                                    // check if there is an other text in the task section
                                    Node node = getNodeByTagNameAndNameAttrib(taskComps, "title", "");
                                    if (node != null) {
                                        if (!getText(node).equals("")) {
                                            title = getText(node);
                                        }
                                    }
                                    outputDebugInfo("Task:     Title=" + title);
                                } else if (equalsNodeName(templateComps.item(j), "text")) {
                                // text
                                    String textStr = getHtmlText(templateComps.item(j));
                                    int bottomPadding = 10;
                                    try {
                                        bottomPadding = (Integer.parseInt(getAttribByName("bottomPadding", templateComps.item(j))));
                                        outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", templateComps.item(j)));
                                    } catch (NumberFormatException e) {
                                    }
                                    Node node = getNodeByTagNameAndNameAttrib(taskComps, "text", getAttribByName("name", templateComps.item(j)));
                                    if (node != null) {                                         // if button node exists in task section
                                        if (node.hasChildNodes()) {
                                            textStr = getHtmlText(node);
                                        } 
                                        try {
                                            bottomPadding = (Integer.parseInt(getAttribByName("bottomPadding", node)));
                                            outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", node));
                                        } catch (NumberFormatException e) {
                                        }
                                    }                                    
                                    panel.addHtml(textStr, (int)utc.getTaskWindow().getSize().getWidth());
                                    if (bottomPadding > 0) {
                                        panel.addPadding(bottomPadding);
                                    }
                                    outputDebugInfo("Task:     Text=" + textStr);
                                } else if (equalsNodeName(templateComps.item(j), "button")) {
                                // Button
                                    UTButton button = new UTButton(utc);
                                    getButtonProperties(button, templateComps.item(j));
                                    Node node = getNodeByTagNameAndNameAttrib(taskComps, "button", getAttribByName("name", templateComps.item(j)));
                                    if (node != null) {                                         // if button node exists in task section
                                        getButtonProperties(button, node);                      // get new properties
                                        button.setComponentName(getAttribByName("name", node));
                                        components.add(button);  // insert component with new name
                                    } else {
                                        button.setComponentName(getAttribByName("name", templateComps.item(j)));
                                        components.add(button);
                                    }                                    
                                    panel.addItem(button);
                                } else if (equalsNodeName(templateComps.item(j), "textField")) {
                                // textField
                                    UTTextField textField = new UTTextField(utc);
//System.out.println("Template Properties auslesen");                                    
                                    getTextFieldProperties(textField, templateComps.item(j));
                                    Node node = getNodeByTagNameAndNameAttrib(taskComps, "textField", getAttribByName("name", templateComps.item(j)));
                                    if (node != null) {                                         // if textfield node exists in task section
//System.out.println("Task Properties auslesen");                                    
                                        getTextFieldProperties(textField, node);
                                        textField.setComponentName(getAttribByName("name", node));
                                        components.add(textField);
                                    } else {
                                        textField.setComponentName(getAttribByName("name", templateComps.item(j)));
                                        components.add(textField);
                                    }
                                    panel.addItem(textField);
                                } else if (equalsNodeName(templateComps.item(j), "dropDownBox")) {
                                // DropDownBox
                                    UTDropDownBox dropDownBox = new UTDropDownBox(utc);
                                    getDropDownBoxProperties(dropDownBox, templateComps.item(j));
                                    Node node = getNodeByTagNameAndNameAttrib(taskComps, "dropDownBox", getAttribByName("name", templateComps.item(j)));
                                    if (node != null) {                                         // if DropDownBox node exists in task section
                                        getDropDownBoxProperties(dropDownBox, node);
                                        dropDownBox.setComponentName(getAttribByName("name", node));
                                        components.add(dropDownBox);
                                    } else {
                                        dropDownBox.setComponentName(getAttribByName("name", templateComps.item(j)));
                                        components.add(dropDownBox);
                                    }
                                    panel.addItem(dropDownBox);
                                } else if (equalsNodeName(templateComps.item(j), "slider")) {
                                // DropDownBox
                                    UTSlider slider = new UTSlider(utc);
                                    getSliderProperties(slider, templateComps.item(j));
                                    Node node = getNodeByTagNameAndNameAttrib(taskComps, "slider ", getAttribByName("name", templateComps.item(j)));
                                    if (node != null) {                                         // if DropDownBox node exists in task section
                                        getSliderProperties(slider, node);
                                        slider.setComponentName(getAttribByName("name", node));
                                        components.add(slider);
                                    } else {
                                        slider.setComponentName(getAttribByName("name", templateComps.item(j)));
                                        components.add(slider);
                                    }
                                    panel.addItem(slider);
                                } else if (equalsNodeName(templateComps.item(j), "likertScale")) {
                                // likertScale
                                    UTLikertScale likertScale = new UTLikertScale();
                                    getLikertScaleProperties(likertScale, templateComps.item(j));
                                    Node node = getNodeByTagNameAndNameAttrib(taskComps, "likertScale", getAttribByName("name", templateComps.item(j)));
                                    if (node != null) {                                         // if likertScale node exists in task section
                                        getLikertScaleProperties(likertScale, node);
                                        likertScale.setComponentName(getAttribByName("name", node));
                                        components.add(likertScale);
                                    } else {
                                        likertScale.setComponentName(getAttribByName("name", templateComps.item(j)));
                                        components.add(likertScale);
                                    }
                                    panel.addItem(likertScale);
                                }
                                j++;
                            }
                        }
                    }
                }
            } else {                                                                                            
                // layout section was not found
                System.out.println("");
                System.out.println("Scone: UserTestTool");
                System.out.println("");
                System.out.println("Eroor: The XML file that controls the current user test refers to template");
                System.out.println(templateName + ". However, in this XML file no \"layout\" section can");
                System.out.println("be found in the \"userTest\" element, that defines the ");
                System.out.println("required templates.");
                System.out.println("");
            }                
        } catch (Exception e) {
            ErrorLog.log(this, "componentsFromTemplate", "Error while converting xml to Task:\n", e);
        }
    }
    


    /**
     * This method looks through the attributes and child nodes to get infor-
     * mation about the look of the Button, it's text and the actions that
     * have to be done on button click
     *
     * @param button The UTButton object
     * @param node The node describing the button in the xml file
     */
    private void getButtonProperties (UTButton button, Node node) {
        
        outputDebugInfo("Task:     name=" + getAttribByName("name", node));
        button.setName(getAttribByName("name", node));
        if (getAttribByNameOrReturnNull("text", node) != null) {
            button.setText(getAttribByName("text", node));
            outputDebugInfo("Task:     text=" + getAttribByName("text", node));
        }
        if (getAttribByNameOrReturnNull("enabled", node) != null) {
            if (getAttribByName("enabled", node).toLowerCase().equals("false")) {
                button.setComponentEnabled(false);
                outputDebugInfo("Task:     enabled=\"false\"");
            }
            if (getAttribByName("enabled", node).toLowerCase().equals("true")) {
                button.setComponentEnabled(true);
                outputDebugInfo("Task:     enabled=\"true\"");
            }
        }
        if (getAttribByNameOrReturnNull("highlighted", node) != null) {
            if (getAttribByName("highlighted", node).toLowerCase().equals("true")) {
                button.setComponentHighlighted(true);
                outputDebugInfo("Task:     highlighted=\"true\"");
            }
            if (getAttribByName("highlighted", node).toLowerCase().equals("false")) {
                button.setComponentHighlighted(false);
                outputDebugInfo("Task:     highlighted=\"false\"");
            }
        }
        try {
            button.setComponentBottomPadding(Integer.parseInt(getAttribByName("bottomPadding", node)));
            outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", node));
        } catch (NumberFormatException e) {
        }
        readActions(button, node);
    }

    /**
     * This method looks through the attributes and child nodes to get infor-
     * mation about the look of the TextField, it's text and it's description.
     *
     * @param textField The UTTextField object
     * @param node The node describing the textField in the xml file
     */
    private void getTextFieldProperties (UTTextField textField, Node node) {
        outputDebugInfo("Task:     name=" + getAttribByName("name", node));
        textField.setName(getAttribByName("name", node));
        if (getAttribByNameOrReturnNull("text", node) != null) {
            textField.setDescription(getAttribByName("text", node));
            outputDebugInfo("Task:     text=" + getAttribByName("text", node));
        }
        if (getAttribByNameOrReturnNull("description", node) != null) {
            textField.setDescription(getAttribByName("description", node));
            outputDebugInfo("Task:     description=" + getAttribByName("description", node));
        }
        if (getAttribByNameOrReturnNull("height", node) != null) {
            try {
                textField.setHeight(Integer.parseInt(getAttribByName("height", node)));
                outputDebugInfo("Task:     height=" + getAttribByName("height", node));
            } catch (NumberFormatException e) {
            }
        }
        if (getAttribByNameOrReturnNull("required", node) != null) {
            if (getAttribByName("required", node).toLowerCase().equals("true")) {
                textField.setInputRequired(true);
                outputDebugInfo("Task:     required=\"true\"");
            }
            if (getAttribByName("required", node).toLowerCase().equals("false")) {
                textField.setInputRequired(false);
                outputDebugInfo("Task:     required=\"false\"");
            }
        }
        if (getAttribByNameOrReturnNull("enabled", node) != null) {
            if (getAttribByName("enabled", node).toLowerCase().equals("false")) {
                textField.setComponentEnabled(false);
                outputDebugInfo("Task:     enabled=\"false\"");
            }
            if (getAttribByName("enabled", node).toLowerCase().equals("true")) {
                textField.setComponentEnabled(true);
                outputDebugInfo("Task:     enabled=\"true\"");
            }
        }
        if (getAttribByNameOrReturnNull("highlighted", node) != null) {
            if (getAttribByName("highlighted", node).toLowerCase().equals("true")) {
                textField.setComponentHighlighted(true);
                outputDebugInfo("Task:     highlighted=\"true\"");
            }
            if (getAttribByName("highlighted", node).toLowerCase().equals("false")) {
                textField.setComponentHighlighted(false);
                outputDebugInfo("Task:     highlighted=\"false\"");
            }
        }
        try {
            textField.setComponentBottomPadding(Integer.parseInt(getAttribByName("bottomPadding", node)));
            outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", node));
        } catch (NumberFormatException e) {
        }
//        readActions((DataComponentInterface)textField, nList.item(j));
    }

    /**
     * This method looks through the attributes and child nodes to get infor-
     * mation about the look of the DropDownBox, it's text and it's description.
     *
     * @param button The UTDropDownBox object
     * @param node The node describing the DropDownBox in the xml file
     */
    private void getDropDownBoxProperties (UTDropDownBox dropDownBox, Node node) {
        outputDebugInfo("Task:     name=" + getAttribByName("name", node));
        dropDownBox.setName(getAttribByName("name", node));
        if (getAttribByNameOrReturnNull("description", node) != null) {
            dropDownBox.setDescription(getAttribByName("description", node));
            outputDebugInfo("Task:     description=" + getAttribByName("description", node));
        }
        if (getAttribByNameOrReturnNull("required", node) != null) {
            if (getAttribByName("required", node).toLowerCase().equals("true")) {
                dropDownBox.setInputRequired(true);
                outputDebugInfo("Task:     required=\"true\"");
            }
            if (getAttribByName("required", node).toLowerCase().equals("false")) {
                dropDownBox.setInputRequired(false);
                outputDebugInfo("Task:     required=\"false\"");
            }
        }
        if (getAttribByNameOrReturnNull("enabled", node) != null) {
            if (getAttribByName("enabled", node).toLowerCase().equals("false")) {
                dropDownBox.setComponentEnabled(false);
                outputDebugInfo("Task:     enabled=\"false\"");
            }
            if (getAttribByName("enabled", node).toLowerCase().equals("true")) {
                dropDownBox.setComponentEnabled(true);
                outputDebugInfo("Task:     enabled=\"true\"");
            }
        }
        if (getAttribByNameOrReturnNull("highlighted", node) != null) {
            if (getAttribByName("highlighted", node).toLowerCase().equals("true")) {
                dropDownBox.setComponentHighlighted(true);
                outputDebugInfo("Task:     highlighted=\"true\"");
            }
            if (getAttribByName("highlighted", node).toLowerCase().equals("false")) {
                dropDownBox.setComponentHighlighted(false);
                outputDebugInfo("Task:     highlighted=\"false\"");
            }
        }
        try {
            dropDownBox.setComponentBottomPadding(Integer.parseInt(getAttribByName("bottomPadding", node)));
            outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", node));
        } catch (NumberFormatException e) {
        }
        readItems(dropDownBox, node);
    }

    /**
     * This method looks through the attributes and child nodes to get infor-
     * mation about the look of the Slider, it's text and it's description.
     *
     * @param slider The UTSlider object
     * @param node The node describing the Slider in the xml file
     */
    private void getSliderProperties (UTSlider slider, Node node) {
        outputDebugInfo("Task:     Slider: name=" + getAttribByName("name", node));
        slider.setName(getAttribByName("name", node));
        if (getAttribByNameOrReturnNull("description", node) != null) {
            slider.setDescription(getAttribByName("description", node));
            outputDebugInfo("Task:     description=" + getAttribByName("description", node));
        }
        try {
            slider.setMajorTickSpacing(Integer.parseInt(getAttribByName("majorTickSpacing", node)));
            outputDebugInfo("Task:     majorTickSpacing=" + getAttribByName("majorTickSpacing", node));
        } catch (NumberFormatException e) {
        }
        try {
            slider.setMinorTickSpacing(Integer.parseInt(getAttribByName("minorTickSpacing", node)));
            outputDebugInfo("Task:     minorTickSpacing=" + getAttribByName("minorTickSpacing", node));
        } catch (NumberFormatException e) {
        }
        try {
            slider.setMinimum(Integer.parseInt(getAttribByName("minimum", node)));
            outputDebugInfo("Task:     minimum=" + getAttribByName("minimum", node));
        } catch (NumberFormatException e) {
        }
        try {
            slider.setMaximum(Integer.parseInt(getAttribByName("maximum", node)));
            outputDebugInfo("Task:     maximum=" + getAttribByName("maximum", node));
        } catch (NumberFormatException e) {
        }
        try {
            slider.setDefault(Integer.parseInt(getAttribByName("default", node)));
            outputDebugInfo("Task:     default=" + getAttribByName("default", node));
        } catch (NumberFormatException e) {
        }
        if (getAttribByNameOrReturnNull("snapToTicks", node) != null) {
            if (getAttribByName("snapToTicks", node).toLowerCase().equals("true")) {
                slider.setSnapToTicks(true);
                outputDebugInfo("Task:     snapToTicks=\"true\"");
            }
            if (getAttribByName("snapToTicks", node).toLowerCase().equals("false")) {
                slider.setSnapToTicks(false);
                outputDebugInfo("Task:     snapToTicks=\"false\"");
            }
        }
        if (getAttribByNameOrReturnNull("paintLabels", node) != null) {
            if (getAttribByName("paintLabels", node).toLowerCase().equals("true")) {
                slider.setPaintLabels(true);
                outputDebugInfo("Task:     paintLabels=\"true\"");
            }
            if (getAttribByName("paintLabels", node).toLowerCase().equals("false")) {
                slider.setPaintLabels(false);
                outputDebugInfo("Task:     paintLabels=\"false\"");
            }
        }
        // Create the slider with these parameters!
        slider.createSlider();

        if (getAttribByNameOrReturnNull("required", node) != null) {
            if (getAttribByName("required", node).toLowerCase().equals("true")) {
                slider.setInputRequired(true);
                outputDebugInfo("Task:     required=\"true\"");
            }
            if (getAttribByName("required", node).toLowerCase().equals("false")) {
                slider.setInputRequired(false);
                outputDebugInfo("Task:     required=\"false\"");
            }
        }
        if (getAttribByNameOrReturnNull("enabled", node) != null) {
            if (getAttribByName("enabled", node).toLowerCase().equals("false")) {
                slider.setComponentEnabled(false);
                outputDebugInfo("Task:     enabled=\"false\"");
            }
            if (getAttribByName("enabled", node).toLowerCase().equals("true")) {
                slider.setComponentEnabled(true);
                outputDebugInfo("Task:     enabled=\"true\"");
            }
        }
        if (getAttribByNameOrReturnNull("highlighted", node) != null) {
            if (getAttribByName("highlighted", node).toLowerCase().equals("true")) {
                slider.setComponentHighlighted(true);
                outputDebugInfo("Task:     highlighted=\"true\"");
            }
            if (getAttribByName("highlighted", node).toLowerCase().equals("false")) {
                slider.setComponentHighlighted(false);
                outputDebugInfo("Task:     highlighted=\"false\"");
            }
        }
        try {
            slider.setComponentBottomPadding(Integer.parseInt(getAttribByName("bottomPadding", node)));
            outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", node));
        } catch (NumberFormatException e) {
        }
    }

    /**
     * This method looks through the attributes and child nodes to get infor-
     * mation about the look of the LikertSkale, it's text and it's description.
     *
     * @param button The UTLikertSkale object
     * @param node The node describing the LikertSkale in the xml file
     */
    private void getLikertScaleProperties (UTLikertScale likertScale, Node node) {
        outputDebugInfo("Task:     LikertScaleName=" + getAttribByName("name", node));
        likertScale.setName(getAttribByName("name", node));
        if (getAttribByNameOrReturnNull("description", node) != null) {
            likertScale.setDescription(getAttribByName("description", node));
            outputDebugInfo("Task:     description=" + getAttribByName("description", node));
        }
        int numberOfRatings = 5;
        try {
            likertScale.setNumberOfRatings(Integer.parseInt(getAttribByName("numberOfRatings", node)));
            outputDebugInfo("Task:     numberOfRatings=" + getAttribByName("numberOfRatings", node));
        } catch (NumberFormatException e) {
        }
        if (getAttribByNameOrReturnNull("maxLabel", node) != null) {
            likertScale.setRightLabel(getAttribByName("maxLabel", node));
            outputDebugInfo("Task:     maxLabel="+getAttribByName("maxLabel", node));
        }
        if (getAttribByNameOrReturnNull("minLabel", node) != null) {
            likertScale.setLeftLabel(getAttribByName("minLabel", node));
            outputDebugInfo("Task:     minLabel="+getAttribByName("minLabel", node));
        }
        likertScale.createLikertScale();
        if (getAttribByNameOrReturnNull("required", node) != null) {
            if (getAttribByName("required", node).toLowerCase().equals("true")) {
                likertScale.setInputRequired(true);
                outputDebugInfo("Task:     required=\"true\"");
            }
            if (getAttribByName("required", node).toLowerCase().equals("false")) {
                likertScale.setInputRequired(false);
                outputDebugInfo("Task:     required=\"false\"");
            }
        }
        if (getAttribByNameOrReturnNull("enabled", node) != null) {
            if (getAttribByName("enabled", node).toLowerCase().equals("false")) {
                likertScale.setComponentEnabled(false);
                outputDebugInfo("Task:     enabled=\"false\"");
            }
            if (getAttribByName("enabled", node).toLowerCase().equals("true")) {
                likertScale.setComponentEnabled(true);
                outputDebugInfo("Task:     enabled=\"true\"");
            }
        }
        if (getAttribByNameOrReturnNull("highlighted", node) != null) {
            if (getAttribByName("highlighted", node).toLowerCase().equals("true")) {
                likertScale.setComponentHighlighted(true);
                outputDebugInfo("Task:     highlighted=\"true\"");
            }
            if (getAttribByName("highlighted", node).toLowerCase().equals("false")) {
                likertScale.setComponentHighlighted(false);
                outputDebugInfo("Task:     highlighted=\"false\"");
            }
        }
        try {
            likertScale.setComponentBottomPadding(Integer.parseInt(getAttribByName("bottomPadding", node)));
            outputDebugInfo("Task:     bottomPadding=" + getAttribByName("bottomPadding", node));
        } catch (NumberFormatException e) {
        }
    }

    /**
     * This method gets the first child node that has the same
     * node name as parameter name
     *
     * @param node The node to look for a special child
     * @param name The name of the seached child
     */
    private Node getChildByName(Node node, String name) {
        int i = 0;
        Node result = null;
        boolean finished = false;
        
        NodeList nList = node.getChildNodes();
        while ((i < nList.getLength()) & !finished) {
//            outputDebugInfo(nList.item(i).getNodeName());
            if (nList.item(i).getNodeName().equals(name)) {
                result = nList.item(i);    
                finished = true;
            }
            i++;
        }
        return result;
    }
    
    
    /**
     * This method reads the text nodes that are child nodes of "node"
     *
     * @param node The node that has the text nodes as children
     */
    private String getText (Node node) {
        String textString = "";
        
        NodeList nList = node.getChildNodes();
        for (int i = 0; i<nList.getLength(); i++) {
            if (nList.item(i).getNodeType() == Node.TEXT_NODE) {
                textString += nList.item(i).getNodeValue();    
            }
        }
        return textString;
    }
    

    /**
     * This method reads the text nodes that are child nodes of "node". Other child elements
     * will be converted to strings containing that tags
     *
     * @param node The node that has the text nodes as children
     */
    private String getHtmlText (Node node) {
        String textString = "";
        
        NodeList nList = node.getChildNodes();
        for (int i = 0; i<nList.getLength(); i++) {
            if (nList.item(i).getNodeType() == Node.TEXT_NODE) {
                textString += nList.item(i).getNodeValue();    
            } else if (nList.item(i).getNodeType() == Node.ELEMENT_NODE) {
                textString += "<"+nList.item(i).getNodeName()+">"+getHtmlText(nList.item(i))+"</"+nList.item(i).getNodeName()+">";
            }
        }
        return textString;
    }
    
    
    private String getAttribByName (String attrName, Node node) {
        NamedNodeMap nMap = node.getAttributes();
        String result = "";
        if (nMap != null) {
            int i = 0;
            while (i < nMap.getLength()) {
                if (nMap.item(i).getNodeName().equals(attrName)) {
                    result = getText(nMap.item(i));
                }
                i++;
            }
        }
        return result;
    }


    private String getAttribByNameOrReturnNull (String attrName, Node node) {
        NamedNodeMap nMap = node.getAttributes();
        String result = null;
        if (nMap != null) {
            int i = 0;
            while (i < nMap.getLength()) {
                if (nMap.item(i).getNodeName().equals(attrName)) {
                    result = getText(nMap.item(i));
                }
                i++;
            }
        }
        return result;
    }


    private Node getNodeByTagNameAndNameAttrib(NodeList componentList, String tagName, String attribName) {
        int i=0;
        while (i < componentList.getLength()) {
            if ((componentList.item(i).getNodeName().equals(tagName)) &&
              getAttribByName("nameInTemplate", componentList.item(i)).equals(attribName)) {
                return componentList.item(i);
            }
            i++;
        }
        return null;
    }
    
    
    private void readActions (ButtonComponent component, Node node) {
        int k;
        NodeList nList = node.getChildNodes();
        for (k=0; k < nList.getLength(); k++) {
            if (equalsNodeName(nList.item(k), "openUri")) {
                component.addAction("openUri", getText(nList.item(k)));
                outputDebugInfo("Task:     openUri=" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "javaScriptCommand")) {
                component.addAction("javaScriptCommand", getText(nList.item(k)));
                outputDebugInfo("Task:     javaScriptCommand=" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "browserToFront")) {
                component.addAction("browserToFront", getText(nList.item(k)));
                outputDebugInfo("Task:     browserToFront");
            }
            if (equalsNodeName(nList.item(k), "browserResize")) {
                int browserWidth = 640;
                int browserHeight = 480;
                try {
                    browserWidth = (Integer.parseInt(getAttribByName("width", nList.item(k))));
                } catch (NumberFormatException e) {
                }
                try {
                    browserHeight = (Integer.parseInt(getAttribByName("height", nList.item(k))));
                } catch (NumberFormatException e) {
                }
                component.addAction("browserResize", browserWidth+"x"+browserHeight);
                outputDebugInfo("Task:     browserResize "+browserWidth+"x"+browserHeight);
            }
            if (equalsNodeName(nList.item(k), "moveBrowserWindow")) {
                int x = 0;
                int y = 0;
                try {
                    x = (Integer.parseInt(getAttribByName("x", nList.item(k))));
                } catch (NumberFormatException e) {
                }
                try {
                    y = (Integer.parseInt(getAttribByName("y", nList.item(k))));
                } catch (NumberFormatException e) {
                }
                component.addAction("moveBrowserWindow", x+"x"+y);
                outputDebugInfo("Task:     moveBrowserWindow "+x+"x"+y);
            }
            if (equalsNodeName(nList.item(k), "startNextTask")) {
                component.addAction("startNextTask", "");
                outputDebugInfo("Task:     startNextTask");
            }
            if (equalsNodeName(nList.item(k), "cancelTest")) {
                component.addAction("cancelTest", "");
                outputDebugInfo("Task:     cancelTest");
            }
            if (equalsNodeName(nList.item(k), "enable")) {
                component.addAction("enable", getText(nList.item(k)));
                outputDebugInfo("Task:     enable=" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "disable")) {
                component.addAction("disable", getText(nList.item(k)));
                outputDebugInfo("Task:     disable=" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "stopWatchStart")) {
                component.addAction("stopWatchStart", getText(nList.item(k)));
                outputDebugInfo("Task:     stopWatchStart=" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "stopWatchElapsed")) {
                component.addAction("stopWatchElapsed", getText(nList.item(k)));
                outputDebugInfo("Task:     stopWatchElapsed=" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "stopWatchLapTime")) {
                component.addAction("stopWatchLapTime", getText(nList.item(k)));
                outputDebugInfo("Task:     stopWatchLapTime=" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "highlight")) {
                component.addAction("highlight", getText(nList.item(k)));
                outputDebugInfo("Task:     highlight" + getText(nList.item(k)));
            }
            if (equalsNodeName(nList.item(k), "unhighlight")) {
                component.addAction("unhighlight", getText(nList.item(k)));
                outputDebugInfo("Task:     unhighlight=" + getText(nList.item(k)));
            }
        }                                    
    }

    private void readItems (UTDropDownBox component, Node node) {
        
        NodeList nList = node.getChildNodes();
        for (int k=0; k < nList.getLength(); k++) {
            if (equalsNodeName(nList.item(k), "item")) {
                long value = 0;
                boolean selectable = true;
                boolean showThisFirst = false;
                try {
                    value = Integer.parseInt(getAttribByName("value", nList.item(k)));
                } catch (NumberFormatException e) {
                }
                selectable = !getAttribByName("selectable", nList.item(k)).toLowerCase().equals("false");
                showThisFirst = getAttribByName("showThisFirst", nList.item(k)).toLowerCase().equals("true");
                component.addItem(value, getText(nList.item(k)),selectable, showThisFirst);
                outputDebugInfo("Task:     DropDownBoxItem:" + getText(nList.item(k)));
            }
        }                                    
    }

    private boolean equalsNodeName (Node node, String name) {
        return ((node.getNodeName().equals(name)) || (node.getNodeName().toLowerCase().equals(name.toLowerCase()) && !caseSensitive));
    }
        
    public String getTaskName () {
        return taskName;
    }
    
    public ArrayList getComponents () {
        return components;
    }
    
    
    public TaskPanel getTaskPanel () {
        return panel;
    }
    
    public String getTitle () {
        return title;
    }
    
    public void outputDebugInfo (String info) {
        if (utc.outputDebugInfo) {
            System.out.println(info);
        }
    }
    
}
