
//\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\//
// Property grid functions
//\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\////\\//

var SelectPropertyElementAfterRebuildId = null;

// EditCellEnded
// Event which is raised after end cell editing.
// Function takes arguments evt and ui.Use ui.owner to get reference to igGridUpdating.
// Use ui.owner.grid to get reference to igGrid.
// Use ui.rowID to get key or index of row.
// Use ui.columnIndex to get index of column.
// Use ui.columnKey to get key of column.
// Use ui.editor to get reference to igEditor.
// Use ui.value to get value of cell.
// Use ui.oldValue to get old value.
// Use ui.update to check if cell was modified and data source will be updated.
// Use ui.rowAdding to check if that event is raised while new- row - adding.

function PropertyGridEditCellEnded(evt, ui) {

    if (!ui.update)
        return;

    //var GridId = evt.target.id;
    //var Grid = ui.owner;
//    var RecordTableName = Grid.grid.getCellValue(ui.rowID, "COL_DBTABLE");
//    var RecordId = Grid.grid.getCellValue(ui.rowID, "GUID");
//    var PropertyName = Grid.grid.getCellValue(ui.rowID, "COL_PROPERTYNAME");
//    var PropertyId = Grid.grid.getCellValue(ui.rowID, "COL_PROPERTYID");
}

// Watch for "Enter" key to set database record value
function SetContentPropertyValueOnEnterKey(element, PropertyName, PropertyId, ContentType, RecordTableName, RecordId) {

    // Check for Enter key
    if (event.key === 'Enter') {
        SelectPropertyElementAfterRebuildId = element.id;
        AjaxSetContentPropertyValueByElement(element, PropertyName, PropertyId, ContentType, RecordTableName, RecordId);
        SelectNextInput(element);
    }
}

/**
 * Ajax functions sets the database record value
 * @param {any} element
 * @param {any} PropertyName
 * @param {any} PropertyId
 * @param {any} RecordTableName
 * @param {any} RecordId
 */
function AjaxSetContentPropertyValueByElement(element, PropertyName, PropertyId, ContentType, RecordTableName, RecordId) {

    if (!element)
        return;

    // Any change?
    var OldValue = element.oldvalue;
    var NewValue = element.value;
    if (OldValue == NewValue)
        return;
    element.oldvalue = element.value;
    SelectPropertyElementAfterRebuildId = element.id;

    AjaxSetContentPropertyValue(NewValue, PropertyName, PropertyId, ContentType, RecordTableName, RecordId);
}

function AjaxSetContentPropertyValue(NewValue, PropertyName, PropertyId, ContentType, RecordTableName, RecordId) {

    var FilterJsonString = GetSelectedContentPaneFilterJsonString();

    var params = {
        "NewValue": NewValue,
        "PropertyName": PropertyName,
        "PropertyId": PropertyId,
        "ContentType": ContentType,
        "TableName": RecordTableName,
        "RecordId": RecordId,
        "FilterJsonString": FilterJsonString,
    };

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

                // Refresh the grid contents to show the new property value
                SetSelectRecordIdAfterRebuild(RecordTableName, RecordId);
                //RefreshSelectedContent();
                DeferRefreshSelectedContent();

                // Refresh the property grid because the entire record may have changed when this property was set
                // Example: Change Actual work, Stop date is also changed as a result
                //RefreshPropertyGridViewFromHiddenSelection($("#" + PropertyGridPartialViewDivId));
                DeferRefreshPropertyGrid();

                // Perform actions after property has been set
                setTimeout(function () { OnAfterSetContentPropertyValue(NewValue, PropertyName, PropertyId, ContentType, RecordTableName, RecordId); }, 500);
            }
            else {
                if (response.ErrorResults)
                    ToastError("AjaxSetContentPropertyValue", response.ErrorResults);
                else
                    ToastError("AjaxSetContentPropertyValue", response);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxSetContentPropertyValue", errormsg);
            console.log('AJAX: ' + errormsg);
        }
    });
}


function AjaxGetContentPropertyValue(ContentType, RecordTableName, RecordId, DbColumn, successcallback) {

    var params = {
        "ContentType": ContentType,
        "TableName": RecordTableName,
        "RecordId": RecordId,
        "DbColumn": DbColumn,
    };

    $.ajax({
        url: VirtualDirectory + "/Home/AjaxGetContentPropertyValue",
        type: "POST",
        data: JSON.stringify(params),
        contentType: "application/json",
        success: function (response) {
            if (response.Success) {
                if (successcallback)
                    successcallback(ContentType, RecordTableName, RecordId, DbColumn, response.PropertyValue);
            }
            else {
                ToastError("AjaxGetContentPropertyValue", response.ErrorResults);
            }
        },
        error: function (xhr, status, error) {
            var errormsg = "Error " + xhr.status + ", " + xhr.statusText;
            ToastError("AjaxGetContentPropertyValue", errormsg);
            console.log('AJAX: ' + errormsg);
        }
    });
}

