function SearchBuilderUI()
{
}

/**
 * Message strings
 */
SearchBuilderUI.btnOk = "?????";
SearchBuilderUI.btnCancel = "?????";
SearchBuilderUI.btnDelete = "?????";
SearchBuilderUI.btnContinue = "?????";
SearchBuilderUI.btnSaveCont = "?????";
SearchBuilderUI.saveTemplateTitle = "?????";
SearchBuilderUI.saveTemplateMsg = "?????";
SearchBuilderUI.deleteTemplateTitle = "?????";
SearchBuilderUI.deleteTemplateMsg = "?????";
SearchBuilderUI.saveChangesTitle = "?????";
SearchBuilderUI.saveChangesMsg = "?????";
SearchBuilderUI.dupTemp = "?????";
SearchBuilderUI.dupPrompt = "?????";
SearchBuilderUI.duplicate = "?????";
SearchBuilderUI.duplicate2 = "?????";
SearchBuilderUI.createTitle = "?????";
SearchBuilderUI.createMsg = "?????";
SearchBuilderUI.create = "?????";
SearchBuilderUI.delete2 = "?????";
SearchBuilderUI.preview = "?????";
SearchBuilderUI.searchBoxButtonText = "?????";
SearchBuilderUI.searchBoxButtonTitle = "?????";
SearchBuilderUI.topTitle = "?????";
SearchBuilderUI.btnClose = "?????";
SearchBuilderUI.applicationTitle = "?????";
SearchBuilderUI.notAlphanumericTitle = "?????";
SearchBuilderUI.notAlphanumericMsg = "?????";
SearchBuilderUI.errorCreatingSearchTemplate = "?????";
SearchBuilderUI.renameBtn = "??????";
SearchBuilderUI.renameTitle = "?????";
SearchBuilderUI.renameMsg = "??????";
SearchBuilderUI.applicationBaseHref = "?????";
SearchBuilderUI.collectionCodesLbl = "?????";
SearchBuilderUI.searchFieldsLbl  = "?????";

/** The layout manager */
SearchBuilderUI.layoutManager = null;


SearchBuilderUI.dlgWidth = "28em";
/**
 * The Yahoo UI tree view object the holds the templates
 */
SearchBuilderUI.tree = null;

/**
 * The currently selected node in the tree
 */
SearchBuilderUI.selectedNode = null;

/**
 * True if the template being added is new
 */
SearchBuilderUI.isNewTemplate = false;

/**
 * The id and owner of the search template to duplicate.
 */
SearchBuilderUI.duplicateTemplateId = "";
SearchBuilderUI.duplicateOwnerId    = "";

/**
 * The Yahoo UI Dialog box for duplicating or creating a search template
 */
SearchBuilderUI.addTemplateDlg = null;

/**
 * The Yahoo UI Dialog box for renaming a search template
 */
SearchBuilderUI.renameTemplateDlg = null;

/**
 * The Yahoo UI Dialog box for displaying the code for a searchbox
 */
SearchBuilderUI.generateSearchBoxDlg = null;

/**
 * The form change tracker object that will track changes to the editing form
 */
SearchBuilderUI.formChangeTracker = null;

/**
 * The function to call after the template has been saved
 */
SearchBuilderUI.afterUpdateFunction = null;

SearchBuilderUI.displayConfirmationAfterUpdate = true;

/**
 * Maps label ids to text node.  Used in the context menu.
 */
SearchBuilderUI.textNodeMap = {};

/**
 * The node that the context menu is acting on
 */
SearchBuilderUI.contextTreeNode = null;

/**
 * The text for the messages that will be displayed when the search session expired
 */
SearchBuilderUI.sessionExpiredTitle   = "SearchBuilderUI.sessionExpiredTitle";
SearchBuilderUI.sessionExpiredMessage = "SearchBuilderUI.sessionExpiredMessage";

/**
 * The list of owner objects
 */
SearchBuilderUI.owners = null;

/*
 * Flag for admin user
 */
SearchBuilderUI.isAdmin = null;

/**
 * Handles ajax errors that occur on this page
 * @param methodName the name of the method that failed
 * @param message the message from the exception that was thrown
 * @param info furhter information on the exception that was thrown.
 * @param titleMessage the mesage to be displayed in the message box's title bar
 */
SearchBuilderUI.pageErrorHandler = function(methodName, message, info, titleMessage)
{
    var buttons;

    // if the search session has expired
    if (info.javaClassName == "com.deepwebtech.coral.user.UserNotLoggedInException")
    {
        buttons = [ { text: SearchBuilderUI.btnOk, isDefault:true, handler: function()
        {
            window.location.reload();
        } }];

        MessageBox.displayDialog(SearchBuilderUI.sessionExpiredTitle, SearchBuilderUI.sessionExpiredMessage,
                buttons, YAHOO.widget.SimpleDialog.ICON_WARN);
    }
    else
    {
        DWRHelper.displayDWRError(methodName, message, info, titleMessage);
    }

};

//-----------------------------------------------------------------------------
// Update Template
//-----------------------------------------------------------------------------

/**
 * Callback function to the call to SearchBuilderConnector.updateSearchTemplate
 * @param data the data returned.  In this case, it is empty.
 */
SearchBuilderUI.updateTemplateCallbackFunction = function()
{
    if (SearchBuilderUI.displayConfirmationAfterUpdate)
    {
        MessageBox.info(SearchBuilderUI.saveTemplateTitle, SearchBuilderUI.saveTemplateMsg);
    }
    else
    {
        SearchBuilderUI.displayConfirmationAfterUpdate = true;
    }

    SearchBuilderUI.formChangeTracker.setClean();
    if (SearchBuilderUI.afterUpdateFunction)
    {
        SearchBuilderUI.afterUpdateFunction();
        SearchBuilderUI.afterUpdateFunction = null;
    }
};

/**
 * ErrorHandler to the call to SearchBuilderConnector.updateSearchTemplate
 * @param message the error message
 * @param info the stack info
 */
