using Microsoft.Security.Application.AntiXss;
using Microsoft.Security.Application.Sanitizer;
/// 
///     Sortable control
/// 
[FormControlAttribute('VKOSortableList', '/resources/html/VKOSortableListControlHTML.html', classStr(VKOSortableListBuild))]
class VKOSortableList extends FormTemplateControl
{
    FormProperty SortableItems;
    public void new(FormBuildControl _build, FormRun _formRun)
    {
        super(_build, _formRun);
        //this.setTemplateId('VKOSortableList');
        this.setResourceBundleName("/resources/html/VKOSortableListControlHTML.html");
        SortableItems = this.addProperty(methodstr(VKOSortableList, parmSortableItems), Types::Class);
    }
    /// 
    /// Applies the build configurations to the run instance of the control.
    /// 
    /// 
    /// ApplyBuild of the form part control should be called only in formRun::Init() method.
    /// 
    public void applyBuild()
    {
        VKOSortableListBuild build;
        super();
        build = this.build();
        if (build)
        {
            List  sortableItemsLoc = build.parmSortableItems();
        
            if (this.isDataSourceBinded())
            {
                DataSourceName      dataSourceName      = build.parmDataSourceName();
                FieldName           fieldNameName       = build.parmDataFieldNameName();
                FieldName           fieldNameSort       = build.parmDataFieldNameSort();
                FormDataSource      fds                 = this.formRun().dataSource(dataSourceName);
                Common                  sortableTable   = fds.cursor();
                FieldId                 fieldIdName     = fieldName2Id(sortableTable.TableId, fieldNameName);
                FieldId                 fieldIdSort     = fieldName2Id(sortableTable.TableId, fieldNameSort);
                VKOSortableListItem     sortableItem;
                List                    itemList        = this.getRecordsList();
                ListEnumerator          le;
                sortableItemsLoc    = new List(Types::Class);
                if (itemList.elements())
                {
                    le = itemList.getEnumerator();
                    while (le.moveNext())
                    {
                        sortableTable = le.current();
                        sortableItem    = new VKOSortableListItem();
                        sortableItem.parmText(sortableTable.(fieldIdName));
                        sortableItem.parmRecId(sortableTable.RecId);
                        sortableItemsLoc.addEnd(sortableItem);
                    }
                }
                //this.setTemplateId('VKOSortableList');
                //this.setResourceBundleName(build.resourceBundleName());
            }
            this.parmSortableItems(sortableItemsLoc);
        }
    }
    [FormCommandAttribute(identifierstr(OrderModified), true)]
    private void orderModified(str serializedOrder)
    {
        info('sort: '+serializedOrder);
        container       recIdCon = str2con(serializedOrder, ",");
        int             curIndex = 0,
                        conLen   = conLen(recIdCon);
        RefRecId        refRecId;
        List            itemList = this.getRecordsList();
        Common          sortableTable;
        if (this.isDataSourceBinded() && conLen > 0 && itemList.elements())
        {
            VKOSortableListBuild    build               = this.build();
            FieldName               fieldNameSort       = build.parmDataFieldNameSort();
            FieldId                 fieldIdSort         = fieldName2Id(sortableTable.TableId, fieldNameSort);
            Map                     itemMap             = new Map(Types::Int64, Types::Record);
            ListEnumerator          le;
            if (itemList.elements())
            {
                le = itemList.getEnumerator();
                while (le.moveNext())
                {
                    sortableTable = le.current();
                    itemMap.insert(sortableTable.RecId, sortableTable);
                }
            }
            ttsbegin;
            for (curIndex = 1; curIndex <= conLen; curIndex++)
            {
                refRecId = str2Int64(conPeek(recIdCon, curIndex));
                if (refRecId)
                {
                    if (itemMap.exists(refRecId))
                    {
                        sortableTable = itemMap.lookup(refRecId);
                        if (!fieldIdSort)
                        {
                            fieldIdSort = fieldName2Id(sortableTable.TableId, fieldNameSort);
                        }
                        if (sortableTable.(fieldIdSort) != curIndex)
                        {
                            sortableTable.(fieldIdSort) = curIndex;
                            sortableTable.selectForUpdate(true);
                            sortableTable.update();
                        }
                    }
                }
            }
            ttscommit;
        }
    }
    [FormPropertyAttribute(FormPropertyKind::Value, identifierstr(SortableItems))]
    public List parmSortableItems(List _sortableItems = SortableItems.parmValue())
    {
        if (!prmIsDefault(_sortableItems))
        {
            SortableItems.setValueOrBinding(_sortableItems);
        }
        return SortableItems.parmValue();
    }
    /* */
    protected boolean isDataSourceBinded()
    {
        boolean                 ret     = false;
        VKOSortableListBuild    build   = this.build();
        if (build && build.parmDataSourceName() && build.parmDataFieldNameName() && build.parmDataFieldNameSort())
        {
            ret = true;
        }
        return ret;
    }
    protected List getRecordsList()
    {
        List recordList = new List(Types::Record);
        if(this.isDataSourceBinded())
        {
            VKOSortableListBuild    build               = this.build();
            DataSourceName          dataSourceName      = build.parmDataSourceName();
            FieldName               fieldNameName       = build.parmDataFieldNameName();
            FieldName               fieldNameSort       = build.parmDataFieldNameSort();
            FormDataSource          fds                 = this.formRun().dataSource(dataSourceName);
            Common                  sortableTable   = fds.cursor();
            FieldId                 fieldIdSort     = fieldName2Id(sortableTable.TableId, fieldNameSort);
            Query                   q               = new Query();
            QueryBuildDataSource    qbds            = q.addDataSource(sortableTable.TableId);
            QueryRun                qr;
            qbds.addSortField(fieldIdSort);
            qr = new QueryRun(q);
            qr.setCursor(sortableTable);
                
            while (qr.next())
            {
                recordList.addEnd(sortableTable);
            }
        }
        return recordList;
    }
}