Imports Microsoft.VisualBasic
Imports System
Imports System.Web.UI.WebControls
Imports System.Collections
Imports System.Collections.Generic
Imports BaseClasses
Imports BaseClasses.Web.UI.WebControls
Imports BaseClasses.Data
Imports BaseClasses.Data.BaseFilter.ComparisonOperator
Imports BaseClasses.Data.BaseFilter
Imports BaseClasses.Utils
Imports BaseClasses.Data.OrderByItem.OrderDir

Namespace Persons.UI.Controls.LargeListSelector

#Region "Section 1: Place your customizations here."

    Public Class ItemsTableRecordControl
        Inherits BaseItemsTableRecordControl

    End Class

    ' The ItemsTable class implements the query used to retrieve records
    ' to be displayed in the grid.  The static query at design time is combined with the dynamic
    ' filter and search criteria.

    Public Class ItemsTable
        Inherits BaseItemsTable

    End Class

#End Region

#Region "Section 2: Do not modify this section."
    ' Base class for the ItemsTableRecordControl control on the LargeListSelector page.
    Public Class BaseItemsTableRecordControl
        Inherits Persons.UI.BaseApplicationRecordControl

        Private Const ASSEMBLY_NAME As String = "Persons.Business"

        Protected Overridable Sub Control_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Init
            ' Register the event handlers.
            AddHandler Me.SelectButton.Click, AddressOf SelectButton_Click

            Me.Page.RegisterPostBackTrigger(Me.SelectButton, MiscUtils.GetParentControlObject(Me, "ItemsTableControlUpdatePanel"))

        End Sub

        Protected Overridable Sub Control_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

        End Sub

        ' Populate the UI controls using the DataSource.
        Public Overrides Sub DataBind()

            ' Make sure that the DataSource is initialized.
            If Me.DataSource Is Nothing Then
                Return
            End If

            Dim table As ItemsTable = DirectCast(Me.Page.FindControlRecursively("ItemsTable"), ItemsTable)
            Dim td As BaseClasses.Data.TableDefinition = table.GetTable().TableDefinition
            Dim col As BaseClasses.Data.BaseColumn = td.ColumnList.GetByAnyName(table.Field)
            Dim displayCol As BaseClasses.Data.BaseColumn = td.ColumnList.GetByAnyName(table.DisplayField)

            Me.ValueText.Text = Me.DataSource.GetValue(col).ToString()

            Dim formula As String = table.Formula()
            Dim dfka As String = ""

            If Not String.IsNullOrEmpty(formula) Then
                Me.ItemText.Text = Me.EvaluateFormula(formula, Me.DataSource, Nothing, td.TableCodeName)
            Else
                If displayCol Is Nothing Then
                    dfka = table.DisplayField
                    If dfka.Trim.StartsWith("=") Then
                        Me.ItemText.Text = Me.EvaluateFormula(dfka, Me.DataSource, Nothing, td.TableCodeName)
                    Else
                        Me.ItemText.Text = Me.DataSource.Format(col)
                    End If
                Else
                    Me.ItemText.Text = Me.DataSource.Format(displayCol)
                End If

            End If

        End Sub

        ' Read data from database.
        Public Overridable Sub LoadData()
        End Sub


        Public Overridable Function EvaluateFormula(ByVal formula As String) As String
            Dim e As FormulaEvaluator = New FormulaEvaluator()


            e.DataSource = Me.DataSource

            ' Define the calling control.  This is used to add other 
            ' related table and record controls as variables.
            e.CallingControl = Me

            Dim resultObj As Object = e.Evaluate(formula)
            If resultObj Is Nothing Then
                Return ""
            End If

            Return resultObj.ToString()
        End Function

        Public Overridable Function EvaluateFormula(ByVal formula As String, ByVal dataSourceForEvaluate As BaseClasses.Data.BaseRecord, Optional ByVal format As String = Nothing, Optional ByVal name As String = "") As String
            Dim e As Persons.Data.BaseFormulaEvaluator = New Persons.Data.BaseFormulaEvaluator()
            If Not dataSourceForEvaluate Is Nothing Then
                e.Evaluator.Variables.Add(name, dataSourceForEvaluate)
            End If
            e.DataSource = dataSourceForEvaluate

            Dim resultObj As Object = e.Evaluate(formula)
            If resultObj Is Nothing Then
                Return ""
            End If
            If Not String.IsNullOrEmpty(format) Then
                Return Persons.Data.BaseFormulaUtils.Format(resultObj, format)
            Else
                Return resultObj.ToString()
            End If
        End Function

        Protected Overridable Sub SelectButton_Click(ByVal sender As Object, ByVal args As EventArgs)
            Dim table As ItemsTable = DirectCast(Me.Page.FindControlRecursively("ItemsTable"), ItemsTable)
            Me.RegisterSelectValueScript(table.Target, Me.ValueText.Text, Me.ItemText.Text)

            Dim keyForVal As String = table.Target & "_SelectedValue"
            Dim keyForDisplayText As String = table.Target & "_SelectedDisplayText"

            Me.Page.Session.Add(keyForVal, Me.ValueText.Text)
            Me.Page.Session.Add(keyForDisplayText, Me.ItemText.Text)
        End Sub

        Protected Overrides Sub LoadViewState(ByVal savedState As Object)
            MyBase.LoadViewState(savedState)
        End Sub

        Protected Overrides Function SaveViewState() As Object
            Return MyBase.SaveViewState()
        End Function

        Private _DataSource As IRecord
        Public Property DataSource() As BaseRecord
            Get
                Return CType(Me._DataSource, BaseRecord)
            End Get
            Set(ByVal value As BaseRecord)
                Me._DataSource = value
            End Set
        End Property

#Region "Helper Properties"


        Public ReadOnly Property Formula() As System.Web.UI.WebControls.Label
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "Formula"), System.Web.UI.WebControls.Label)
            End Get
        End Property

        Public ReadOnly Property ValueText() As System.Web.UI.WebControls.Label
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "ValueText"), System.Web.UI.WebControls.Label)
            End Get
        End Property

        Public ReadOnly Property SelectButton() As System.Web.UI.WebControls.LinkButton
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "SelectButton"), System.Web.UI.WebControls.LinkButton)
            End Get
        End Property

        Public ReadOnly Property ItemText() As System.Web.UI.WebControls.Label
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "ItemText"), System.Web.UI.WebControls.Label)
            End Get
        End Property