SearchBuilderUI.updateTemplateErrorHandler = function(message, info)
{
    SearchBuilderUI.pageErrorHandler("SearchBuilderConnector.updateSearchTemplate", message, info);
};

/**
 * The object used in the call to SearchBuilderConnector.updateSearchTemplate
 */
SearchBuilderUI.updateTemplateCallbackObject =
{
    callback: SearchBuilderUI.updateTemplateCallbackFunction,
    errorHandler: SearchBuilderUI.updateTemplateErrorHandler,
    timeout: DWRHelper.ajaxTimeout
};

SearchBuilderUI.validate = function()
{
    var ret = true;

    // The following elements are required:
    //  Title, collections, search fields

    if (!ValidationUtils.validateRequiredElement("template_title", ValidationUtils.titleLbl))
    {
        ret = false;
    }
    else if (!ValidationUtils.validateListPicker(ListPicker.instances.collectionCodes, SearchBuilderUI.collectionCodesLbl))
    {
        ret = false;
    }
    else if (!ValidationUtils.validateListPicker(ListPicker.instances.searchFields, SearchBuilderUI.searchFieldsLbl))
    {
        ret = false;
    }
    else if (!ValidationUtils.validateEmailByEleId("template_editor_emailAddress"))
    {
        ret = false;
    }

    //check to see if someone is trying to put a script into the title or the description
    var regex1 = /<script type=/;
    var titleEle = document.getElementById("template_title");
    var descriptionEle = document.getElementById("template_description");
    var alertFunction = function(){alert("Dont even try it buddy!!!");};

    if(titleEle.value.match(regex1) || descriptionEle.value.match(regex1))
    {
        alertFunction();
        ret = false;
    }

    return ret;
};

/**                                                                                               ﻿
 * Updates the currently template that is being edited.
 */
SearchBuilderUI.updateTemplate = function()
{
    if (SearchBuilderUI.validate())
    {
        // Build a searchTemplate object
        var searchTemplate = {};
        searchTemplate.title = document.getElementById("template_title").value;
        searchTemplate.id = document.getElementById("template_id").value;
        searchTemplate.newName = document.getElementById("newName").value;
        searchTemplate.owner = document.getElementById("templateOwnerDiv").innerHTML;
        searchTemplate.description = document.getElementById("template_description").value;
        searchTemplate.numColumns = document.getElementById("template_numColumns").value;
        searchTemplate.collectionCodes = ListPicker.instances.collectionCodes.getSelectedValues();
        searchTemplate.searchFields = ListPicker.instances.searchFields.getSelectedValues();
        searchTemplate.editor = {
            name: document.getElementById("template_editor_name").value,
            emailAddress: document.getElementById("template_editor_emailAddress").value,
            bio: document.getElementById("template_editor_bio").value
        };

        SearchBuilderConnector.updateSearchTemplate(searchTemplate, SearchBuilderUI.updateTemplateCallbackObject);
    }
    else
    {
        SearchBuilderUI.afterUpdateFunction = null;
    }

    return false;
};

//-----------------------------------------------------------------------------
// Delete Template
//-----------------------------------------------------------------------------

/**
 * Callback function to the call to SearchBuilderConnector.deleteSearchTemplate
 * @param data the data returned.  In this case, it is empty.
 */
SearchBuilderUI.deleteTemplateCallbackFunction = function(data)
{
    var i;
    var nodeParent;
    var nextSelectedNode;

    var nodeToRemove = SearchBuilderUI.getNodeByLabel(data.id, data.owner);

    // if the selected template was deleted
    if (SearchBuilderUI.selectedNode && SearchBuilderUI.getSelectedId() == data.id)
    {
        nodeParent = SearchBuilderUI.selectedNode.parent;
        nextSelectedNode = null;
        if (nodeParent.children.length > 1)
        {
            for (i = 0; i < nodeParent.children.length; ++i)
            {
                if (nodeParent.children[i] == SearchBuilderUI.selectedNode)
                {
                    if (i === 0)
                    {
                        nextSelectedNode = nodeParent.children[1];
                    }
                    else
                    {
                        nextSelectedNode = nodeParent.children[i - 1];
                    }
                    break;
                }
            }
        }

        if (nextSelectedNode !== null)
        {
            SearchBuilderConnector.retrieveSearchTemplate(nodeParent.label, nextSelectedNode.label,
                    SearchBuilderUI.retrieveTemplateCallbackObject);
        }
        else
        {
            document.getElementById("searchTemplateEditForm").style.display = "none";
            document.getElementById("initialScreen").style.display = "";
            SearchBuilderUI.disableIndividualTemplateButtons(true);
        }
    }

    delete SearchBuilderUI.textNodeMap[nodeToRemove.labelElId];

    // Remove the deleted node from the tree
    SearchBuilderUI.tree.removeNode(nodeToRemove, true);

    SearchBuilderUI.tree.render();
};

SearchBuilderUI.getNodeByLabel = function(label, owner)
{
    var i, returnNode = null,
            nodes = SearchBuilderUI.tree.getNodesByProperty("label", label);

    if (nodes === null)
    {
        return null;
    }

    if (SearchBuilderUI.isAdmin)
    {
        for (i = 0; i < nodes.length; i++)
        {
            if (owner)
            {
                if (nodes[i].parent != SearchBuilderUI.tree.getRoot() && nodes[i].parent.label == owner)
                {
                    returnNode = nodes[i];
                    break;
                }
            }
            else
            {
                if (nodes[i].parent == SearchBuilderUI.tree.getRoot())
                {
                    returnNode = nodes[i];
                    break;
                }
            }
        }
    }
    else
    {
        for (i = 0; i < nodes.length; i++)
        {
            if (nodes[i] != SearchBuilderUI.tree.getRoot())
            {
                returnNode = nodes[i];
            }
        }
    }

    return returnNode;
};

/**
 * ErrorHandler to the call to SearchBuilderConnector.deleteSearchTemplate
 * @param message the error message
 * @param info the stack info
 */
