
//\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\//
// Property panel functions
//\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\//


// Remeber the last right-click on tree node
var RightClickNode;
var RightClickTree;

// Update everything after a delay. This allows uninterupted editing
var UpdatePropertiesAndContentTimeout = 0;


/**
 * Create a new property panel in this div
 * Called by HTML <IMG> onload function
 * See: ModelPropertyGrid.BuildDropdownPanelPropertyHtmlEditorTemplate()
 * HTML: <img id="CreateCustomPanelImg-b7adfc20-342f-47b0-9eff-08453552630f" src="/Content/images/one-pixel-invisible.png" onload="CreatePropertyEditorPanel($('#DropdownInnerPanel-bd5e6f71-403d-4b8b-bc4f-6290fcee75aa'), 'rptdata.RptStylesProperty', 'Style', 'Normal Text', '', 'C:\Source\Standard Time Web\Standard Time Web\Reports\Management\Barcodes Labels.rpx', 'CE64549D-A65E-4319-A14C-48FDBA8F2E6C'); " style="visibility:hidden;" />
 * @param {any} ParentDiv
 */
function CreatePropertyEditorPanel(ParentDiv, PropertyType, PropertyId, PropertyValue, ObjectDataType, ObjectTable, ObjectRecordId, DisplayText) {

    AjaxGetPropertyEditorPartialView(ParentDiv, PropertyType, PropertyId, PropertyValue, ObjectDataType, ObjectTable, ObjectRecordId, DisplayText);
}



function AjaxGetPropertyEditorPartialView(divElement, PropertyType, PropertyId, PropertyValue, ObjectDataType, ObjectTable, ObjectRecordId, DisplayText) {

    if (!divElement || divElement.length == 0) {
        console.log("AjaxCreateCustomPropertyPanel div does not exist!");
        return;
    }

// Does not work because this is called multiple times for a single recordset (called for: folder, attachments, inventory locations, etc.)
    // Remember these for RefreshPropertyEditorPartialView()
    //CurrentPropertyEditorDivElement = divElement;
    //CurrentPropertyEditorPropertyType = PropertyType;
    //CurrentPropertyEditorPropertyId = PropertyId;
    //CurrentPropertyEditorPropertyValue = PropertyValue;
    //CurrentPropertyEditorSelectedDataType = ObjectDataType;
    //CurrentPropertyEditorSelectedTable = ObjectTable;
    //CurrentPropertyEditorSelectedRecordId = ObjectRecordId;

    var params = {
        "PropertyType": PropertyType,
        "PropertyId": PropertyId,
        "PropertyValue": PropertyValue,
        "SelectedDataType": ObjectDataType,
        "SelectedTable": ObjectTable,
        "SelectedRecordId": ObjectRecordId,
        "DisplayText": DisplayText
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxGetPropertyEditorPartialView/",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json", /*type of data sent to server*/
    }).done(function (data) {
        $(divElement).html(data);
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
        var parsed = false;
        var res = void 0;
        try {
            res = JSON.parse(jqXHR.responseText);
            parsed = true;
        }
        catch (err) {
            // will handle parsed=false
        }
        console.error("AjaxGetPropertyEditorPartialView Error:", jqXHR, textStatus, errorThrown);

        // Display error
        if (res && parsed)
            ToastError("AjaxGetPropertyEditorPartialView", res);
        else if (jqXHR.responseText)
            ToastError("AjaxGetPropertyEditorPartialView", jqXHR.responseText);
    })
    .always(function() {
    });
}



// Used to refresh the current view when changes occur
var CurrentPropertyEditorDivElement;
var CurrentPropertyEditorPropertyType;
var CurrentPropertyEditorPropertyId;
var CurrentPropertyEditorPropertyValue;
var CurrentPropertyEditorSelectedDataType;
var CurrentPropertyEditorSelectedTable;
var CurrentPropertyEditorSelectedRecordId;

function RefreshPropertyEditorPartialView() {

    // Use the last values to refresh
    AjaxGetPropertyEditorPartialView(CurrentPropertyEditorDivElement, CurrentPropertyEditorPropertyType, CurrentPropertyEditorPropertyId, CurrentPropertyEditorPropertyValue, CurrentPropertyEditorSelectedDataType, CurrentPropertyEditorSelectedTable, CurrentPropertyEditorSelectedRecordId);
}




// https://www.igniteui.com/help/api/2021.2/ui.igtree#events:nodeClick
// https://www.igniteui.com/help/api/2021.1/ui.igtree
//Fired on node click.
//    evt
//Type: Event
//JQuery event object.

//    ui
//Type: Object
//owner
//Type: Object
//Gets a reference to the tree.

//    node
//Type: Object
//Gets a reference to the node object being clicked.