function CheckSelectPropertyElementAfterRebuild(element) {

    if (!SelectPropertyElementAfterRebuildId)
        return;

    // Scroll the element back into view
    // Ensure visible
    var DomElement = document.getElementById(SelectPropertyElementAfterRebuildId);
    if (DomElement) {
        ScrollIntoViewIfNeeded(DomElement);
    }

    // Special attribute holding the grid id for selection
    if (!element)
        return;
    var GridId = $(element).attr("data-gridid");
    if (!GridId)
        return;
}


function SelectNextInput(element) {

    // Hmm, doesn't work
    //$(this).next('input').focus();

//    var NextElement = $(element).next('input');
//    if (NextElement)
//        NextElement.focus();

    //var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
    //focusable = form.find('input').filter(':visible');
    //next = focusable.eq(focusable.index(this) + 1);
    //if (next.length) {
    //    next.focus();
    //}

}



/**
 * Watch for "Enter" key to set database record value
 * @param {any} element
 * @param {any} PropertyName
 * @param {any} PropertyId
 * @param {any} RecordTableName
 * @param {any} RecordId
 */
function SetCookiePropertyValueOnEnterKey(element, PropertyName, PropertyId, ContentType, RecordTableName, RecordId) {

    // Check for Enter key
    if (event.key === 'Enter') {
        SetCookiePropertyValue(element, PropertyName, PropertyId, ContentType, RecordTableName, RecordId);
        SelectNextInput(element);
    }
}

/**
 * Save value to cookie
 * @param {any} element
 * @param {any} PropertyName
 * @param {any} PropertyId
 * @param {any} RecordTableName
 * @param {any} RecordId
 */
function SetCookiePropertyValue(element, PropertyName, PropertyId, ContentType, RecordTableName, RecordId) {

    if (!element)
        return;
    if (!PropertyId)
        return;

    // Any change?
    var OldValue = element.oldvalue;
    var NewValue = element.value;
    if (OldValue == NewValue)
        return;
    element.oldvalue = element.value;

    // Save value in cookie
    setCookie(PropertyId, NewValue, 365);

    // Send the barcode defaults to the server for used during scanning
    AjaxSetBarcodeDefaults();

    // Refresh the property grid because the entire record may have changed when this property was set
    // Example: Change project, so the list of project tasks must be reloaded
    RefreshBarcodeDefaultsPropertyGridView();

    //console.log("SetCookiePropertyValue: " + PropertyName + ", " + PropertyId + ", " + OldValue + ", " + NewValue);
}

function SetPropertyValueFromCookie(element, cookiename) {

    if (!element)
        return;
    if (!cookiename)
        return;

    var sValue = getCookie(cookiename);
    $(element).val(sValue);

    //console.log("SetPropertyValueFromCookie: " + $(element).attr("id") + ", " + cookiename + ", " + sValue);
}


function SetPropertyValueFromCookieIfNotNull(element, cookiename) {

    if (!element)
        return;
    if (!cookiename)
        return;

    var sValue = getCookie(cookiename);
    if (sValue != null)
        $(element).val(sValue);

    //console.log("SetPropertyValueFromCookie: " + $(element).attr("id") + ", " + cookiename + ", " + sValue);
}




function SetClientPropertyValueOnEnterKey(element, PropertyType, PropertyName, ContentType, RecordTableName, RecordId) {

    // Check for Enter key
    if (event.key === 'Enter') {
        SetClientPropertyValue(element, PropertyName, ContentType, RecordTableName, RecordId);
        SelectNextInput(element);
    }
}


function SetClientPropertyValue(element, PropertyType, PropertyName, ContentType, RecordTableName, RecordId) {

    if (!element)
        return;

    // Any change?
    var OldValue = element.oldvalue;
    var NewValue = element.value;
    if (OldValue == NewValue)
        return;
    element.oldvalue = element.value;

    // View settings (Grouping, Totals on top, Totals on bottom, etc)
    if (PropertyType == "VIEWSETTINGS") {
        ProcessSettings(PropertyName, NewValue, PropertyName);
        return;
    }
}