SearchBuilderUI.deleteTemplateErrorHandler = function(message, info)
{
    SearchBuilderUI.pageErrorHandler("SearchBuilderConnector.deleteSearchTemplate", message, info);
};

/**
 * The object used in the call to SearchBuilderConnector.deleteSearchTemplate
 */
SearchBuilderUI.deleteTemplatetCallbackObject =
{
    callback: SearchBuilderUI.deleteTemplateCallbackFunction,
    errorHandler: SearchBuilderUI.deleteTemplateErrorHandler,
    timeout: DWRHelper.ajaxTimeout
};

/**
 * Deletes the currently selected search template from the context menu
 */
SearchBuilderUI.deleteTemplateFromContext = function()
{
    SearchBuilderUI.deleteTemplate(SearchBuilderUI.contextTreeNode.label, SearchBuilderUI.contextTreeNode.parent.label);
};

/**
 * Deletes the currently selected search template
 */
SearchBuilderUI.deleteTemplate = function(stid, owner)
{
    stid = SearchBuilderUI.getStid(stid);
    owner = SearchBuilderUI.getOwner(owner);

    var buttons = [ { text: SearchBuilderUI.btnCancel, isDefault:true },
        { text: SearchBuilderUI.btnDelete, handler: function(ownerId, searchTemplateId)
        {
            return function()
            {
                SearchBuilderConnector.deleteSearchTemplate(ownerId, searchTemplateId, SearchBuilderUI.deleteTemplatetCallbackObject);
            };
        }(owner, stid) }
    ];

    MessageBox.displayDialog(SearchBuilderUI.deleteTemplateTitle, "<div>" + SearchBuilderUI.deleteTemplateMsg + "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(" + stid + ") ?</div>", buttons);

    return false;
};

//-----------------------------------------------------------------------------
// Get templates for user
//-----------------------------------------------------------------------------

SearchBuilderUI.getNodeDataCallback = function(templates, node, fnLoadComplete)
{
    for (var i = 0; i < templates.length; i++)
    {
        SearchBuilderUI.addTemplateNode(node, templates[i].id);
    }

    fnLoadComplete();
};

SearchBuilderUI.getNodeDataErrorHandler = function(message, info, fnLoadComplete)
{
    SearchBuilderUI.pageErrorHandler("SearchBuilderConnector.retrieveSearchTemplatesForUser", message, info);
    fnLoadComplete();
};

SearchBuilderUI.loadNodeData = function(node, fnLoadComplete)
{
    var callbackFunction = function(treeNode, completeFunc)
    {
        return function(serverData)
        {
            SearchBuilderUI.getNodeDataCallback(serverData, treeNode, completeFunc);
        };
    }(node, fnLoadComplete);

    var errorHandlerFunction = function(completeFunc)
    {
        return function(message, info)
        {
            SearchBuilderUI.getNodeDataErrorHandler(message, info, completeFunc);
        };
    }(fnLoadComplete);

    var callbackObject =
    {
        callback: callbackFunction,
        errorHandler: errorHandlerFunction,
        timeout: DWRHelper.ajaxTimeout
    };

    SearchBuilderConnector.retrieveSearchTemplatesForUser(node.label, callbackObject);
};

//-----------------------------------------------------------------------------
// retrieve template
//-----------------------------------------------------------------------------

SearchBuilderUI.loadTemplateData = function(data)
{
    SearchBuilderUI.formChangeTracker.ignoreChangeEvent = true;
    SearchBuilderUI.formChangeTracker.setClean();

    document.getElementById("stid").innerHTML = data.id;
    document.getElementById("template_id").value = data.id;
    document.getElementById("template_title").value = data.title;
    document.getElementById("template_owner").value = data.owner;
    document.getElementById("templateOwnerDiv").innerHTML = data.owner;
    document.getElementById("template_numColumns").value = data.numColumns;
    document.getElementById("template_description").value = data.description;

    document.getElementById("template_editor_name").value         = data.editor ? data.editor.name : "";
    document.getElementById("template_editor_emailAddress").value = data.editor ? data.editor.emailAddress : "";
    document.getElementById("template_editor_bio").value          = data.editor ? data.editor.bio : "";

    document.getElementById("template_showEditorInfo").checked =
    (document.getElementById("template_editor_name").value.length > 0);
    SearchBuilderUI.toggleEditorInfo();

    ListPicker.instances.collectionCodes.loadNewData(data.collectionCodes);
    ListPicker.instances.searchFields.loadNewData(data.searchFields);

    // show the template data form
    document.getElementById("initialScreen").style.display = "none";
    document.getElementById("searchTemplateEditForm").style.display = "";

    // Select the node to edit
    var nodeToEdit = SearchBuilderUI.getNodeByLabel(data.id, data.owner);
    if (nodeToEdit)
    {
        SearchBuilderUI.setSelectedNode(nodeToEdit, true);
    }

    // Enable the buttons to edit individual templates
    SearchBuilderUI.disableIndividualTemplateButtons(false);

    SearchBuilderUI.formChangeTracker.ignoreChangeEvent = false;

    var height = document.getElementById("center1").scrollHeight + SearchBuilderUI.layoutManager.getUnitById("top1").get('height') + 30;
    SearchBuilderUI.layoutManager.set('height', height);
    SearchBuilderUI.layoutManager.resize();
};

/**
 * Disables the save template buttons
 * @param isDisabled true if the buttons should be disabled
 */
SearchBuilderUI.disableSaveButtons = function(isDisabled)
{
    document.getElementById("saveTemplate").disabled       = isDisabled;
    document.getElementById("saveTemplateBottom").disabled = isDisabled;
};

/**
 * Disables the buttons that are associated with a singly selected search template
 * @param isDisabled true if the buttons should be disabled
 */