#End Region

#Region "Helper Functions"
        Public Shadows ReadOnly Property Page() As BaseApplicationPage
            Get
                Return DirectCast(MyBase.Page, BaseApplicationPage)
            End Get
        End Property

        Private Sub RegisterSelectValueScript(ByVal target As String, ByVal value As String, ByVal text As String)
            Dim scriptContent As String = String.Format( _
                "updateTarget({0}, {1}, {2});", _
                BaseClasses.Web.AspxTextWriter.CreateJScriptStringLiteral(target), _
                BaseClasses.Web.AspxTextWriter.CreateJScriptStringLiteral(value), _
                BaseClasses.Web.AspxTextWriter.CreateJScriptStringLiteral(text) _
                )
            Dim script As String = BaseClasses.Web.AspxTextWriter.CreateJScriptBlock(scriptContent)
            Me.Page.ClientScript.RegisterStartupScript(GetType(String), "SelectValueScript", script)
        End Sub

#End Region

    End Class

    ' Base class for the ItemsTable control on the LargeListSelector page.
    Public Class BaseItemsTable
        Inherits Persons.UI.BaseApplicationTableControl

        Private Const ASSEMBLY_NAME As String = "Persons.Business"

        Protected Overridable Sub Control_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Init

            ' Setup the pagination events.
            AddHandler Me.Pagination.FirstPage.Click, AddressOf Pagination_FirstPage_Click
            AddHandler Me.Pagination.LastPage.Click, AddressOf Pagination_LastPage_Click
            AddHandler Me.Pagination.NextPage.Click, AddressOf Pagination_NextPage_Click
            AddHandler Me.Pagination.PageSizeButton.Click, AddressOf Pagination_PageSizeButton_Click
            AddHandler Me.Pagination.PreviousPage.Click, AddressOf Pagination_PreviousPage_Click

            ' Setup - the button events.
            AddHandler Me.SearchButton.Button.Click, AddressOf SearchButton_Click

            ' Control Initializations.
            If Not Me.Page.IsPostBack Then
                ' Initialize the table's current sort order.
                Me.CurrentSortOrder = New OrderBy(True, False)

                ' Setup default pagination settings.
                Me.PageSize = 10
                Me.PageIndex = 0
            End If

        End Sub

        Protected Overridable Sub Control_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.RegisterAutoCloseScript()

            Try
                ' Load data only when displaying the page for the first time
                If (Not Me.Page.IsPostBack) Then

                    ' Must start a transaction before performing database operations
                    DbUtils.StartTransaction()

                    ' Load data for each record and table UI control.
                    ' Ordering is important because child controls get 
                    ' their parent ids from their parent UI controls.
                    Me.LoadData()
                    Me.DataBind()
                End If

            Catch ex As Exception
                ' An error has occured so display an error message.
                Utils.RegisterJScriptAlert(Me, "Load_Error_Message", ex.Message)
            Finally
                If Not Me.Page.IsPostBack Then
                    ' End database transaction
                    DbUtils.EndTransaction()
                End If
            End Try
        End Sub

        ' Read data from database. Returns an array of records that can be assigned
        ' to the DataSource table control property.
        Public Overridable Sub LoadData()

            ' Make sure all url parametes are passed.
            If ((Len(BaseClasses.Utils.NetUtils.GetUrlParam(Me, "Table", True)) < 1) OrElse _
                (Len(BaseClasses.Utils.NetUtils.GetUrlParam(Me, "Field", True)) < 1) OrElse _
                (Len(BaseClasses.Utils.NetUtils.GetUrlParam(Me, "DisplayField", True)) < 1) OrElse _
                (Len(BaseClasses.Utils.NetUtils.GetUrlParam(Me, "Target", True)) < 1) _
            ) Then
                Me.DataSource = DirectCast((New ArrayList()).ToArray(GetType(BaseRecord)), BaseRecord())
                Return
            End If
            ' Save all of the URL parameters in the session for use by Ajax type-ahead control
            HttpContext.Current.Session().Add("LLSAjaxTable", Me.Table())
            HttpContext.Current.Session().Add("LLSAjaxField", Me.Field())
            HttpContext.Current.Session().Add("LLSAjaxDisplayField", Me.DisplayField())
            HttpContext.Current.Session().Add("LLSAjaxFormula", Me.Formula())

            ' The WHERE clause will be empty when displaying all records in table.
            Dim whereClause As WhereClause = CreateWhereClause()
            Dim orderBy As OrderBy = CreateOrderBy()

            ' Set the pagesize.
            Me.SetPagintionPageSize()

            ' Get the total number of records to be displayed.
            Me.TotalRecords = CInt(Me.GetTable().GetRecordListCount(Nothing, whereClause.GetFilter(), Nothing, Nothing))

            ' Go to the last page.
            If Me.TotalPages <= 0 Then
                Me.PageIndex = 0
            ElseIf Me.DisplayLastPage OrElse Me.PageIndex >= Me.TotalPages Then
                Me.PageIndex = Me.TotalPages - 1
            End If

            ' Retrieve the records and set the table DataSource.
            ' Only PageSize records are fetched starting at PageIndex (zero based).
            Dim join As BaseClasses.Data.BaseFilter = Nothing
            Me.DataSource = DirectCast(Me.GetTable().GetRecordList(join, whereClause.GetFilter(), Nothing, orderBy, Me.PageIndex, Me.PageSize, Nothing).ToArray(GetType(BaseRecord)), BaseRecord())

        End Sub

        ' Populate the UI controls.
        Public Overrides Sub DataBind()

            MyBase.DataBind()

            ' Make sure that the DataSource is initialized.
            If Me.DataSource Is Nothing Then
                Return
            End If

            ' Setup the pagination controls.
            BindPaginationControls()

            Dim rep As System.Web.UI.WebControls.Repeater = CType(Me.FindControl("row1"), System.Web.UI.WebControls.Repeater)
            rep.DataSource = Me.DataSource()
            rep.DataBind()

            Dim index As Integer = 0
            Dim repItem As System.Web.UI.WebControls.RepeaterItem
            Dim listDuplicatesText = New ArrayList()
            Dim listDuplicatesRecControl = New ArrayList()
            Dim fvalue As String
            Dim cvalue As String

            For Each repItem In rep.Items
                ' Loop through all rows in the table, set its DataSource and call DataBind().
                Dim recControl As ItemsTableRecordControl = DirectCast(repItem.FindControl("ItemsTableRecordControl"), ItemsTableRecordControl)
                recControl.DataSource = Me.DataSource(index)
                recControl.DataBind()

                fvalue = recControl.ItemText.Text
                cvalue = recControl.ValueText.Text

                If (IsNothing(fvalue)) Then
                    fvalue = ""
                End If

                fvalue = fvalue.Trim()

                If (fvalue.Length > 50) Then
                    fvalue = fvalue.Substring(0, 50) + "..."
                End If

                Dim dupItemIdx As Integer = listDuplicatesText.IndexOf(fvalue)

                If (dupItemIdx >= 0) Then
                    Dim dupItem As ItemsTableRecordControl = CType(listDuplicatesRecControl(dupItemIdx), ItemsTableRecordControl)

                    dupItem.ItemText.Text = fvalue + " (ID " + dupItem.ValueText.Text.Substring(0, Math.Min(dupItem.ValueText.Text.Length, 38)) + ")"
                End If

                If (listDuplicatesText.Contains(fvalue)) Then
                    recControl.ItemText.Text = fvalue + " (ID " + cvalue.Substring(0, Math.Min(cvalue.Length, 38)) + ")"
                End If

                listDuplicatesText.Add(fvalue)
                listDuplicatesRecControl.Add(recControl)

                index += 1
            Next

        End Sub


        Protected Overridable Sub BindPaginationControls()

            ' Setup the pagination controls.

            ' Bind the buttons for CategoriesTableControl pagination.
            Me.Pagination.FirstPage.Enabled = Not (Me.PageIndex = 0)
            Me.Pagination.LastPage.Enabled = Not (Me.PageIndex = Me.TotalPages - 1)
            Me.Pagination.NextPage.Enabled = Not (Me.PageIndex = Me.TotalPages - 1)
            Me.Pagination.PreviousPage.Enabled = Not (Me.PageIndex = 0)

            ' Bind the pagination labels.
            Me.Pagination.CurrentPage.Text = (Me.PageIndex + 1).ToString()
            Me.Pagination.PageSize.Text = Me.PageSize.ToString()          
            Dim totalPagesTB As Label = DirectCast(MiscUtils.FindControlRecursively(Me.Pagination, "_TotalPages"), Label)
            If totalPagesTB IsNot Nothing Then
                totalPagesTB.Text = Me.TotalPages.ToString()
            End If
        End Sub

        Protected Overridable Sub SetPagintionPageSize()
            If Not Me.Pagination.PageSize Is Nothing AndAlso _
               Not Me.Pagination.PageSize.Text Is Nothing AndAlso _
               Me.Pagination.PageSize.Text.Trim <> "" Then
                Try
                    Me.PageSize = Integer.Parse(Me.Pagination.PageSize.Text)
                Catch ex As Exception
                End Try
            End If
        End Sub

        Protected Overridable Function CreateOrderBy() As OrderBy


            Dim displayCol As BaseClasses.Data.BaseColumn = Me.GetTable().TableDefinition.ColumnList.GetByAnyName(Me.DisplayField)


            If GetDFKAColumns().Count > 0 Then
                Dim dfkacolumns As List(Of BaseClasses.Data.BaseColumn) = GetDFKAColumns()
                For Each col As BaseClasses.Data.BaseColumn In dfkacolumns
                    If col.ColumnType.Equals(BaseColumn.ColumnTypes.String) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.Number) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.Email) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_State) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_Zip_Code) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_Phone_Number) Then
                        Me.CurrentSortOrder.Add(col, Asc)
                    End If
                Next
            Else
                Me.CurrentSortOrder.Add(displayCol, Asc)
            End If

            Return Me.CurrentSortOrder
        End Function

        Protected Overridable Function CreateWhereClause() As WhereClause
            Dim whereClause As WhereClause = New WhereClause()

            Dim displayCol As BaseClasses.Data.BaseColumn = Me.GetTable().TableDefinition.ColumnList.GetByAnyName(Me.DisplayField)

            If MiscUtils.IsValueSelected(Me.StartsWith) Then
                ' Strip "..." from begin and ending of the search text, otherwise the search will return 0 values as in database "..." is not stored.
                If Me.StartsWith.Text.StartsWith("...") Then
                    Me.StartsWith.Text = Me.StartsWith.Text.Substring(3, Me.StartsWith.Text.Length - 3)
                End If
                If Me.StartsWith.Text.EndsWith("...") Then
                    Me.StartsWith.Text = Me.StartsWith.Text.Substring(0, Me.StartsWith.Text.Length - 3)
                End If
                Me.StartsWith.Text = Me.StartsWith.Text.Trim()
                If GetDFKAColumns().Count > 0 Then
                    Dim wc As WhereClause = New WhereClause()
                    Dim dfkacolumns As List(Of BaseClasses.Data.BaseColumn) = GetDFKAColumns()
                    For Each col As BaseClasses.Data.BaseColumn In dfkacolumns
                        If col.ColumnType.Equals(BaseColumn.ColumnTypes.String) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.Number) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.Email) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_State) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_Zip_Code) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_Phone_Number) Then
                            wc.iOR(col, BaseFilter.ComparisonOperator.Starts_With, Me.StartsWith.Text, True, False)
                        End If
                    Next
                    whereClause.iAND(wc)
                Else
                    whereClause.iAND(displayCol, Starts_With, Me.StartsWith.Text, True, False)
                End If
            End If

                If MiscUtils.IsValueSelected(Me.Contains) Then
                    ' Strip "..." from begin and ending of the search text, otherwise the search will return 0 values as in database "..." is not stored.
                    If Me.Contains.Text.StartsWith("...") Then
                        Me.Contains.Text = Me.Contains.Text.Substring(3, Me.Contains.Text.Length - 3)
                    End If
                    If Me.StartsWith.Text.EndsWith("...") Then
                        Me.Contains.Text = Me.Contains.Text.Substring(0, Me.Contains.Text.Length - 3)
                    End If
                    Me.Contains.Text = Me.Contains.Text.Trim()
                If GetDFKAColumns().Count > 0 Then
                    Dim wc As WhereClause = New WhereClause()
                    Dim dfkacolumns As List(Of BaseClasses.Data.BaseColumn) = GetDFKAColumns()
                    For Each col As BaseClasses.Data.BaseColumn In dfkacolumns
                        If col.ColumnType.Equals(BaseColumn.ColumnTypes.String) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.Number) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.Email) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_State) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_Zip_Code) OrElse _
                           col.ColumnType.Equals(BaseColumn.ColumnTypes.USA_Phone_Number) Then
                            wc.iOR(col, BaseFilter.ComparisonOperator.Contains, Me.Contains.Text, True, False)
                        End If
                    Next
                    whereClause.iAND(wc)
                Else
                    whereClause.iAND(displayCol, ComparisonOperator.Contains, Me.Contains.Text, True, False)
                End If
            End If

            Return whereClause
        End Function


        ' This CreateWhereClause is used for loading list of suggestions for Auto Type-Ahead feature.
        Public Overridable Function CreateWhereClause(ByVal searchText As String, ByVal bStartsWith As Boolean, ByVal AutoTypeAheadWordSeparators As String) As WhereClause
            Dim wc As WhereClause = New WhereClause()
            ' Compose the WHERE clause consiting of:
            ' 1. Static clause defined at design time.
            ' 2. User selected filter criteria.
            ' 3. User selected search criteria.
            Dim appRelativeVirtualPath As String = CType(HttpContext.Current.Session("AppRelativeVirtualPath"), String)

            Dim displayCol As BaseClasses.Data.BaseColumn = Me.GetTable().TableDefinition.ColumnList.GetByAnyName(Me.DisplayField)

            ' Adds clauses if values are selected in Filter controls which are configured in the page.

            If IsValueSelected(searchText) Then
                Dim formatedSearchText As String = searchText
                ' strip "..." from begin and ending of the search text, otherwise the search will return 0 values as in database "..." is not stored.
                If searchText.StartsWith("...") Then
                    formatedSearchText = searchText.Substring(3, searchText.Length - 3)
                End If
                If searchText.EndsWith("...") Then
                    formatedSearchText = searchText.Substring(0, searchText.Length - 3)
                End If
                'After stripping "...", trim any leading and trailing whitespaces 
                formatedSearchText = formatedSearchText.Trim()

                ' These clauses are added depending on operator and fields selected in Control's property page, bindings tab.
                Dim search As WhereClause = New WhereClause()
                If Not displayCol Is Nothing Then
                    If bStartsWith Then
                        ' Search Text specified in Starts With textbox
                        search.iOR(displayCol, BaseFilter.ComparisonOperator.Starts_With, formatedSearchText, True, False)
                    Else
                        ' Search Text specified in Contains textbox
                        search.iOR(displayCol, BaseFilter.ComparisonOperator.Starts_With, formatedSearchText, True, False)
                        search.iOR(displayCol, BaseFilter.ComparisonOperator.Contains, AutoTypeAheadWordSeparators & formatedSearchText, True, False)
                    End If
                Else
                    Dim dfkacolumns As List(Of BaseClasses.Data.BaseColumn) = GetDFKAColumns()
                    For Each col As BaseClasses.Data.BaseColumn In dfkacolumns
                        If col.ColumnType.Equals(BaseColumn.ColumnTypes.String) Then
                            If (bStartsWith) Then
                                ' Search Text specified in Starts With textbox 
                                search.iOR(col, BaseFilter.ComparisonOperator.Starts_With, formatedSearchText, True, False)
                            End If
                        Else
                            ' Search Text specified in Contains textbox 
                            search.iOR(col, BaseFilter.ComparisonOperator.Starts_With, formatedSearchText, True, False)
                            search.iOR(col, BaseFilter.ComparisonOperator.Contains, AutoTypeAheadWordSeparators + formatedSearchText, True, False)
                        End If
                    Next
                End If
                wc.iAND(search)
            End If

            If Not displayCol Is Nothing Then
                ' The Ajax call may come from one of the fields (e.g., StartsWith).  But the user may have some text in the other field.  
                ' So we need to add the clause for the other field.

                If Not (bStartsWith) Then
                    ' This was the Contains textbox that was used in Ajax, so add the StartsWith clause.
                    Dim StartsWithSearchSelectedValue As String = CType(HttpContext.Current.Session()(HttpContext.Current.Session.SessionID & appRelativeVirtualPath & "StartsWithSearch_Ajax"), String)
                    If IsValueSelected(StartsWithSearchSelectedValue) Then
                        wc.iAND(displayCol, BaseFilter.ComparisonOperator.Starts_With, StartsWithSearchSelectedValue, False, False)
                    End If
                Else
                    ' This was the StartsWith textbox that was used in Ajax, so add the Contains clause.
                    Dim ContainsSelectedValue As String = CType(HttpContext.Current.Session()(HttpContext.Current.Session.SessionID & appRelativeVirtualPath & "ContainsSearch_Ajax"), String)
                    If IsValueSelected(ContainsSelectedValue) Then
                        wc.iAND(displayCol, BaseFilter.ComparisonOperator.Contains, ContainsSelectedValue, False, False)
                    End If
                End If
            Else

                Dim dfkacolumns As List(Of BaseClasses.Data.BaseColumn) = GetDFKAColumns()
                Dim wcAllColumns As WhereClause = New WhereClause()
                For Each col As BaseClasses.Data.BaseColumn In dfkacolumns
                    If Not (bStartsWith) Then
                        ' This was the Contains textbox that was used in Ajax, so add the StartsWith clause.
                        Dim StartsWithSearchSelectedValue As String = CType(HttpContext.Current.Session()(HttpContext.Current.Session.SessionID & appRelativeVirtualPath & "StartsWithSearch_Ajax"), String)
                        If IsValueSelected(StartsWithSearchSelectedValue) Then
                            wcAllColumns.iOR(col, BaseFilter.ComparisonOperator.Starts_With, StartsWithSearchSelectedValue, False, False)
                        End If
                    Else
                        ' This was the StartsWith textbox that was used in Ajax, so add the Contains clause.
                        Dim ContainsSelectedValue As String = CType(HttpContext.Current.Session()(HttpContext.Current.Session.SessionID & appRelativeVirtualPath & "ContainsSearch_Ajax"), String)
                        If IsValueSelected(ContainsSelectedValue) Then
                            wcAllColumns.iOR(col, BaseFilter.ComparisonOperator.Contains, ContainsSelectedValue, False, False)
                        End If
                    End If
                Next
            End If

            Return wc
        End Function
        Public Overridable Function GetDFKAColumns() As List(Of BaseClasses.Data.BaseColumn)

            Dim formula As String = ""
            Dim table As ItemsTable = CType(Me.Page.FindControlRecursively("ItemsTable"), ItemsTable)

            If Not String.IsNullOrEmpty(table.Formula) Then
                formula = table.Formula
            Else
                Dim dfka As String = Me.DisplayField
                dfka = dfka.Replace(Me.Table, "")
                dfka = dfka.Replace("=", "")
                dfka = dfka.Replace(" ", "")
                formula = dfka
            End If

            Dim dfkaColumns As List(Of BaseClasses.Data.BaseColumn) = New List(Of BaseClasses.Data.BaseColumn)()
            Dim columns() As BaseClasses.Data.BaseColumn = Me.GetTable().TableDefinition.ColumnList.ToColumnArray()
            For Each col As BaseColumn In columns
                If formula.ToLower().Contains(col.CodeName.ToLower()) Then
                    formula.Replace(col.CodeName, "")
                    dfkaColumns.Add(col)
                End If
            Next
            Return dfkaColumns
        End Function

        Public Overridable Function GetAutoCompletionList(ByVal startsWithText As String, ByVal containsText As String, ByVal count As Integer) As String()
            Dim resultList As ArrayList = New ArrayList
            Dim wordList As ArrayList = New ArrayList
            Dim iteration As Integer = 0
            Dim prefixText As String = ""
            Dim displayCol As BaseClasses.Data.BaseColumn = Me.GetTable().TableDefinition.ColumnList.GetByAnyName(Me.DisplayField)

            Dim wc As WhereClause

            If Not (IsNothing(startsWithText)) AndAlso startsWithText.Trim.Length() > 0 Then
                prefixText = startsWithText
                wc = CreateWhereClause(startsWithText, True, "[!a-zA-Z0-9]")
            Else
                prefixText = containsText
                wc = CreateWhereClause(containsText, False, "[!a-zA-Z0-9]")
            End If

            While (resultList.Count < count AndAlso iteration < 5)
                ' Fetch 100 records in each iteration
                ' Dim records() As BaseRecord = Me.GetTable().G.GetRecords(wc, Nothing, iteration, 100)
                Dim join As BaseClasses.Data.BaseFilter = Nothing
                Dim records() As BaseRecord = DirectCast(Me.GetTable().GetRecordList(join, wc.GetFilter(), Nothing, Nothing, iteration, 100).ToArray(GetType(BaseRecord)), BaseRecord())
                Dim rec As BaseRecord = Nothing
                Dim resultItem As String = ""
                For Each rec In records
                    ' Exit the loop if recordList count has reached AutoTypeAheadListSize.
                    If resultList.Count >= count Then
                        Exit For
                    End If
                    ' If the field is configured to Display as Foreign key, Format() method returns the 
                    ' Display as Forien Key value instead of original field value.
                    ' Since search had to be done in multiple fields (selected in Control's page property, binding tab) in a record,
                    ' We need to find relevent field to display which matches the prefixText and is not already present in the result list.

                    resultItem = rec.Format(displayCol)

                    If InvariantUCase(resultItem).Contains(InvariantUCase(prefixText)) Then
                        Dim isAdded As Boolean = FormatSuggestions(prefixText, resultItem, 50, "AtBeginningOfMatchedString", "WordsStartingWithSearchString", "[^a-zA-Z0-9]", resultList)
                        If isAdded Then
                            Continue For
                        End If
                    End If
                Next

                ' Exit the loop if number of records found is less as further iteration will not return any more records
                If records.Length < 100 Then
                    Exit While
                End If
                iteration += 1
            End While

            resultList.Sort()
            Dim result() As String = New String(resultList.Count - 1) {}
            Array.Copy(resultList.ToArray, result, resultList.Count)
            Return result
        End Function



        'Formats the resultItem and adds it to the list of suggestions.
        Public Overridable Function FormatSuggestions(ByVal prefixText As String, ByVal resultItem As String, _
                                                 ByVal columnLength As Integer, ByVal AutoTypeAheadDisplayFoundText As String, _
                                                 ByVal autoTypeAheadSearch As String, ByVal AutoTypeAheadWordSeparators As String, _
                                                 ByVal resultList As ArrayList) As Boolean
            Dim index As Integer = InvariantLCase(resultItem).IndexOf(InvariantLCase(prefixText))
            Dim itemToAdd As String = ""
            Dim isFound As Boolean = False
            Dim isAdded As Boolean = False
            ' Get the index where prfixt is at the beginning of resultItem. If not found then, index of word which begins with prefixText.
            If InvariantLCase(autoTypeAheadSearch).equals("wordsstartingwithsearchstring") And Not index = 0 Then
                ' Expression to find word which contains AutoTypeAheadWordSeparators followed by prefixText
                Dim regex1 As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex(AutoTypeAheadWordSeparators + prefixText, System.Text.RegularExpressions.RegexOptions.IgnoreCase)
                If regex1.IsMatch(resultItem) Then
                    index = regex1.Match(resultItem).Index
                    isFound = True
                End If
                ' If the prefixText is found immediatly after white space then starting of the word is found so don not search any further
                If Not resultItem(index).ToString() = " " Then
                    ' Expression to find beginning of the word which contains AutoTypeAheadWordSeparators followed by prefixText
                    Dim regex As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex("\\S*" + AutoTypeAheadWordSeparators + prefixText, System.Text.RegularExpressions.RegexOptions.IgnoreCase)
                    If regex.IsMatch(resultItem) Then
                        index = regex.Match(resultItem).Index
                        isFound = True
                    End If
                End If
            End If
            ' If autoTypeAheadSearch value is wordsstartingwithsearchstring then, extract the substring only if the prefixText is found at the 
            ' beginning of the resultItem (index = 0) or a word in resultItem is found starts with prefixText. 
            If index = 0 Or isFound Or InvariantLCase(autoTypeAheadSearch).Equals("anywhereinstring") Then
                If InvariantLCase(AutoTypeAheadDisplayFoundText).equals("atbeginningofmatchedstring") Then
                    ' Expression to find beginning of the word which contains prefixText
                    Dim regex1 As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex("\\S*" + prefixText, System.Text.RegularExpressions.RegexOptions.IgnoreCase)
                    '  Find the beginning of the word which contains prefexText
                    If (StringUtils.InvariantLCase(autoTypeAheadSearch).Equals("anywhereinstring") AndAlso regex1.IsMatch(resultItem)) Then
                        index = regex1.Match(resultItem).Index
                        isFound = True
                    End If
                    ' Display string from the index till end of the string if sub string from index till end is less than columnLength value.
                    If Len(resultItem) - index <= columnLength Then
                        If index = 0 Then
                            itemToAdd = resultItem
                        Else
                            itemToAdd = "..." & resultItem.Substring(index, Len(resultItem) - index)
                        End If
                    Else
                        If index = 0 Then
                            itemToAdd = resultItem.Substring(index, (columnLength - 3)) & "..."
                        Else
                            'Truncate the string to show only columnLength - 6 characters as begining and trailing "..." has to be appended.
                            itemToAdd = "..." & resultItem.Substring(index, columnLength - 6) & "..."
                        End If
                    End If
                ElseIf InvariantLCase(AutoTypeAheadDisplayFoundText).equals("inmiddleofmatchedstring") Then
                    Dim subStringBeginIndex As Integer = CType(columnLength / 2, Integer)
                    If Len(resultItem) <= columnLength Then
                        itemToAdd = resultItem
                    Else
                        ' Sanity check at end of the string
                        If index + Len(prefixText) = columnLength Then
                            itemToAdd = "..." & resultItem.Substring(index - columnLength, index)
                        ElseIf Len(resultITem) - index < subStringBeginIndex Then
                            ' Display string from the end till columnLength value if, index is closer to the end of the string.
                            itemToAdd = "..." & resultItem.Substring(Len(resultItem) - columnLength, Len(resultItem))
                        ElseIf index <= subStringBeginIndex Then
                            ' Sanity chet at beginning of the string
                            itemToAdd = resultItem.Substring(0, columnLength) & "..."
                        Else
                            ' Display string containing text before the prefixText occures and text after the prefixText
                            itemToAdd = "..." & resultItem.Substring(index - subStringBeginIndex, columnLength) & "..."
                        End If
                    End If
                ElseIf InvariantLCase(AutoTypeAheadDisplayFoundText).equals("atendofmatchedstring") Then
                    ' Expression to find ending of the word which contains prefexText
                    Dim regex1 As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex("\s", System.Text.RegularExpressions.RegexOptions.IgnoreCase)
                    ' Find the ending of the word which contains prefexText
                    If regex1.IsMatch(resultItem, index + 1) Then
                        index = regex1.Match(resultItem, index + 1).Index
                    Else
                        ' If the word which contains prefexText is the last word in string, regex1.IsMatch returns false.
                        index = resultItem.Length
                    End If
                    If index > Len(resultItem) Then
                        index = Len(resultItem)
                    End If
                    ' If text from beginning of the string till index is less than columnLength value then, display string from the beginning till index.
                    If index <= columnLength Then
                        If index = Len(resultItem) Then   'Make decision to append "..."
                            itemToAdd = resultItem.Substring(0, index)
                        Else
                            itemToAdd = resultItem.Substring(0, index) & "..."
                        End If
                    Else
                        If index = Len(resultItem) Then
                            itemToAdd = "..." & resultItem.Substring(index - (columnLength - 3), (columnLength - 3))
                        Else
                            'Truncate the string to show only columnLength - 6 characters as begining and trailing "..." has to be appended.
                            itemToAdd = "..." & resultItem.Substring(index - (columnLength - 6), columnLength - 6) & "..."
                        End If
                    End If
                End If
                If Not itemToAdd Is Nothing AndAlso Not resultList.Contains(itemToAdd) Then
                    resultList.Add(itemToAdd)
                    isAdded = True
                End If
            End If
            Return isAdded
        End Function



        Private Sub Control_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
            If Me.DataChanged Then
                Try
                    ' Must start a transaction before performing database operations
                    DbUtils.StartTransaction()

                    ' Load data for each record and table UI control.
                    ' Ordering is important because child controls get 
                    ' their parent ids from their parent UI controls.
                    Me.LoadData()
                    Me.DataBind()

                Catch ex As Exception
                    ' An error has occured so display an error message.
                    Utils.RegisterJScriptAlert(Me, "Load_Error_Message", ex.Message)
                Finally
                    ' End database transaction
                    DbUtils.EndTransaction()
                End Try
            End If
        End Sub

        Protected Overrides Sub LoadViewState(ByVal savedState As Object)
            MyBase.LoadViewState(savedState)

            Dim orderByStr As String = CType(ViewState("ItemsTable_OrderBy"), String)
            If Not orderByStr Is Nothing OrElse orderByStr.Trim <> "" Then
                Me.CurrentSortOrder = BaseClasses.Data.OrderBy.FromXmlString(orderByStr)
            Else
                Me.CurrentSortOrder = New OrderBy(True, False)
            End If

            Dim pageIndex As String = CType(ViewState("Page_Index"), String)
            If Not pageIndex Is Nothing Then
                Me.PageIndex = CInt(pageIndex)
            End If

            Dim pageSize As String = CType(ViewState("Page_Size"), String)
            If Not pageSize Is Nothing Then
                Me.PageSize = CInt(pageSize)
            End If
        End Sub

        Protected Overrides Function SaveViewState() As Object

            Me.ViewState("ItemsTable_OrderBy") = Me.CurrentSortOrder.ToXmlString()

            Me.ViewState("Page_Index") = Me.PageIndex
            Me.ViewState("Page_Size") = Me.PageSize

            Return MyBase.SaveViewState()

        End Function

        ' Generate the event handling functions for pagination events.
        Public Overridable Sub Pagination_FirstPage_Click(ByVal sender As Object, ByVal args As ImageClickEventArgs)
            Try
                Me.PageIndex = 0
                Me.DataChanged = True
            Catch ex As Exception
                Utils.MiscUtils.RegisterJScriptAlert(Me, "BUTTON_CLICK_MESSAGE", ex.Message)
            Finally
            End Try
        End Sub

        ' event handler for ImageButton
        Public Overridable Sub Pagination_LastPage_Click(ByVal sender As Object, ByVal args As ImageClickEventArgs)
            Try
                Me.DisplayLastPage = True
                Me.DataChanged = True
            Catch ex As Exception
                Utils.MiscUtils.RegisterJScriptAlert(Me, "BUTTON_CLICK_MESSAGE", ex.Message)
            Finally
            End Try
        End Sub

        ' event handler for ImageButton
        Public Overridable Sub Pagination_NextPage_Click(ByVal sender As Object, ByVal args As ImageClickEventArgs)
            Try
                Me.PageIndex += 1
                Me.DataChanged = True
            Catch ex As Exception
                Utils.MiscUtils.RegisterJScriptAlert(Me, "BUTTON_CLICK_MESSAGE", ex.Message)
            Finally
            End Try
        End Sub

        ' event handler for Button w/ Layout
        Public Overridable Sub Pagination_PageSizeButton_Click(ByVal sender As Object, ByVal args As EventArgs)
            Try
                Me.DataChanged = True
                Me.PageSize = Integer.Parse(Me.Pagination.PageSize.Text)
                Me.PageIndex = Integer.Parse(Me.Pagination.CurrentPage.Text) - 1
            Catch ex As Exception
                Utils.MiscUtils.RegisterJScriptAlert(Me, "BUTTON_CLICK_MESSAGE", ex.Message)
            Finally
            End Try
        End Sub

        ' event handler for ImageButton
        Public Overridable Sub Pagination_PreviousPage_Click(ByVal sender As Object, ByVal args As ImageClickEventArgs)
            Try
                If Me.PageIndex > 0 Then
                    Me.PageIndex -= 1
                    Me.DataChanged = True
                End If
            Catch ex As Exception
                Utils.MiscUtils.RegisterJScriptAlert(Me, "BUTTON_CLICK_MESSAGE", ex.Message)
            Finally
            End Try
        End Sub

        ' Generate the event handling functions for button events.
        Public Overridable Sub SearchButton_Click(ByVal sender As Object, ByVal args As EventArgs)
            Try
                Me.DataChanged = True
            Catch ex As Exception
                Utils.MiscUtils.RegisterJScriptAlert(Me, "BUTTON_CLICK_MESSAGE", ex.Message)
            Finally
            End Try
        End Sub

        Private _PageSize As Integer
        Public Property PageSize() As Integer
            Get
                Return Me._PageSize
            End Get
            Set(ByVal value As Integer)
                Me._PageSize = value
            End Set
        End Property

        Private _PageIndex As Integer
        Public Property PageIndex() As Integer
            Get
                ' Return the PageIndex
                Return Me._PageIndex
            End Get
            Set(ByVal value As Integer)
                Me._PageIndex = value
            End Set
        End Property

        Private _TotalRecords As Integer
        Public Property TotalRecords() As Integer
            Get
                Return Me._TotalRecords
            End Get
            Set(ByVal value As Integer)
                If Me.PageSize > 0 Then
                    Dim num As Double = Me.PageSize
                    Me.TotalPages = CInt(Math.Ceiling(value / num))
                End If

                Me._TotalRecords = value
            End Set
        End Property

        Private _TotalPages As Integer
        Public Property TotalPages() As Integer
            Get
                Return Me._TotalPages
            End Get
            Set(ByVal value As Integer)
                Me._TotalPages = value
            End Set
        End Property

        Private _DisplayLastPage As Boolean
        Public Property DisplayLastPage() As Boolean
            Get
                Return Me._DisplayLastPage
            End Get
            Set(ByVal value As Boolean)
                Me._DisplayLastPage = value
            End Set
        End Property

        Private _DataChanged As Boolean = False
        Public Property DataChanged() As Boolean
            Get
                Return Me._DataChanged
            End Get
            Set(ByVal value As Boolean)
                Me._DataChanged = value
            End Set
        End Property

        Private _CurrentSortOrder As OrderBy = Nothing
        Public Property CurrentSortOrder() As OrderBy
            Get
                Return Me._CurrentSortOrder
            End Get
            Set(ByVal value As BaseClasses.Data.OrderBy)
                Me._CurrentSortOrder = value
            End Set
        End Property

        Private _DataSource() As BaseRecord = Nothing
        Public Property DataSource() As BaseRecord()
            Get
                Return Me._DataSource
            End Get
            Set(ByVal value() As BaseRecord)
                Me._DataSource = value
            End Set
        End Property

        Public ReadOnly Property Table() As String
            Get
                Dim errMsg As String = ""
                Dim TYPE_FORMAT As String = "{0}.{1}{2},{3}"
                Dim tableName As String = ""
                Try
                    ' Try getting from the URL.  If not, get it from the session.
                    tableName = BaseClasses.Utils.NetUtils.GetUrlParam(Me, "Table", True)
                    tableName = HttpUtility.UrlDecode(tableName)
                Catch ex As Exception
                    ' Get from the session.  This table name already contains the prefix required, so we return directly.
                    tableName = CStr(HttpContext.Current.Session()("LLSAjaxTable"))
                    Return tableName
                End Try

                tableName = CType(Me.Page, BaseApplicationPage).Decrypt(tableName)

                tableName = tableName.Replace(" ", "_")
                tableName = tableName.Replace(".", "_")


                ' Check if it is a table.
                Try

                    Dim tableType As String = String.Format(TYPE_FORMAT, "Persons.Business", tableName, "Table", "App_Code")
                    Type.GetType(tableType, True, True)
                    Return tableType
                Catch ex As Exception
                End Try

                ' Check if it is a view.
                Try

                    Dim viewType As String = String.Format(TYPE_FORMAT, "Persons.Business", tableName, "View", "App_Code")
                    Type.GetType(viewType, True, True)
                    Return viewType
                Catch ex As Exception
                End Try

                ' Check if it is a query.
                Try

                    Dim queryType As String = String.Format(TYPE_FORMAT, "Persons.Business", tableName, "Query", "App_Code")
                    Type.GetType(queryType, True, True)
                    Return queryType
                Catch ex As Exception
                End Try

                Try

                    Dim tableType As String = String.Format(TYPE_FORMAT, "Persons.Business", "Table" & tableName, "Table", "App_Code")
                    Type.GetType(tableType, True, True)
                    Return tableType
                Catch ex As Exception
                End Try

                ' Check if it is a view.
                Try

                    Dim viewType As String = String.Format(TYPE_FORMAT, "Persons.Business", "Table" & tableName, "View", "App_Code")
                    Type.GetType(viewType, True, True)
                    Return viewType
                Catch ex As Exception
                End Try

                ' Check if it is a query.
                Try

                    Dim queryType As String = String.Format(TYPE_FORMAT, "Persons.Business", "Table" & tableName, "Query", "App_Code")
                    Type.GetType(queryType, True, True)
                    Return queryType
                Catch ex As Exception
                End Try

                Throw New Exception("Fail to locate business layer for " & tableName)
                Return ""
            End Get
        End Property

        Public ReadOnly Property Field() As String
            Get
                Dim fld As String = ""
                Try
                    ' Try getting from the URL.  If not, get it from the session.
                    fld = BaseClasses.Utils.NetUtils.GetUrlParam(Me, "Field", True)
					fld = HttpUtility.UrlDecode(fld)
                Catch ex As Exception
                    ' Get from the session
                    fld = CStr(HttpContext.Current.Session()("LLSAjaxField"))
                End Try

	            fld = CType(Me.Page, BaseApplicationPage).Decrypt(fld)

                Return fld
            End Get
        End Property

        Public ReadOnly Property DisplayField() As String
            Get
                Dim fld As String = ""
                Try
                    Try
                        ' Try getting from the URL.  If not, get it from the session.
                        fld = BaseClasses.Utils.NetUtils.GetUrlParam(Me, "DisplayField", True)
	                    fld = HttpUtility.UrlDecode(fld)
                    Catch ex As Exception
                        ' Get from the session
                        fld = CStr(HttpContext.Current.Session()("LLSAjaxDisplayField"))
                    End Try

                    fld = CType(Me.Page, BaseApplicationPage).Decrypt(fld)
                Catch
                End Try
                Return fld
            End Get
        End Property

        Public ReadOnly Property Formula() As String
            Get
                Dim fld As String = ""
                Try
                    Try
                        ' Try getting from the URL.  If not, get it from the session.
                        fld = BaseClasses.Utils.NetUtils.GetUrlParam(Me, "Formula", False, False, False)
						fld = HttpUtility.UrlDecode(fld)
                    Catch ex As Exception
                        ' Get from the session
                        fld = CStr(HttpContext.Current.Session()("LLSFormulaField"))
                    End Try

                    fld = CType(Me.Page, BaseApplicationPage).Decrypt(fld)

                Catch

                End Try

                Return fld
            End Get
        End Property

        Public ReadOnly Property Target() As String
            Get
                Return BaseClasses.Utils.NetUtils.GetUrlParam(Me, "Target", True)
            End Get
        End Property