/**
 * Grid is fully rendered
 * @param {any} event
 * @param {any} ui
 */
function OnPropertyGridRendered(event, ui) {

    if (!ui)
        return;
    if (!ui.owner) // reference to igGrid
        return;

    var Grid = ui.owner;
    var GridObj = $(ui.owner);
    if (!GridObj)
        return;
    if (GridObj.length == 0)
        return;
    var GridId = event.target.id;
    if (!GridId)
        return;
    var GridElement = $("#" + GridId);
    if (!GridElement)
        return;
    if (GridElement.length == 0)
        return;

    try {
        CollapasePropertyGridRows(GridElement);
    } catch (e) {
        ToastError("OnPropertyGridRendered", e.name + ": " + e.message);
        console.log("OnPropertyGridRendered: " + e.name + ": " + e.message);
    }
}

function CollapasePropertyGridRows(GridElement) {

    // Special grid attributes, after grid has rendered
    var CollapsedProperties = [];
    var bManuallyCollapsed = GetHasManualCollapsedPropertiesCookie();
    if (!bManuallyCollapsed) {
        // Collapse default sections so the list is not overwhelming
        //ToastMessage("OnPropertyGridRendered", "Auto-collapse");
        CollapsedProperties = GetAllPropertyParentPropertyIds(GridElement);
        if (!CollapsedProperties)
            return;

        // Don't collapse the first two
        // Collapse all the sections after the first two
    //    if (CollapsedProperties.length > 2) {
    //        CollapsedProperties.splice(0, 1);
    //        CollapsedProperties.splice(0, 1);
    //    }
        if (CollapsedProperties.length >= 1)
            CollapsedProperties.splice(0, 1);
        if (CollapsedProperties.length >= 1)
            CollapsedProperties.splice(0, 1);
    }
    else {
        // Collapse only the manually collapsed rows (user clicked rocker button to specifically collapse/expand a section)
        CollapsedProperties = GetCollapsedPropertiesCookieAsArray();
    }

    //ToastMessage("OnPropertyGridRendered", "CollapsedProperties: " + CollapsedProperties.length);
    CollapsePropertyGridParentsById(GridElement, CollapsedProperties);
}

function CollapsePropertyGridParentsById(GridElement, RowIds) {

    // Row "data-id" atrribute
    //ToastMessage("CollapsePropertyGridParentsById", "okay");
    if (!RowIds)
        return;
    if (RowIds.length == 0)
        return;

    for (i = 0; i < RowIds.length; ++i) {
        var sPropertyId = RowIds[i];
        var Row = GridElement.find("[data-id='" + sPropertyId + "']");
        if (Row && Row.length > 0)
            GridElement.igTreeGrid("collapseRow", Row);
    }
}

function GetAllPropertyParentPropertyIds(GridElement) {

    var ParentPropertyIds = [];
    var ParentRows = GridElement.find("[aria-level='0']");
    if (!ParentRows)
        return ParentPropertyIds;
    if (ParentRows.length == 0)
        return ParentPropertyIds;

    for (i = 0; i < ParentRows.length; ++i) {
        var ParentRow = ParentRows[i];
        var DataId = $(ParentRow).attr("data-id");
        ParentPropertyIds.push(DataId);
    }

    return ParentPropertyIds;
}


function OnPropertyGridRowCollapsed(event, ui) {

    if (!ui)
        return;
    if (!ui.owner) // reference to igGrid
        return;
    if (!ui.dataRecord)
        return;
    if (!ui.dataRecord.Property)
        return;

    var Grid = ui.owner;
    var GridObj = $(ui.owner);
    if (!GridObj)
        return;
    if (GridObj.length == 0)
        return;
    var GridId = event.target.id;
    if (!GridId)
        return;
    var GridElement = $("#" + GridId);
    if (!GridElement)
        return;
    if (GridElement.length == 0)
        return;

    AddPropertyToCollapsedCookie(ui.dataRecord.Property);
    SetHasManuallyCollapsedPropertiesCookie();
    //ToastError("OnPropertyGridRowCollapsed", SelectedTableId + ", " + ui.dataRecord.Property);
}