SearchBuilderUI.disableIndividualTemplateButtons = function(isDisabled)
{
    document.getElementById("renameTemplate").disabled          = isDisabled;
    document.getElementById("deleteTemplate").disabled          = isDisabled;
    document.getElementById("previewTemplate").disabled         = isDisabled;
    document.getElementById("downloadTemplate").disabled        = isDisabled;
    document.getElementById("duplicateTemplate").disabled       = isDisabled;
    document.getElementById("generateSearchBoxButton").disabled = isDisabled;

};

SearchBuilderUI.retrieveSearchTemplateCallback = function(data)
{
    SearchBuilderUI.loadTemplateData(data);
};

SearchBuilderUI.retrieveSearchTemplateErrorHandler = function(message, info)
{
    SearchBuilderUI.pageErrorHandler("SearchBuilderConnector.retrieveSearchTemplate", message, info);
};

SearchBuilderUI.retrieveTemplateCallbackObject =
{
    callback: SearchBuilderUI.retrieveSearchTemplateCallback,
    errorHandler: SearchBuilderUI.retrieveSearchTemplateErrorHandler,
    timeout: DWRHelper.ajaxTimeout
};

SearchBuilderUI.initiateRetrieveSearchTemplate = function(ownerId, stid)
{
    var afterFunc = function(userId, templateId)
    {
        return function()
        {
            SearchBuilderConnector.retrieveSearchTemplate(userId, templateId,
                    SearchBuilderUI.retrieveTemplateCallbackObject);
        };
    }(ownerId, stid);

    SearchBuilderUI.promptToSaveChanges(afterFunc);
};

/**
 * Prompts the user to let them know that they are about to lose their unsaved changes
 * @return true if it is ok to proceed with the operation.
 */
SearchBuilderUI.promptToSaveChanges = function(afterFunc)
{
    var buttons;

    if (SearchBuilderUI.formChangeTracker.isDirty())
    {
        buttons =
        [
            { text: SearchBuilderUI.btnCancel,           isDefault:true },
            { text: SearchBuilderUI.btnContinue,        handler: function(afterFunc)
            {
                return function()
                {
                    SearchBuilderUI.formChangeTracker.setClean();
                    afterFunc();
                };
            }(afterFunc) },

            { text: SearchBuilderUI.btnSaveCont, handler: function(afterFunc)
            {
                return function()
                {
                    SearchBuilderUI.afterUpdateFunction = afterFunc;
                    SearchBuilderUI.updateTemplate();
                };
            }(afterFunc)}
        ];

        MessageBox.displayDialog(SearchBuilderUI.saveChangesTitle, SearchBuilderUI.saveChangesMsg, buttons);
    }

    else
    {
        afterFunc();
    }
};

//-----------------------------------------------------------------------------
// Create/Duplicate template
//-----------------------------------------------------------------------------

/**
 * This method adds a tempate node to the tree
 * @param parentNode the parent node that will receive the new node
 * @param stid id of the search template
 * @return the newly created tree node
 */
SearchBuilderUI.addTemplateNode = function(parentNode, stid)
{
    var nodeData = { label: stid, stid: stid };
    var node = new YAHOO.widget.TextNode(nodeData, parentNode, false);
    node.isLeaf = true;

    SearchBuilderUI.textNodeMap[node.labelElId] = node;

    return node;
};

/**
 * The callback function to requests to add search templates to the application.
 * @param data the template objec that was just created
 */
SearchBuilderUI.addSearchTemplateCallback = function(data)
{
    var ownerNode;

    if (!SearchBuilderUI.isAdmin)
    {
        ownerNode = SearchBuilderUI.tree.getRoot();
    }
    else
    {
        // Add the template under the appropriate user tree node and select it.
        ownerNode = SearchBuilderUI.getNodeByLabel(data.owner);
        if (ownerNode === null)
        {
            ownerNode = new YAHOO.widget.TextNode({ label: data.owner }, SearchBuilderUI.tree.getRoot(), true);
            SearchBuilderUI.textNodeMap[ownerNode.labelElId] = ownerNode;
            SearchBuilderUI.tree.render();
        }
    }

    SearchBuilderUI.addTemplateNode(ownerNode, data.id);

    // Load the template's data into the edit form
    SearchBuilderUI.loadTemplateData(data);

    if (document.getElementById("template_title").value === "")
    {
        // Set the dirty flag to force the user to enter data
        SearchBuilderUI.formChangeTracker.setDirty();
    }
};

/**
 * The error handler to requests to add a search tempalte to the application
 * @param message the error message
 * @param info stack trace info
 */
SearchBuilderUI.addSearchTemplateErrorHandler = function(message, info)
{
    SearchBuilderUI.pageErrorHandler("SearchBuilderConnector.addSearchTemplate", message, info,
            SearchBuilderUI.errorCreatingSearchTemplate);
};

/**
 * Callback object used for requests to add templates to the application
 */
SearchBuilderUI.addTemplateCallbackObject =
{
    callback: SearchBuilderUI.addSearchTemplateCallback,
    errorHandler: SearchBuilderUI.addSearchTemplateErrorHandler,
    timeout: DWRHelper.ajaxTimeout
};

/**
 * Duplicate search template when selected from the context menu
 */
SearchBuilderUI.duplicateTemplateFromContext = function()
{
    SearchBuilderUI.initiateDuplicateSearchTemplate(SearchBuilderUI.contextTreeNode.label,
            SearchBuilderUI.contextTreeNode.parent.label);
};

/**
 * Starts the creation of a new search template by first checking if the current
 * form is dirty and prompting the user to save it.
 */
SearchBuilderUI.initiateDuplicateSearchTemplate = function(stid, owner)
{
    stid  = SearchBuilderUI.getStid(stid);
    owner = SearchBuilderUI.getOwner(owner);

    var afterFunc = function(templateId, ownerId)
    {
        return function()
        {
            SearchBuilderUI.duplicateSearchTemplate(templateId, ownerId);
        };
    }(stid, owner);

    SearchBuilderUI.promptToSaveChanges(afterFunc);
};

/**
 * Prompts the user to duplicate the curently selected search template
 */