function PropertyEditorTreeNodeClicked(evt, ui) {

    if (!evt)
        return;
    if (!evt.target)
        return;
    if (!ui)
        return;
    if (!ui.node)
        return;
    if (!ui.node.data)
        return;

    var Text = ui.node.data.Text;
    var Value = ui.node.data.Value;
    var TreeObject = $(evt.target);

    // Find a parent with class=propertycontainer
    // This div will have the following "data" attributes
    // 1. data-propertytype (the System.Type of the property value)
    // 2. data-propertyid (the DbColumn for the recordset)
    // 3. data-propertyname (the name of the property being set)
    // 4. data-objecttype (the System.Type of the recordset object)
    // 5. data-objecttable (the database table for the recordset)
    // 6. data-objectid (the GUID of the recordset)
    var PropertyContainer = FindPropertyContainer(TreeObject);
    if (!PropertyContainer)
        return;
    if (PropertyContainer.length == 0)
        return;

    // New folder?
    if (Text && (Text.toLowerCase() == "new folder")) {
        RightClickTree = TreeObject;
        RightClickNode = ui.node;
        OnFolderPropertyEditorNewFolder();
        return;
    }

    // Set the property for the current record
    //var ContentType = GetSelectedContentType();
    //var SelectedRecordId = GetSelectedRecordId();
    //var SelectedTableId = GetSelectedRecordTableId();
    //var SelectedDataType = GetSelectedDataType();
    var ContentType = GetSelectedContentType();
    var PropertyId = PropertyContainer.attr('data-propertyid');
    var PropertyName = PropertyContainer.attr('data-propertyname');
    var SelectedRecordId = PropertyContainer.attr('data-objectid');
    var SelectedTableId = PropertyContainer.attr('data-objecttable');
    var SelectedDataType = PropertyContainer.attr('data-objecttype');
    AjaxSetContentPropertyValue(Value, /*"Folder"*/PropertyName, /*"Folder_Property"*/PropertyId, ContentType, SelectedTableId, SelectedRecordId);

    // Close the dropdown
    var DropdownParent = FindDropdownPanelParent(TreeObject);
    if (DropdownParent)
        CloseDropdown(DropdownParent.attr('id'));
}



function PropertyEditorTreeNodeChecked(evt, ui) {

    // https://www.igniteui.com/help/igtree-configure-checkboxes-and-selection?_ga=2.123665667.989417234.1661804899-1526114389.1655224915
    if (!evt)
        return;
    if (!evt.target)
        return;
    if (!ui)
        return;
    if (!ui.node)
        return;
    if (!ui.node.data)
        return;
    var TreeObject = $(evt.target);
    if (!TreeObject)
        return;

    var Text = ui.node.data.Text;
    var Value = ui.node.data.Value;
    var CheckedNodes = TreeObject.igTree("checkedNodes");
    if (CheckedNodes && CheckedNodes.length > 0) {

        Value = "";
        for (const CheckedNode of CheckedNodes) {

            if (Value.length > 0)
                Value += ",";
            Value += CheckedNode.data.Value;
        }
    } else {
        // Nothing is checked, so no value
        // Example: Uncheck all users in Assign_Property tree
        // See: Permission to View Data property in User record
        Value = "";
    }

    // Comma separated values for multiple checkbox choices
    Value = "CSV_VALUE:" + Value;

    // Find a parent with class=propertycontainer
    // This div will have the following "data" attributes
    // 1. data-propertytype (the System.Type of the property value)
    // 2. data-propertyid (the DbColumn for the recordset)
    // 3. data-propertyname (the name of the property being set)
    // 4. data-objecttype (the System.Type of the recordset object)
    // 5. data-objecttable (the database table for the recordset)
    // 6. data-objectid (the GUID of the recordset)
    var PropertyContainer = FindPropertyContainer(TreeObject);
    if (!PropertyContainer)
        return;
    if (PropertyContainer.length == 0)
        return;

    // Set the property for the current record
    var ContentType = GetSelectedContentType();
    var PropertyId = PropertyContainer.attr('data-propertyid');
    var PropertyName = PropertyContainer.attr('data-propertyname');
    var SelectedRecordId = PropertyContainer.attr('data-objectid');
    var SelectedTableId = PropertyContainer.attr('data-objecttable');
    var SelectedDataType = PropertyContainer.attr('data-objecttype');
    AjaxSetContentPropertyValue(Value, /*"Assign to users"*/PropertyName, /*"Assign_Property"*/PropertyId, ContentType, SelectedTableId, SelectedRecordId);

    // Close the dropdown
    //    var DropdownParent = FindDropdownPanelParent(TreeObject);
    //    if (DropdownParent)
    //        CloseDropdown(DropdownParent.attr('id'));
}




/**
 * Folder property editor tree has been rendered
 * Set up tree events or data
 * @param {any} evt
 * @param {any} ui
 */