#Region "Helper Properties"
        Public ReadOnly Property StartsWith() As System.Web.UI.WebControls.TextBox
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "StartsWith"), System.Web.UI.WebControls.TextBox)
            End Get
        End Property

        Public ReadOnly Property Contains() As System.Web.UI.WebControls.TextBox
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "Contains"), System.Web.UI.WebControls.TextBox)
            End Get
        End Property

        Public ReadOnly Property SearchButton() As Persons.UI.IThemeButton
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "SearchButton"), Persons.UI.IThemeButton)
            End Get
        End Property

        Public ReadOnly Property Pagination() As Persons.UI.IPaginationMedium
            Get
                Return CType(BaseClasses.Utils.MiscUtils.FindControlRecursively(Me, "Pagination"), Persons.UI.IPaginationMedium)
            End Get
        End Property
#End Region

#Region "Helper Functions"

        ' What do we generate when there is no selection box for the record?
        Public Overloads Overrides Function ModifyRedirectUrl(ByVal url As String, ByVal arg As String, ByVal bEncrypt As Boolean) As String
            Return ModifyRedirectUrl(url, arg, Nothing, False)
        End Function

        Public Function GetRecordControls() As ItemsTableRecordControl()

            Dim recList As ArrayList = New ArrayList()

            Dim rep As System.Web.UI.WebControls.Repeater = CType(Me.FindControl("row1"), System.Web.UI.WebControls.Repeater)
            Dim repItem As System.Web.UI.WebControls.RepeaterItem
            For Each repItem In rep.Items
                Dim recControl As ItemsTableRecordControl = DirectCast(repItem.FindControl("ItemsTableRecordControl"), ItemsTableRecordControl)
                recList.Add(recControl)
            Next

            Return DirectCast(recList.ToArray(GetType(ItemsTableRecordControl)), ItemsTableRecordControl())
        End Function

        Public Shadows ReadOnly Property Page() As BaseApplicationPage
            Get
                Return DirectCast(MyBase.Page, BaseApplicationPage)
            End Get
        End Property

        Private Sub RegisterAutoCloseScript()
            'If (Me.IsPostBack) Then
            '    Return
            'End If
            If (BaseClasses.Utils.StringUtils.InvariantUCase(Me.Page.Request.Browser.Browser).IndexOf("IE") < 0) Then
                Return
            End If
            If (Me.Page.Request.Browser.MajorVersion < 5) Then
                Return
            End If

            'attach a function to the parent window's onunload event
            'that will close the current window
            Dim script As String = BaseClasses.Web.AspxTextWriter.CreateJScriptBlock( _
                "function onParentUnload() { window.close(); }" & vbCrLf & _
                "if (window.opener && !window.opener.closed) { window.opener.attachEvent('onunload', onParentUnload);}")
            Me.Page.ClientScript.RegisterClientScriptBlock(GetType(String), "AutoCloseScript", script)
        End Sub

        Public Function GetTable() As BaseClasses.Data.BaseTable
            Dim tn As String = Me.Table
            Try
                Return BaseClasses.Data.BaseTable.CreateInstance(tn)
            Catch e As System.Exception
                tn = String.Format("{0}.{1}Access,{2}", "Persons", Replace(tn, " ", "_"), "Persons")
                Return BaseClasses.Data.BaseTable.CreateInstance(tn)
            End Try
        End Function
#End Region

    End Class

#End Region

End Namespace