SearchBuilderUI.duplicateSearchTemplate = function(stid, owner)
{
    SearchBuilderUI.duplicateTemplateId = stid;
    SearchBuilderUI.duplicateOwnerId    = owner;

    SearchBuilderUI.isNewTemplate = false;

    document.getElementById("newId").value = "";
    document.getElementById("addTemplateDlg_title").innerHTML = SearchBuilderUI.dupTemp;
    document.getElementById("prompt").innerHTML = SearchBuilderUI.dupPrompt;
    SearchBuilderUI.addTemplateDlg.getButtons()[1].set("label", SearchBuilderUI.duplicate);

    // Display the dialog box to enter the new id of the search template
    SearchBuilderUI.addTemplateDlg.show();
};

/**
 * Starts the creation of a new search template by first checking if the current
 * form is dirty and prompting the user to save it.
 */
SearchBuilderUI.initiateNewSearchTemplate = function()
{
    var afterFunc = function()
    {
        return function()
        {
            SearchBuilderUI.newSearchTemplate();
        };
    }();

    if (SearchBuilderUI.formChangeTracker.isDirty())
    {
        SearchBuilderUI.displayConfirmationAfterUpdate = false;
    }

    SearchBuilderUI.promptToSaveChanges(afterFunc);
};

/**
 * Prompts the user to create a new search template
 */
SearchBuilderUI.newSearchTemplate = function()
{
    SearchBuilderUI.isNewTemplate = true;

    document.getElementById("newId").value = "";
    document.getElementById("addTemplateDlg_title").innerHTML = SearchBuilderUI.createTitle;
    document.getElementById("prompt").innerHTML = SearchBuilderUI.createMsg;
    SearchBuilderUI.addTemplateDlg.getButtons()[1].set("label", SearchBuilderUI.create);

    // Display the dialog box to enter the new id of the search template
    SearchBuilderUI.addTemplateDlg.show();
};

/**
 * Creates the new/duplicate template dialog box
 */
SearchBuilderUI.addTemplateDialog = function()
{
    // Define various event handlers for Dialog
    var handleSubmit = function()
    {
        var data = this.getData();
        if (ValidationUtils.validateRequiredElement("newId", ValidationUtils.nameLbl))
        {
            var destId = data.newId;
            
            
            if (ValidationUtils.validateTemplateName(destId, SearchBuilderUI.notAlphanumericTitle, SearchBuilderUI.notAlphanumericMsg))
            {

                if (SearchBuilderUI.isNewTemplate)
                {
                    SearchBuilderConnector.createSearchTemplate(destId, null, SearchBuilderUI.addTemplateCallbackObject);
                }
                else
                {
                    SearchBuilderConnector.duplicateSearchTemplate(destId, SearchBuilderUI.duplicateOwnerId, SearchBuilderUI.duplicateTemplateId, SearchBuilderUI.addTemplateCallbackObject);
                }
                this.cancel();
            }
        }
    };

    var handleCancel = function()
    {
        this.cancel();
    };

    // Instantiate the Dialog
    SearchBuilderUI.addTemplateDlg = new YAHOO.widget.Dialog("addTemplateDlg",
    {   width : SearchBuilderUI.dlgWidth,
        fixedcenter : true,
        visible : false,
        constraintoviewport : true,
        modal:true,
        buttons : [ { text: SearchBuilderUI.btnCancel, handler:handleCancel},
            { text: SearchBuilderUI.dupTemp,   handler:handleSubmit, isDefault:true }
        ]
    });

    YahooDlgHelper.attachKeyEventHandlers(SearchBuilderUI.addTemplateDlg, SearchBuilderUI.addTemplateDlg.cancel);

    // Set focus to the text box when the dialog is displayed.
    SearchBuilderUI.addTemplateDlg.showEvent.subscribe(function(){document.getElementById("newId").focus()});

    // Render the Dialog
    SearchBuilderUI.addTemplateDlg.render();
};

/**
 * Generates a dialog box that contains code the user can copy and use in a blog
 * or send to other people.
 */
SearchBuilderUI.getSearchBoxCode = function()
{
    var searchPageLinkTextArea = document.getElementById("searchPageLink");
    searchPageLinkTextArea.value = SearchBuilderUI.applicationBaseHref + "/search/viewId:" + SearchBuilderUI.getViewId(SearchBuilderUI.getStid(), SearchBuilderUI.getOwner()) + "/";

    var searchBoxTextArea = document.getElementById("searchBoxCode");

    searchBoxTextArea.value = SearchBuilderUI.getLinkValue();

    SearchBuilderUI.generateSearchBoxDlg.show();
    searchBoxTextArea.focus();
    searchBoxTextArea.select();
};

SearchBuilderUI.generateSearchBoxCode = function()
{
    var handleCancel = function()
    {
        this.cancel();
    };

    // Instantiate the Dialog
    SearchBuilderUI.generateSearchBoxDlg = new YAHOO.widget.Dialog("generateSearchBox",
    {   /*width : SearchBuilderUI.dlgWidth,*/
        fixedcenter : true,
        visible : false,
        constraintoviewport : true,
        buttons : [ { text: SearchBuilderUI.btnClose, handler:handleCancel, isDefault:true } ]
    });

    YahooDlgHelper.attachKeyEventHandlers(SearchBuilderUI.generateSearchBoxDlg, SearchBuilderUI.addTemplateDlg.cancel);

    // Render the Dialog
    SearchBuilderUI.generateSearchBoxDlg.render();
};

SearchBuilderUI.init = function()
{
    SearchBuilderUI.addTemplateDialog();
    SearchBuilderUI.renameTemplateDlg();
    SearchBuilderUI.generateSearchBoxCode();
};

//-----------------------------------------------------------------------------
// Build the template tree
//-----------------------------------------------------------------------------

/**
 * Gets the id of the currently selected node
 */
SearchBuilderUI.getSelectedId = function()
{
    return document.getElementById("template_id").value;
};