function OnFolderPropertyEditorTreeRendered(evt, ui) {

    if (!evt)
        return;
    if (!evt.target)
        return;
    if (!ui)
        return;

    var TreeElement = $(evt.target);

    //Context menu
    TreeElement.contextmenu(function (evt) { OnFolderPropertyEditorTreeContextMenu(TreeElement, evt); });
}


/**
 * Right-click Folder property editor tree node
 * @param {any} TreeElement
 * @param {any} event
 */
function OnFolderPropertyEditorTreeContextMenu(TreeElement, event) {

    RightClickNode = null;
    RightClickTree = null;

    if (!TreeElement)
        return;
    if (!event)
        return;
    if (!event.target)
        return;

    // No browser right-click menu
    event.preventDefault();

    var ClickedHtmlElement = event.target;
    var Node = $(TreeElement).igTree('nodeFromElement', $(event.target).closest('li[data-role=node]'));
    if (!Node)
        return;
    if (!Node.data)
        return;
    if (!Node.data.Text)
        return;
    if (!Node.data.Value)
        return;

    var ClickedFolder = Node.data.Value;
    RightClickNode = Node;
    RightClickTree = TreeElement;

    // Open a folder
    AjaxGetFolderPropertyEditorContextMenu(event, ClickedFolder);
}



function AjaxGetFolderPropertyEditorContextMenu(event, SelectedFolder) {

    //console.log("AjaxGetFolderEditorContextMenu: " + BarcodeText);

    var params = {
        "SelectedFolder": SelectedFolder,
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxGetFolderEditorContextMenu",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json",
        success: function (response) {
            if (response.Success) {
                if (response.ContextMenuItems) {
                    var menuitems = JSON.parse(response.ContextMenuItems);
                    var menu = new ContextMenu(menuitems);
                    menu.display(event);
                }
            }
            else {
                ToastError("Folder menu", response.ErrorResults);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxGetFolderEditorContextMenu", errormsg);
            console.log('AJAX: ' + errormsg);
        }
    });
}


/**
 * Called from context menu "Rename" menu choice
 * */
function OnFolderPropertyEditorRename() {

    if (!RightClickTree)
        return;
    if (!RightClickNode)
        return;
    if (!RightClickNode.data)
        return;
    if (!RightClickNode.data.Value)
        return;

    // Prompt for a new folder name
    var proceedcallback = OnFolderPropertyEditorAfterRenamePrompt;
    var proceedobject = null;
    PopupPromptForValueBox("Rename Folder", "Enter new folder name", RightClickNode.data.Text, proceedcallback, proceedobject);
}

function OnFolderPropertyEditorAfterRenamePrompt(prompt) {

    if (!prompt)
        return;
    if (!prompt.sValue)
        return;
    if (!RightClickTree)
        return;
    if (!RightClickNode)
        return;
    if (!RightClickNode.data.Value)
        return;

    // https://www.igniteui.com/help/api/2014.2/ui.igtree?_ga=2.201928152.852125402.1662475699-1526114389.1655224915#methods:parentNode
    var ParentNode = GetParentTreeNode(RightClickTree, RightClickNode);

    // Current strings
    var sOldKey = RightClickNode.data.Value;
    var sOldText = RightClickNode.data.Text;

    // New strings
    var sParentKey = "";
    var sNewKey = prompt.sValue;
    var sNewText = prompt.sValue;
    if (ParentNode && ParentNode.data && ParentNode.data.Value)
        sParentKey = ParentNode.data.Value;
    if (sParentKey)
        sNewKey = sParentKey + ":" + prompt.sValue;
    RightClickNode.data.Text = sNewText;
    RightClickNode.data.Value = sNewKey;
    RightClickTree.igTree("applyChangesToNode", RightClickNode.element, RightClickNode.data);

    var SelectedTableId = GetSelectedRecordTableId();
    AjaxRenameFolder(SelectedTableId, sOldKey, sNewKey);
}


/**
 * Called from context menu "New Folder" menu choice
 * */
function OnFolderPropertyEditorNewFolder() {

    // Prompt for a new folder name
    var proceedcallback = OnFolderPropertyEditorAfterNewFolderPrompt;
    var proceedobject = null;
    PopupPromptForValueBox("New Folder", "Enter folder name", "", proceedcallback, proceedobject);
}

function OnFolderPropertyEditorAfterNewFolderPrompt(prompt) {

    if (!prompt)
        return;
    if (!RightClickTree)
        return;
    if (!RightClickNode)
        return;
    if (!prompt.sValue)
        return;

    // Add a new node to the tree
    // User must click that node to actually use it for the selected record
    // If user does not click the new node it will go away because it is temporary
    // Only folders actually used by records are permanent
    var NewFolderData = jQuery.extend({}, RightClickNode.data);
    NewFolderData.Text = prompt.sValue;
    NewFolderData.Value = prompt.sValue;
    NewFolderData.ChildItems = {};
    RightClickTree.igTree("addNode", NewFolderData, null/*parentNode*/);
}