function OnPropertyGridRowExpanded(event, ui) {

    if (!ui)
        return;
    if (!ui.owner) // reference to igGrid
        return;
    if (!ui.dataRecord)
        return;
    if (!ui.dataRecord.Property)
        return;

    var Grid = ui.owner;
    var GridObj = $(ui.owner);
    if (!GridObj)
        return;
    if (GridObj.length == 0)
        return;
    var GridId = event.target.id;
    if (!GridId)
        return;
    var GridElement = $("#" + GridId);
    if (!GridElement)
        return;
    if (GridElement.length == 0)
        return;

    RemovePropertyFromCollapsedCookie(ui.dataRecord.Property);
    SetHasManuallyCollapsedPropertiesCookie();
    //ToastError("OnPropertyGridRowExpanded", SelectedTableId + ", " + ui.dataRecord.Property);
}




function DeferRefreshPropertyGrid(seconds, callbackfunction) {

    if (!seconds || seconds == null || seconds <= 0)
        seconds = GetDeferRefreshSecondsFromCookie();
    if (seconds <= 0) {
        RefreshPropertyGridViewFromHiddenSelection($("#" + ActivePropertyGridPartialViewDivId));
        return;
    }

    //console.log("DeferRefreshSelectedContent: " + seconds);

    // If you don't clear the timeout below, you get repeated refreshes every time you enter a grid value
    // Example: Type repeatedly into timesheet cells, and you will get repeated refreshes that are very annoying
    // So, you must clear this timeout for each timesheet entry
    if (PrtDeferTimeoutID > 0)
        clearTimeout(PrtDeferTimeoutID);
    PrtDeferTimeoutID = 0;

    // Add the progress bar
    AddPrtCircleProgressBarElements();
    var PrtProgressBarObject = GetPrtCircleProgressObject();

    // Set a timer to refresh the page
    PrtDeferTimeoutID = setTimeout(function () {

        //console.log("DeferRefreshPropertyGrid timeout");

        // Hide the progress bar
        //$('#PrtCircleProgressBar').css('display', 'none');
        if (PrtProgressBarObject && PrtProgressBarObject.length > 0)
            PrtProgressBarObject.css('display', 'none');

        // Refreshing every time an "Edit" dialog is open is disruptive
        RefreshPropertyGridViewFromHiddenSelection($("#" + ActivePropertyGridPartialViewDivId));

        // Callback when the content is refreshed
        if (callbackfunction) {
            setTimeout(function () { callbackfunction(); }, 20);
        }

    }, (seconds * 1000));

    //console.log("DeferRefreshPropertyGrid setTimeout ID: " + PrtDeferTimeoutID);

    // Start circle progress bar to show countdown
    if (PrtCirclebarObject)
        PrtCirclebarObject.clearCircle();
    //$('#PrtCircleProgressBar').css('display', 'block');
    if (PrtProgressBarObject && PrtProgressBarObject.length > 0)
        PrtProgressBarObject.css('display', 'block');

    //PrtCirclebarObject = new Circlebar({ element: "#PrtCircleProgressBar", startValue: 0, maxValue: seconds, skin: "purple", });
    PrtCirclebarObject = null;
    if (PrtProgressBarObject && PrtProgressBarObject.length > 0)
        PrtCirclebarObject = new Circlebar({ element: PrtProgressBarObject, startValue: 0, maxValue: seconds, skin: "purple", });
}


/**
 * Cancel the countdown and refresh Properties
 */
function CancelPropertiesCountdownAndRefresh() {

    if (PrtDeferTimeoutID > 0)
        clearTimeout(PrtDeferTimeoutID);
    PrtDeferTimeoutID = 0;

    var PrtProgressBarObject = GetPrtCircleProgressObject();
    if (PrtProgressBarObject && PrtProgressBarObject.length > 0)
        PrtProgressBarObject.css('display', 'none');

    RefreshPropertyGridViewFromHiddenSelection($("#" + ActivePropertyGridPartialViewDivId));
}



/**
 * A new property value has been successfully set
 * Perform follow-up functions
 * @param {any} NewValue
 * @param {any} PropertyName
 * @param {any} PropertyId
 * @param {any} ContentType
 * @param {any} RecordTableName
 * @param {any} RecordId
 */
function OnAfterSetContentPropertyValue(NewValue, PropertyName, PropertyId, ContentType, RecordTableName, RecordId) {

    //ToastError(PropertyId, NewValue);

    if (ContentType == "QBCUSTOMERQUERY")
        AjaxQueryQbCustomerCount(ContentType);
    else if (ContentType == "QBEXPORTTIME")
        AjaxQueryQbExportRecordCount(ContentType, false/*FirstQuery*/);
    else if (ContentType == "QBEXPORTEXPENSES")
        AjaxQueryQbExportRecordCount(ContentType, false/*FirstQuery*/);
}