/**
 * Gets the owner of the currently selected node
 */
SearchBuilderUI.getSelectedOwner = function()
{
    return document.getElementById("templateOwnerDiv").innerHTML;
};

/**
 * sets the selected node in the cluster tree
 * @param node the node veing selected
 * @param doRedraw true if the tree should be redrawn
 */
SearchBuilderUI.setSelectedNode = function(node, doRedraw)
{
    if (SearchBuilderUI.selectedNode !== null)
    {
        SearchBuilderUI.selectedNode.labelStyle = "ygtvlabel";
    }

    node.labelStyle = "selectedNode";
    SearchBuilderUI.selectedNode = node;

    if (doRedraw)
    {
        SearchBuilderUI.tree.draw();
    }
};

/**
 * "contextmenu" event handler for the element(s) that triggered the display of
 * the ContextMenu instance - used to set a reference to the TextNode instance that
 * triggered the display of the ContextMenu instance.
 * @param p_oEvent the event object
 */
SearchBuilderUI.onTriggerContextMenu = function(p_oEvent)
{
    var targetId = this.contextEventTarget.id;

    if (SearchBuilderUI.textNodeMap[targetId] && SearchBuilderUI.textNodeMap[targetId].isLeaf)
    {
        SearchBuilderUI.contextTreeNode = SearchBuilderUI.textNodeMap[targetId];
    }
    else
    {
        this.cancel();
    }
};

/**
 * Builds the template tree to enable editing by users
 * @param owners the list of template owners
 */
SearchBuilderUI.buildTemplateTree = function(owners)
{

    SearchBuilderUI.tree = new YAHOO.widget.TreeView("left1");

    SearchBuilderUI.tree.subscribe("expand", function(node)
    {
        YAHOO.log(node.index + " was expanded", "info", "example");
    });

    SearchBuilderUI.tree.subscribe("collapse", function(node)
    {
        YAHOO.log(node.index + " was collapsed", "info", "example");
    });

    // Trees with TextNodes will fire an event for when the label is clicked:
    SearchBuilderUI.tree.subscribe("labelClick",
            function(node)
            {
                if (!node.isLeaf)
                {
                    return;
                }

                if (node.label != SearchBuilderUI.getSelectedId() ||
                    (SearchBuilderUI.isAdmin && (node.label == SearchBuilderUI.getSelectedId() && node.parent.label != SearchBuilderUI.selectedNode.parent.label)) ||
                    document.getElementById("initialScreen").style.display != "none")
                {
                    SearchBuilderUI.initiateRetrieveSearchTemplate(node.parent.label, node.label);
                }
            }
            );


    if (!SearchBuilderUI.isAdmin)
    {
        var rootNode = SearchBuilderUI.tree.getRoot();
        rootNode.label = SearchBuilderUI.owners[0];

        SearchBuilderUI.loadNodeData(rootNode, function(){SearchBuilderUI.tree.render()});
    }
    else
    {
        // turn dynamic loading on for entire tree:
        SearchBuilderUI.tree.setDynamicLoad(SearchBuilderUI.loadNodeData, 0);

        var tmpNode;

        for (var i = 0; i < owners.length; i++)
        {
            tmpNode = new YAHOO.widget.TextNode({ label: owners[i] }, SearchBuilderUI.tree.getRoot(), false);
            SearchBuilderUI.textNodeMap[tmpNode.labelElId] = tmpNode;
        }

        if(owners.length == 1)
        {
            tmpNode.expand();
        }
    }

    SearchBuilderUI.tree.render();

    /*
     Instantiate a ContextMenu:  The first argument passed to
     the constructor is the id of the element to be created; the
     second is an object literal of configuration properties.
     */
    var oContextMenu = new YAHOO.widget.ContextMenu("mytreecontextmenu", {
        trigger: "left1",
        lazyload: true,
        itemdata: [
            { text: SearchBuilderUI.duplicate2, onclick: { fn: SearchBuilderUI.duplicateTemplateFromContext } },
            { text: SearchBuilderUI.delete2, onclick: { fn: SearchBuilderUI.deleteTemplateFromContext } },
            { text: SearchBuilderUI.preview, onclick: { fn: SearchBuilderUI.previewTemplateFromContext } },
            { text: SearchBuilderUI.download, onclick: { fn: SearchBuilderUI.downloadTemplateFromContext } }
        ] });


    /*
     Subscribe to the "contextmenu" event for the element(s)
     specified as the "trigger" for the ContextMenu instance.
     */

    oContextMenu.subscribe("triggerContextMenu", SearchBuilderUI.onTriggerContextMenu);
};

//-----------------------------------------------------------------------------
// Template Downloading
//-----------------------------------------------------------------------------

/**
 * Downloads the search template selected from the context menu
 */
SearchBuilderUI.downloadTemplateFromContext = function()
{
    SearchBuilderUI.downloadTemplate(SearchBuilderUI.contextTreeNode.parent.label, SearchBuilderUI.contextTreeNode.label);
};

/**
 * Downloads the currently selected template
 */
SearchBuilderUI.downloadTemplate = function(owner, stid)
{
    stid  = SearchBuilderUI.getStid(stid);
    owner = SearchBuilderUI.getOwner(owner);

    var urlBuilder = new URLBuilder("export-search-templates.html");
    urlBuilder.addParam("stid", stid);
    urlBuilder.addParam("owner", owner);

    SearchBuilderUI.openURL(urlBuilder.toString());
};

/**
 * Downloads all templates
 */
SearchBuilderUI.downloadAllTemplates = function()
{
    SearchBuilderUI.openURL("export-search-templates.html");
};

/**
 * Opens a window to start the download process
 * @param url the url to open in the window.
 */
SearchBuilderUI.openURL = function(url)
{
    window.open(url, null, "height=20,width=20,status=no,toolbar=no,menubar=no,location=no,scrollbars=no,resizable=no");
};

//-----------------------------------------------------------------------------
// Preview Template
//-----------------------------------------------------------------------------