/**
 * Called from context menu "New Subfolder" menu choice
 * */
function OnFolderPropertyEditorNewSubFolder() {

    // Prompt for a new subfolder name
    var proceedcallback = OnFolderPropertyEditorAfterNewSubfolderPrompt;
    var proceedobject = null;
    PopupPromptForValueBox("New Subfolder", "Enter folder under \"" + RightClickNode.data.Text + "\"", "", proceedcallback, proceedobject);
}

function OnFolderPropertyEditorAfterNewSubfolderPrompt(prompt) {

    if (!prompt)
        return;
    if (!RightClickTree)
        return;
    if (!RightClickNode)
        return;

    // Add a new node to the tree
    // User must click that node to actually use it for the selected record
    // If user does not click the new node it will go away because it is temporary
    // Only folders actually used by records are permanent
    var NewSubfolderData = jQuery.extend({}, RightClickNode.data);
    NewSubfolderData.Text = prompt.sValue;
    NewSubfolderData.Value = RightClickNode.data.Value + ":" + prompt.sValue;
    NewSubfolderData.ChildItems = {};
    RightClickTree.igTree("addNode", NewSubfolderData, RightClickNode.element/*parentNode*/);

    // Expand the selected node to see the new child
    RightClickTree.igTree("expand", RightClickNode.element);
}



function AjaxRenameFolder(DbTable, OldFolder, NewFolder) {

    var params = {
        "DbTable": DbTable,
        "OldFolder": OldFolder,
        "NewFolder": NewFolder,
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxRenameFolder",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json",
        success: function (response) {
            if (response.Success) {
                // Everything has changed because the selected object is now in a new folder

                // This is very disruptive (but it does refresh everything that changed)
                //CloseLastDropdown();
                //RefreshSelectedContent();
                //RefreshPropertyGridViewFromHiddenSelection($("#" + PropertyGridPartialViewDivId));
            }
            else {
                ToastError("AjaxRenameFolder", response.ErrorResults);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxRenameFolder", errormsg);
            console.log('AJAX: ' + errormsg);
        }
    });
}






/**
 * Fired after a node is dropped.

evt
Type: Event
JQuery event object.

ui
Type: Object
    owner
    Type: Object
    Gets a reference to the tree.

    path
    Type: String
    Gets the target node data-path attribute.

    element
    Type: jQuery
    Gets a reference to the jQuery element of the node.

    data
    Type: Object
    Gets a reference to the target node data.

    binding
    Type: Object
    Gets a reference to the binding object for the level at which the target node is located.

    helper
    Type: jQuery
    Gets a reference to the helper.

    offset
    Type: Object
    Gets a reference to the offset.

    position
    Type: Object
    Gets a reference to the current position of the draggable element.

    draggable
    Type: jQuery
    Gets a reference to the draggable element (the node).

    sourceNode
    Type: Object
    Gets a reference to the dropped source node object.

 * @param {any} evt
 * @param {any} ui
 */
function OnFolderPropertyEditorTreeNodeDropped(evt, ui) {

    // https://www.igniteui.com/help/api/2022.1/ui.igtree
    if (!evt)
        return;
    if (!evt.target)
        return;
    if (!ui)
        return;
    if (!ui.sourceNode) // Src node
        return;
    if (!ui.data) // Target node
        return;

    // Get folder being dragged and folder being dropped onto
    DraggedFolder = ui.sourceNode.data.Value;
    DroppedOntoFolder = ui.data.Value;
    if (DraggedFolder == null || DraggedFolder == undefined || DraggedFolder.length == 0)
        return;
    if (DroppedOntoFolder == null || DroppedOntoFolder == undefined || DroppedOntoFolder.length == 0)
        return;
    bMovedBetweenFolders = ui.helper && (ui.helper.text().indexOf("Move between") != -1);

    PopupYesNoWithCallback("Move Folder", "Are you sure you wish to move '" + DraggedFolder + "' to '" + DroppedOntoFolder + "'", OnDragAndDropFolder, null/*proceedobject*/);
}


var DraggedFolder = null;
var DroppedOntoFolder = null;
var bMovedBetweenFolders = false;

function OnDragAndDropFolder(prompt) {

    if (DraggedFolder == null || DraggedFolder == undefined || DraggedFolder.length == 0)
        return;
    if (DroppedOntoFolder == null || DroppedOntoFolder == undefined || DroppedOntoFolder.length == 0)
        return;
    var SelectedTableId = GetSelectedRecordTableId();

    // TODO: P7 Drag and drop folders
    ToastMessage("Dragging folders is not yet available", DraggedFolder + ", " + DroppedOntoFolder);

    //AjaxMoveFolder(string DbTable, string MoveFolder, string MoveToFolder);
    //AjaxRenameFolder(string DbTable, string OldFolder, string NewFolder)
}



function OnLoadPropertyEditorButton(ImgElement) {

    if (!ImgElement)
        return;
    var ImgObject = $(ImgElement);
    if (!ImgObject || ImgObject.length == 0)
        return;

    // Embedded values in <img> button
    var RowData = ImgObject.attr("data-rowkey");

    // Display image in button
    var ImageName = ExtractTagValue(RowData, "TAG-IMAGE:");
    AjaxFillImage(ImgObject, ImageName, 16/*preferredpixelsize*/);

    // HTML id stored in tag
    var ImageId = ExtractTagValue(RowData, "TAG-ID:");
    if (ImageId)
        ImgObject.attr("id", ImageId);

    // OnClick function
    var FunctionWithParams = ExtractTagValue(RowData, "TAG-FUNCTION:");
    if (FunctionWithParams) {
        // Backslashes stripped by onclick
        // Replace backslashes by double-backslashes because they will be reinterpreted by onclick
        FunctionWithParams = FunctionWithParams.replace(/\\/g, '\\\\');
        ImgObject.attr('onclick', FunctionWithParams);
    }
}




/**
 * Called when user clicked a <span> item in property panel
 * Call Ajax to select the new property editor item for the selected recordid
 * @param {any} sDbTable
 * @param {any} sRecordId
 * @param {any} sSelectedItemId
 */
function OnPropertyEditorItemClicked(ElementId, PropertyId, sObjectType, sDbTable, sRecordId, sSelectedItemId) {

    //ToastMessage("OnPropertyEditorItemClicked:", PropertyId + "\r\n\r\n" + sObjectType + "\r\n\r\n" + sDbTable + "\r\n\r\n" + sRecordId + "\r\n\r\n" + sSelectedItemId);

    // Select the new property editor item for this recordid
    var ContentType = GetSelectedContentType();
    AjaxSetContentPropertyValue(sSelectedItemId/*NewValue*/, PropertyId/*PropertyName*/, PropertyId/*PropertyId*/,  ContentType, sDbTable, sRecordId, ""/*FilterJsonString*/);


    // Close the dropdown
    var ElementObject = null;
    if (ElementId)
        ElementObject = $("#" + ElementId);
    else
        ElementObject = $(event.target);

    var DropdownParent = FindDropdownPanelParent(ElementObject);
    if (DropdownParent)
        CloseDropdown(DropdownParent.attr('id'));
}




/**
 * Called when user clicks "Delete" button next to attachment
 * @param {any} sRecordId
 * @param {any} sAttachment
 */
function OnDeleteRecordsetAttachment(sDbTable, sRecordId, sAttachment) {

    AjaxDeleteAttachment(sDbTable, sRecordId, sAttachment);
    //ToastError("Attachments", "Not yet available on web edition");
    //ToastMessage("Delete:" + sDbTable + ", " + sRecordId, sAttachment);
}

/**
 * Called when user clicks "View" button next to attachment
 * @param {any} sRecordId
 * @param {any} sAttachment
 */
function OnViewRecordsetAttachment(sDbTable, sRecordId, sAttachment) {

    AjaxViewAttachment(sAttachment);
    //ToastError("Attachments", "Not yet available on web edition");
    //ToastMessage("View:" + sDbTable + ", " + sRecordId, sAttachment);
}

/**
 * Called when user clicks "Download" button next to attachment
 * @param {any} sRecordId
 * @param {any} sAttachment
 */
function OnDownloadRecordsetAttachment(sDbTable, sRecordId, sAttachment) {

    AjaxDownloadAttachment(sAttachment);
    //ToastError("Attachments", "Download not yet available on web edition");
    //ToastMessage("View:" + sDbTable + ", " + sRecordId, sAttachment);
}

/**
 * Called when user clicks "Add" button for attachment file
 * @param {any} sRecordId
 */
function OnAddRecordsetFileAttachment(sDbTable, sRecordId) {

    FileOpenAndUploadForAttachment(sDbTable, sRecordId);
    //ToastError("Attachments", "Not yet available on web edition");
    //ToastMessage("Add File:" + sDbTable + ", " + sRecordId);
}

/**
 * Called when user clicks "Add" button for attachment folder
 * @param {any} sRecordId
 */
function OnAddRecordsetFolderAttachment(sDbTable, sRecordId) {

    // TODO: P4 Add "folder" attachments with all files in a specified folder
    ToastError("Folder attachments", "Not yet available on web edition");

    //ToastMessage("Add Folder:" + sDbTable + ", " + sRecordId);
}



/**
 * Allow user to edit a while before updating everything
 * */