SearchBuilderUI.initiatePreviewTemplate = function(stid, owner)
{
    var afterFunc = function(templateId, ownerId)
    {
        return function()
        {
            SearchBuilderUI.previewTemplate(templateId, ownerId);
        };
    }(stid, owner);

    if (SearchBuilderUI.formChangeTracker.isDirty())
    {
        SearchBuilderUI.displayConfirmationAfterUpdate = false;
        SearchBuilderUI.afterUpdateFunction = afterFunc;
        SearchBuilderUI.updateTemplate();
    }
    else
    {
        afterFunc();
    }
};

/**
 * Previews the search template selected from the context menu
 */
SearchBuilderUI.previewTemplateFromContext = function()
{
    SearchBuilderUI.initiatePreviewTemplate(SearchBuilderUI.contextTreeNode.label,
            SearchBuilderUI.contextTreeNode.parent.label);
};

/**
 * Previews the template being edited by bringing it up as a search page in a new window.
 * @param stid
 */
SearchBuilderUI.previewTemplate = function(stid, owner)
{
    stid = SearchBuilderUI.getStid(stid);
    owner = SearchBuilderUI.getOwner(owner);

    var win = window.open(SearchBuilderUI.getSearchUrl(stid, owner), "searchTemplatePreview", "");
    win.focus();
};

SearchBuilderUI.getSearchUrl = function(stid, owner)
{
    return Security.contextPath + "/search/viewId:" + SearchBuilderUI.getViewId(stid, owner) + "/";
};

SearchBuilderUI.getViewId = function(stid, owner)
{
    return (owner + "-" + stid);
};

/**
 * If the input stid is not defined, get the selected stid
 * @param stid the input stid
 */
SearchBuilderUI.getStid = function(stid)
{
    if (typeof(stid) == "undefined")
    {
        stid = SearchBuilderUI.getSelectedId();
    }

    return stid;
};

/**
 * If the input stid is not defined, get the selected stid
 * @param stid the input stid
 */
SearchBuilderUI.getOwner = function(owner)
{
    if (typeof(owner) == "undefined")
    {
        owner = SearchBuilderUI.getSelectedOwner();
    }

    return owner;
};

//-----------------------------------------------------------------------------
// Page Layout
//-----------------------------------------------------------------------------

SearchBuilderUI.layoutPage = function(owners)
{
    var Dom = YAHOO.util.Dom;
    var Event = YAHOO.util.Event;

    Event.onDOMReady(function()
    {
        var layout = new YAHOO.widget.Layout('layout',
        {
            height: 400,
            width: Dom.get('layout').parentNode.offsetWidth, //Width of the outer element
            minHeight: 150, //So it doesn't get too small
            units: [
                { position: 'top', height: 60, body: 'top1', gutter: '0px'},
                { position: 'left', header: SearchBuilderUI.topTitle, width: 180, resize: true, body: 'left1', gutter: '2px 2px 5px 0px', collapse: true, close: false, collapseSize: 30, scroll: true, animate: true },
                { position: 'center', body: 'center1', gutter: '2px 0px 5px 5px', scroll: true }
            ]
        });
        layout.on('render', function()
        {
            layout.getUnitByPosition('left').on('close', function()
            {
                closeLeft();
            });
        });
        layout.render();
        Event.on('tLeft', 'click', function(ev)
        {
            Event.stopEvent(ev);
            layout.getUnitByPosition('left').toggle();
        });
        var closeLeft = function()
        {
            var a = document.createElement('a');
            a.href = '#';
            a.innerHTML = 'Add Left Unit';
            Dom.get('closeLeft').parentNode.appendChild(a);

            Dom.setStyle('tLeft', 'display', 'none');
            Dom.setStyle('closeLeft', 'display', 'none');
            Event.on(a, 'click', function(ev)
            {
                Event.stopEvent(ev);
                Dom.setStyle('tLeft', 'display', 'inline');
                Dom.setStyle('closeLeft', 'display', 'inline');
                a.parentNode.removeChild(a);
                layout.addUnit(layout.get('units')[3]);
                layout.getUnitByPosition('left').on('close', function()
                {
                    closeLeft();
                });
            });
        };
        Event.on('closeLeft', 'click', function(ev)
        {
            Event.stopEvent(ev);
            layout.getUnitByPosition('left').close();
        });

        SearchBuilderUI.layoutManager = layout;
    });

    // Disable the buttons that are associated with a selected template
    SearchBuilderUI.disableSaveButtons(true);
    SearchBuilderUI.disableIndividualTemplateButtons(true);

    SearchBuilderUI.buildTemplateTree(owners);

    SearchBuilderUI.formChangeTracker = new FormChangeTracker();
    SearchBuilderUI.formChangeTracker.addListener(SearchBuilderUI);
    SearchBuilderUI.formChangeTracker.attachEventHandlers("searchTemplateForm");
};

/**
 * Fires when the data in the form changes
 * @param isDirty true if the form is dirty
 */
SearchBuilderUI.onDirtyChanged = function(isDirty)
{
    if (isDirty)
    {
        document.getElementById("stid").innerHTML = document.getElementById("template_id").value + " *";
    }
    else
    {
        document.getElementById("stid").innerHTML = document.getElementById("template_id").value;
    }

    SearchBuilderUI.disableSaveButtons(!isDirty);
};

SearchBuilderUI.changeLinkTarget = function()
{
    document.getElementById("searchBoxCode").value = SearchBuilderUI.getLinkValue();
};