function RestartPropertiesAndContentRefreshTimeout(nTimeoutMs) {

    if (UpdatePropertiesAndContentTimeout) {
        clearTimeout(UpdatePropertiesAndContentTimeout);
        UpdatePropertiesAndContentTimeout = 0;
    }

    // Refresh the content after a while
    // Allow uninterupted editing
    UpdatePropertiesAndContentTimeout = setTimeout(function ()
    {
        RefreshPropertyEditorPartialView();
        RefreshSelectedContent();
    }, nTimeoutMs);
}





var PropertyEditorItemPropertyId = "";
var PropertyEditorItemDbTable = "";
var PropertyEditorItemRecordId = "";
var PropertyEditorItemEditId = "";
var PropertyEditorItemObjectType = "";
var PropertyEditorItemName = "";

/**
 * Called when user clicks "Add" button next to property editor item
 * @param {any} PropertyId
 * @param {any} sTitle
 * @param {any} sPrompt
 * @param {any} sDefaultValue
 * @param {any} sDbTable
 * @param {any} sObjectType
 */
function OnPropertyEditorAddItem(PropertyId, sTitle, sPrompt, sDefaultValue, sDbTable, sRecordId, sObjectType) {

    //ToastMessage("OnPropertyEditorAddItem:", PropertyId + "\r\n\r\n" + sDbTable + "\r\n\r\n" + sObjectType);

    // Remember these for use when user clicks OK to add the new item
    PropertyEditorItemPropertyId = PropertyId;
    PropertyEditorItemDbTable = sDbTable;
    PropertyEditorItemRecordId = sRecordId;
    PropertyEditorItemObjectType = sObjectType;

    PopupPromptForValueBox(sTitle, sPrompt, sDefaultValue, OnOkPropertyEditorAddItemCallback);
}

function OnOkPropertyEditorAddItemCallback(prompt) {

    if (!prompt)
        return;
    if (!prompt.sValue)
        return;
    if (!PropertyEditorItemPropertyId)
        return;
    if (!PropertyEditorItemDbTable)
        return;

    //ToastMessage("OnOkPropertyEditorAddItemCallback", prompt.sValue);

    // Call Ajax to add the new item to the selected recordid
    AjaxPropertyEditorAddItem(PropertyEditorItemPropertyId, prompt.sValue, PropertyEditorItemDbTable, PropertyEditorItemRecordId, PropertyEditorItemObjectType);

    // Close the dropdown that originated this
    CloseLastDropdown();
}



function AjaxPropertyEditorAddItem(PropertyId, Value, DbTable, RecordId, ObjectType) {

    var ContentType = GetSelectedContentType();

    var params = {
        "ContentType": ContentType,
        "PropertyId": PropertyId,
        "Value": Value,
        "DbTable": DbTable,
        "RecordId": RecordId,
        "ObjectType": ObjectType,
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxPropertyEditorAddItem",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json",
        success: function (response) {
            if (response.Success) {
                RefreshPropertyGridViewFromHiddenSelection($("#" + PropertyGridPartialViewDivId));
                RefreshSelectedContent();
            }
            else {
                ToastError("AjaxPropertyEditorAddItem", response.ErrorResults);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxPropertyEditorAddItem", errormsg);
            console.log('AJAX: ' + errormsg);
        }
    });
}



function AjaxPropertyEditorDeleteItem(PropertyId, Value, DbTable, RecordId, DeleteItemId, ObjectType) {

    var ContentType = GetSelectedContentType();

    var params = {
        "ContentType": ContentType,
        "PropertyId": PropertyId,
        "Value": Value,
        "DbTable": DbTable,
        "RecordId": RecordId,
        "DeleteItemId": DeleteItemId,
        "ObjectType": ObjectType,
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxPropertyEditorDeleteItem",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json",
        success: function (response) {
            if (response.Success) {
                RefreshPropertyGridViewFromHiddenSelection($("#" + PropertyGridPartialViewDivId));
                RefreshSelectedContent();
            }
            else {
                ToastError("AjaxPropertyEditorDeleteItem", response.ErrorResults);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxPropertyEditorDeleteItem", errormsg);
            console.log('AJAX: ' + errormsg);
        }
    });
}



function OnPropertyEditorEditItem(PropertyId, sDbTable, sRecordId, sEditItemSystemType, sEditItemId, sEditItemName) {

    //ToastMessage("OnPropertyEditorEditItem:", PropertyId + "\r\n\r\n" + sDbTable + "\r\n\r\n" + sRecordId + "\r\n\r\n" + sEditItemSystemType + "\r\n\r\n" + sEditItemId + "\r\n\r\n" + sEditItemName);

    // Remember these for use when user clicks OK to add the new item
    PropertyEditorItemPropertyId = PropertyId;
    PropertyEditorItemDbTable = sDbTable;
    PropertyEditorItemRecordId = sRecordId;
    PropertyEditorItemEditId = sEditItemId;
    PropertyEditorItemObjectType = sEditItemSystemType;
    PropertyEditorItemName = sEditItemName;

    // Display properties for the sEditItemId
    RefreshPropertyEditorPropertyGridView();
}


/**
 * Display the property grid for this object
 */
function RefreshPropertyEditorPropertyGridView() {

    $("#HiddenSelectedTableId").val(PropertyEditorItemDbTable);
    $("#HiddenSelectedDataTypeId").val(PropertyEditorItemObjectType);
    $("#HiddenSelectedRecordId").val(PropertyEditorItemEditId);

    // Fill properties with partial view from server
    AjaxRefreshPropertyGridView($("#" + PropertyGridPartialViewDivId), PropertyEditorItemPropertyId, PropertyEditorItemObjectType/*ObjectDataType*/, PropertyEditorItemDbTable/*ObjectTable*/, PropertyEditorItemEditId/*ObjectRecordId*/, ""/*SelectedCellTable*/, ""/*SelectedCellColumnId*/, ""/*PropertyValuesJsonString*/);
}

function OnPropertyEditorDeleteItem(PropertyId, sDeleteTitle, sDeletePrompt, sDbTable, sRecordId, sEditItemSystemType, sEditItemId, sEditItemName) {

    //ToastMessage("OnPropertyEditorDeleteItem:", PropertyId + "\r\n\r\n" + sDbTable + "\r\n\r\n" + sRecordId + "\r\n\r\n" + sEditItemSystemType + "\r\n\r\n" + sEditItemId + "\r\n\r\n" + sEditItemName);

    // Remember these for use when user clicks OK to add the new item
    PropertyEditorItemPropertyId = PropertyId;
    PropertyEditorItemDbTable = sDbTable;
    PropertyEditorItemRecordId = sRecordId;
    PropertyEditorItemEditId = sEditItemId;
    PropertyEditorItemObjectType = sEditItemSystemType;
    PropertyEditorItemName = sEditItemName;

    PopupYesNoWithCallback(sDeleteTitle, sDeletePrompt, OnOkPropertyEditorDeleteItemCallback);
}

/**
 * User clicked OK to delete a property editor item
 */
function OnOkPropertyEditorDeleteItemCallback() {

    //ToastMessage("OnOkPropertyEditorDeleteItemCallback:", PropertyEditorItemDbTable + "\r\n\r\n" + PropertyEditorItemRecordId + "\r\n\r\n" + PropertyEditorItemName);

    // Call Ajax to add the new item to the selected recordid
    AjaxPropertyEditorDeleteItem(PropertyEditorItemPropertyId, PropertyEditorItemName, PropertyEditorItemDbTable, PropertyEditorItemRecordId, PropertyEditorItemEditId, PropertyEditorItemObjectType);

    // Close the dropdown that originated this
    CloseLastDropdown();
}



//\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\//
//\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\//
//\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\//
// Popup list of records


function CreatePopupForRecordsetList(ElementObj, PopupDivIdPrefix, TableName, RecordId, OnItemClickFunction, PerformMenuAction, IfListIsEmptyFunction, FilterJsonString) {

    // Build the popup which will contain a list of record items to choose from
    var PopupDiv = CreatePopupDiv(ElementObj, PopupDivIdPrefix);
    if (!PopupDiv) {
        ToastError("Popup", "Hmm, something went wrong creating the popup!");
        return;
    }

    // Add the record items to a ul list inside this div
    AjaxGetRecordItemsInPopupList(event, ElementObj, PopupDiv, ""/*ContentType*/, TableName, RecordId, OnItemClickFunction, PerformMenuAction, IfListIsEmptyFunction, FilterJsonString);
}


function CreatePopupForCsvList(ElementObj, CsvNames, OnItemClickFunction, OnDragStartFunction, IfListIsEmptyFunction) {

    if (!ElementObj)
        return;
    if (!ElementObj.length)
        return;

    // Build the popup which will contain a list of record items to choose from
    var PopupDiv = CreatePopupDiv(ElementObj, "PopupListDiv-TaskHintItems-"/*PopupDivIdPrefix*/);
    if (!PopupDiv) {
        ToastError("Popup", "Hmm, something went wrong creating the popup!");
        return;
    }

    AjaxGetCsvItemsInPopupList(event, null/*element*/, PopupDiv, CsvNames, OnItemClickFunction, OnDragStartFunction, IfListIsEmptyFunction);
}


var PopupDivOpenTime = new Date();