SearchBuilderUI.getLinkValue = function()
{
    var path = SearchBuilderUI.applicationBaseHref + "/search.html";
    var link = '<div id="dwt-search-widget"><form method="post" action="' + path + '" ';

    if(document.getElementById("newWindowChkBox").checked)
    {
        link = link + 'target="_blank"';
    }

    link = link + '><div id="dwt-search-widget-inner" style="font-family:Arial, Verdana, sans-serif">' +
           '<input type="hidden" name="formName" value="simpleSearch"/>' +
           '<input type="hidden" name="viewId" value="' + SearchBuilderUI.getViewId(SearchBuilderUI.getStid(), SearchBuilderUI.getOwner()) + '"/>' +
           '<div style="font-weight:bold;" id="dwt-search-widget-title">' + SearchBuilderUI.applicationTitle + "&nbsp;:&nbsp;" + document.getElementById("template_title").value + "</div>" +
           '<input type="text" class="TextInput" id="search_terms" name="fullRecord"/>&nbsp;' +
           '<button type="submit" class="search_submit" id="dwt-search-widget-button" title="' + SearchBuilderUI.searchBoxButtonTitle + '">' + SearchBuilderUI.searchBoxButtonText + "</button>" +
           '<div style="font-size:.8em;margin-top:1px;"><a href="http://www.deepwebtech.com">Powered By Deep Web Technologies</a></div>' +
           "</div></form></div>";

    return link;
};

/**
 * Toggles the editor info text boxes when the check box is pressed.
 * @param enable true to enable, false otherwise.
 */
SearchBuilderUI.toggleEditorInfo = function()
{
    var i, ele,
            enable = document.getElementById("template_showEditorInfo").checked,
            eleIds = ["template_editor_name", "template_editor_emailAddress", "template_editor_bio"];

    for (i = 0; i < eleIds.length; ++i)
    {
        ele = document.getElementById(eleIds[i]);
        ele.disabled = !enable;
        if (enable)
        {
            YAHOO.util.Dom.removeClass(eleIds[i], 'disabled');
        }
        else
        {
            ele.value = "";
            YAHOO.util.Dom.addClass(eleIds[i], 'disabled');
        }
    }
};

/**
 * Starts the creation of a new renaming a template by first checking if the current
 * form is dirty and prompting the user to save it.
 */
SearchBuilderUI.initiateRenameSearchTemplate = function()
{
    var afterFunc = function()
    {
        return function()
        {
            document.getElementById("newName").value = "";
            SearchBuilderUI.renameTemplateDlg.show();
        };
    }();

    if (SearchBuilderUI.formChangeTracker.isDirty())
    {
        SearchBuilderUI.displayConfirmationAfterUpdate = false;
    }

    SearchBuilderUI.promptToSaveChanges(afterFunc);
};

/**
 * Updates the current template that is being edited.
 */
SearchBuilderUI.renameSearchTemplate = function()
{
    if (SearchBuilderUI.validate())
    {
        // Build a searchTemplate object
        var searchTemplate = {};
        searchTemplate.title = document.getElementById("template_title").value;
        searchTemplate.id = document.getElementById("template_id").value;
        searchTemplate.newName = document.getElementById("newName").value;
        searchTemplate.owner = document.getElementById("templateOwnerDiv").innerHTML;
        searchTemplate.description = document.getElementById("template_description").value;
        searchTemplate.numColumns = document.getElementById("template_numColumns").value;
        searchTemplate.collectionCodes = ListPicker.instances.collectionCodes.getSelectedValues();
        searchTemplate.searchFields = ListPicker.instances.searchFields.getSelectedValues();
        searchTemplate.editor = {
            name: document.getElementById("template_editor_name").value,
            emailAddress: document.getElementById("template_editor_emailAddress").value,
            bio: document.getElementById("template_editor_bio").value
        };
        searchTemplate.rename = "true";

        SearchBuilderConnector.renameSearchTemplate(searchTemplate, SearchBuilderUI.renameTemplateCallbackObject);
    }
};

/**
 * Initiates the renameTemplateDlg
 *
 */
SearchBuilderUI.renameTemplateDlg = function()
{
    // Define various event handlers for Dialog
    var handleSubmit = function()    {

        SearchBuilderUI.renameSearchTemplate();
        SearchBuilderUI.renameTemplateDlg.cancel();
    };

    var handleCancel = function()
    {
        this.cancel();
    };

    // Instantiate the Dialog
    SearchBuilderUI.renameTemplateDlg = new YAHOO.widget.Dialog("renameTemplateDlg",
    {   width : SearchBuilderUI.dlgWidth,
        fixedcenter : true,
        visible : false,
        constraintoviewport : true,
        modal:true,
        buttons : [ { text: SearchBuilderUI.btnCancel, handler:handleCancel},
            { text: SearchBuilderUI.renameBtn, handler:handleSubmit, isDefault:true }
        ]
    });

    YahooDlgHelper.attachKeyEventHandlers(SearchBuilderUI.renameTemplateDlg, SearchBuilderUI.renameTemplateDlg.cancel);

    // Set focus to the text box when the dialog is displayed.
    SearchBuilderUI.renameTemplateDlg.showEvent.subscribe(function(){document.getElementById("newName").focus()});

    // Render the Dialog
    SearchBuilderUI.renameTemplateDlg.render();
};

/**
 * ErrorHandler to the call to SearchBuilderConnector.renameSearchTemplate
 * @param message the error message
 * @param info the stack info
 */
SearchBuilderUI.renameTemplateErrorHandler = function(message, info)
{
    SearchBuilderUI.pageErrorHandler("SearchBuilderConnector.renameSearchTemplate", message, info);
};

/**
 * Callback function to the call to SearchBuilderConnector.renameSearchTemplate
 * @param data the data returned.
 */
SearchBuilderUI.renameTemplateCallbackFunction = function(data)
{
    var deleteResponse = data["deleteResponse"];
    var newTempalate = data["newTemplate"];

    SearchBuilderUI.addSearchTemplateCallback(newTempalate);
    SearchBuilderUI.deleteTemplateCallbackFunction(deleteResponse);

};

/**
 * The object used in the call to SearchBuilderConnector.
 */
SearchBuilderUI.renameTemplateCallbackObject =
{
    callback: SearchBuilderUI.renameTemplateCallbackFunction,
    errorHandler: SearchBuilderUI.renameTemplateErrorHandler,
    timeout: DWRHelper.ajaxTimeout
};