function OnClickOutsidePopupDiv() {

    // Strangely, click comes in immediate after display
    // Ignore immediate clicks
    var clicktime = new Date($.now());
    var timeDiff = clicktime - PopupDivOpenTime;
    if (timeDiff < 200)
        return;

    // Get div element to check if click is outside it
    var CurrentPopupDivId = $('input[id="HiddenPopupDivId"]').val();
    if (!CurrentPopupDivId || CurrentPopupDivId == null)
        return;
    var PopupDivObject = $("#" + CurrentPopupDivId);
    if (!PopupDivObject || PopupDivObject.length == 0)
        return;
    var PopupDivElement = PopupDivObject[0];
    if (!PopupDivElement)
        return;

    // Click outside div?
    if (PopupDivElement !== event.target && !PopupDivElement.contains(event.target)) {
        CloseLastPopup();
        //ToastError("OnClickOutsidePopupDiv", "Got it!");
    }
}


function CreatePopupDiv(ElementObj, idprefix) {

    if (!ElementObj)
        return;
    if (ElementObj.length == 0)
        return;

    // Already one open?
    CloseLastPopup();

    var InitiatorId = ElementObj.attr("id");
    if (!InitiatorId)
        return;

    // Add new div to body
    var PopupDivId = GetUniqueId(idprefix);
    var PopupDiv = jQuery('<div>', {
        id: PopupDivId,
        class: 'popuplistdiv',
    });
    PopupDiv.appendTo("body");
    PopupDiv.attr("data-initiator", InitiatorId);
    RepositionDropdownUnderInitiator(PopupDivId);

    // Save this so the popup can be closed
    $('input[id="HiddenPopupDivId"]').val(PopupDivId);
    $('input[id="HiddenPopupRemoveFromBody"]').val("true");

    // Add listener to hide the popup if clicked outside
    PopupDivOpenTime = new Date($.now());
    document.removeEventListener("click", OnClickOutsidePopupDiv);
    document.addEventListener("click", OnClickOutsidePopupDiv);

    // Loading...
    PopupDiv.html("Loading...<br /> <img width=\"16\" height=\"16\" src=\"/Content/images/ajax-loader-large.gif\" />");

    return PopupDiv;
}



function AjaxGetRecordItemsInPopupList(event, element, popupdiv, ContentType, TableName, RecordId, OnItemClickFunction, OnDragStartFunction, IfListIsEmptyFunction, FilterJsonString) {

    var params = {
        "ContentType": ContentType,
        "TableName": TableName,
        "RecordId": RecordId,
        "OnClickFunction": OnItemClickFunction,
        "OnDragStartFunction": OnDragStartFunction,
        "FilterJsonString": FilterJsonString,
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxGetRecordItemsAsMiniHtmlTreeView",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json",
        success: function (response) {
            if (response.Success) {

                // Empty list. No point in a popup. Do something else instead
                if (response.ItemCount == 0 && IfListIsEmptyFunction) {
                    IfListIsEmptyFunction(ContentType, TableName, RecordId);
                    return;
                }

                var sHtmlTreeView = "<div class='popuplistminihtmltreeviewholder'>" + response.MiniHtmlTreeView + "</div>";
                popupdiv.html(sHtmlTreeView);

                // Html data is for a Mini Tree View
                // This is a list of <ul> and <li> items that act as a tree
                // https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_treeview
                SetupMiniHtmlTreeView(popupdiv);
            }
            else {
                if (response.ErrorResults)
                    ToastError("AjaxGetRecordItemsInPopupList", response.ErrorResults);
                else if (response.ToastMessage)
                    ToastError("Popup list: ", response.ToastMessage);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxGetRecordItemsInPopupList", errormsg);
            console.log('AjaxGetRecordItemsInPopupList AJAX: ' + errormsg);
        }
    });
}



function AjaxGetCsvItemsInPopupList(event, element, popupdiv, CsvItems, OnItemClickFunction, OnDragStartFunction, IfListIsEmptyFunction) {

    var params = {
        "CsvItems": CsvItems,
        "OnClickFunction": OnItemClickFunction,
        "OnDragStartFunction": OnDragStartFunction,
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxGetCsvItemsInPopupList",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json",
        success: function (response) {
            if (response.Success) {

                // Empty list. No point in a popup. Do something else instead
                if (response.ItemCount == 0 && IfListIsEmptyFunction) {
                    IfListIsEmptyFunction(ContentType, TableName, RecordId);
                    return;
                }

                var sHtmlTreeView = "<div class='popuplistminihtmltreeviewholder'>" + response.MiniHtmlTreeView + "</div>";
                popupdiv.html(sHtmlTreeView);

                // Html data is for a Mini Tree View
                // This is a list of <ul> and <li> items that act as a tree
                // https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_treeview
                SetupMiniHtmlTreeView(popupdiv);
            }
            else {
                if (response.ErrorResults)
                    ToastError("AjaxGetCsvItemsInPopupList", response.ErrorResults);
                else if (response.ToastMessage)
                    ToastError("Popup list: ", response.ToastMessage);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxGetCsvItemsInPopupList", errormsg);
            console.log('AjaxGetCsvItemsInPopupList AJAX: ' + errormsg);
        }
    });
}








