Imports System
Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.Text

Imports DevExpress.ExpressApp
Imports DevExpress.ExpressApp.Actions
Imports DevExpress.Persistent.Base
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraEditors.Controls
Imports DevExpress.XtraEditors.Repository
Imports DevExpress.XtraGrid.Views.Base
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Views.Grid.ViewInfo
Imports DevExpress.ExpressApp.Win.Editors
Imports DevExpress.ExpressApp.Model
Imports DevExpress.Utils.Drawing
Imports System.Drawing


Public Class MasterDetailVC
    Inherits ViewController(Of ListView)
    Private edit As RepositoryItemCheckEdit
    Protected selection As ArrayList
    Private column As GridColumn
    Private Const CheckboxIndent As Integer = 4
    Private _view As GridView
    Public Sub New()
        MyBase.New()
        'This call is required by the Component Designer.
        selection = New ArrayList()

        InitializeComponent()
        RegisterActions(components)
    End Sub
    Protected Overrides Sub OnViewControlsCreated()
        MyBase.OnViewControlsCreated()
        Dim gridListEditor As GridListEditor = TryCast(View.Editor, GridListEditor)
        If gridListEditor IsNot Nothing Then
            Dim grid As GridControl = gridListEditor.Grid
            _view = gridListEditor.GridView
            _view.OptionsPrint.PrintDetails = True
            _view.OptionsDetail.ShowDetailTabs = True
            _view.OptionsView.ShowDetailButtons = True
            _view.OptionsDetail.EnableMasterViewMode = True
            'iew.OptionsSelection.

            If View.Id = "RegistryTasks_ListView_Not_Completed" Then
                ' InitCheckBoxColumn(_view) 'Úgy tűnik, mégsincs szükség erre.
            End If
            If View.Id = "AssetsHandling_ListView_Active" Then
                InitCheckBoxColumn(_view)
            End If
            AddHandler _view.MasterRowExpanded, AddressOf view_MasterRowExpanded


        End If

    End Sub
    Protected Overrides Sub OnDeactivated()
        MyBase.OnDeactivated()
        If View.Id = "InitCheckBoxColumn(_view)" Then
            DetachCheckBoxColumn(_view)
        End If
    End Sub
    Private Sub DetachCheckBoxColumn(ByVal _view As GridView)
        If _view Is Nothing Then
            Return
        End If
        If column IsNot Nothing Then
            column.Dispose()
        End If
        If edit IsNot Nothing Then
            _view.GridControl.RepositoryItems.Remove(edit)
            edit.Dispose()
        End If

        RemoveHandler _view.Click, AddressOf View_Click
        RemoveHandler _view.CustomDrawColumnHeader, AddressOf View_CustomDrawColumnHeader
        RemoveHandler _view.CustomDrawGroupRow, AddressOf View_CustomDrawGroupRow
        RemoveHandler _view.CustomUnboundColumnData, AddressOf view_CustomUnboundColumnData
        RemoveHandler _view.KeyDown, AddressOf view_KeyDown
        RemoveHandler _view.RowStyle, AddressOf view_RowStyle

        _view = Nothing

    End Sub
    Private Sub InitCheckBoxColumn(ByVal view As GridView)
        If view Is Nothing Then
            Return
        End If
        selection.Clear()
        view.BeginUpdate()
        Try
            edit = TryCast(view.GridControl.RepositoryItems.Add("CheckEdit"), RepositoryItemCheckEdit)

            column = view.Columns.Add()
            column.OptionsColumn.AllowSort = DevExpress.Utils.DefaultBoolean.False
            column.Visible = True
            column.VisibleIndex = 0
            column.FieldName = "CheckMarkSelection"
            column.Caption = "Mark"
            column.OptionsColumn.ShowCaption = False
            column.OptionsColumn.AllowEdit = False
            column.OptionsColumn.AllowSize = False
            column.UnboundType = DevExpress.Data.UnboundColumnType.Boolean
            column.Width = GetCheckBoxWidth()
            column.ColumnEdit = edit

            AddHandler view.Click, AddressOf View_Click
            AddHandler view.CustomDrawColumnHeader, AddressOf View_CustomDrawColumnHeader
            AddHandler view.CustomDrawGroupRow, AddressOf View_CustomDrawGroupRow
            AddHandler view.CustomUnboundColumnData, AddressOf view_CustomUnboundColumnData
            AddHandler view.KeyDown, AddressOf view_KeyDown
            AddHandler view.RowStyle, AddressOf view_RowStyle
        Finally
            view.EndUpdate()
        End Try


    End Sub
    Protected Function GetCheckBoxWidth() As Integer
        Dim info As DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo = TryCast(edit.CreateViewInfo(), DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo)
        Dim width As Integer = 0
        GraphicsInfo.Default.AddGraphics(Nothing)
        Try
            width = info.CalcBestFit(GraphicsInfo.Default.Graphics).Width
        Finally
            GraphicsInfo.Default.ReleaseGraphics()
        End Try
        Return width + CheckboxIndent * 2
    End Function
    Protected Sub DrawCheckBox(ByVal g As Graphics, ByVal r As Rectangle, ByVal Checked As Boolean)
        Dim info As DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo
        Dim painter As DevExpress.XtraEditors.Drawing.CheckEditPainter
        Dim args As DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs
        info = TryCast(edit.CreateViewInfo(), DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo)
        painter = TryCast(edit.CreatePainter(), DevExpress.XtraEditors.Drawing.CheckEditPainter)
        info.EditValue = Checked
        info.Bounds = r
        info.CalcViewInfo(g)
        args = New DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs(info, New DevExpress.Utils.Drawing.GraphicsCache(g), r)
        painter.Draw(args)
        args.Cache.Dispose()
    End Sub
    Private Sub Invalidate()
        _view.BeginUpdate()
        _view.EndUpdate()
    End Sub
    Private Sub SelectRow(ByVal rowHandle As Integer, ByVal [select] As Boolean, ByVal invalidate As Boolean)
        If IsRowSelected(rowHandle) = [select] Then
            Return
        End If
        Dim row As Object = _view.GetRow(rowHandle)
        If [select] Then
            selection.Add(row)
        Else
            selection.Remove(row)
        End If
        If invalidate Then
            Me.Invalidate()
        End If
    End Sub
    Private Sub view_CustomUnboundColumnData(ByVal sender As Object, ByVal e As CustomColumnDataEventArgs)
        If e.Column Is CheckMarkColumn Then
            If e.IsGetData Then
                e.Value = IsRowSelected(e.ListSourceRowIndex)
            Else
                SelectRow(e.ListSourceRowIndex, CBool(e.Value))
            End If
        End If
    End Sub
    Private Sub view_KeyDown(ByVal sender As Object, ByVal e As Windows.Forms.KeyEventArgs)
        If _view.FocusedColumn IsNot column OrElse e.KeyCode <> Windows.Forms.Keys.Space Then
            Return
        End If
        InvertRowSelection(_view.FocusedRowHandle)
    End Sub
    Private Sub View_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim info As GridHitInfo
        Dim pt As Point = _view.GridControl.PointToClient(Windows.Forms.Control.MousePosition)
        info = _view.CalcHitInfo(pt)
        If info.Column Is column Then
            If info.InColumn Then
                If SelectedCount = _view.DataRowCount Then
                    ClearSelection()
                Else
                    SelectAll()
                End If
            End If
            If info.InRowCell Then
                InvertRowSelection(info.RowHandle)
            End If
        End If
        If info.InRow AndAlso _view.IsGroupRow(info.RowHandle) AndAlso info.HitTest <> GridHitTest.RowGroupButton Then
            InvertRowSelection(info.RowHandle)
        End If
    End Sub
    Private Sub View_CustomDrawColumnHeader(ByVal sender As Object, ByVal e As ColumnHeaderCustomDrawEventArgs)
        If e.Column Is column Then
            e.Info.InnerElements.Clear()
            e.Painter.DrawObject(e.Info)
            DrawCheckBox(e.Graphics, e.Bounds, SelectedCount = _view.DataRowCount)
            e.Handled = True
        End If
    End Sub
    Private Sub View_CustomDrawGroupRow(ByVal sender As Object, ByVal e As RowObjectCustomDrawEventArgs)
        Dim info As DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo
        info = TryCast(e.Info, DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo)

        info.GroupText = "         " & info.GroupText.TrimStart()
        e.Info.Paint.FillRectangle(e.Graphics, e.Appearance.GetBackBrush(e.Cache), e.Bounds)
        e.Painter.DrawObject(e.Info)

        Dim r As Rectangle = info.ButtonBounds
        r.Offset(r.Width + CheckboxIndent * 2 - 1, 0)
        DrawCheckBox(e.Graphics, r, IsGroupRowSelected(e.RowHandle))
        e.Handled = True
    End Sub
    Private Sub view_RowStyle(ByVal sender As Object, ByVal e As RowStyleEventArgs)
        If IsRowSelected(e.RowHandle) Then
            e.Appearance.BackColor = SystemColors.Highlight
            e.Appearance.ForeColor = SystemColors.HighlightText
        End If
    End Sub
    Public ReadOnly Property CheckMarkColumn() As GridColumn
        Get
            Return column
        End Get
    End Property
    Public ReadOnly Property SelectedCount() As Integer
        Get
            Return selection.Count
        End Get
    End Property
    Public Function GetSelectedRow(ByVal index As Integer) As Object
        Return selection(index)
    End Function
    Public Function GetSelectedIndex(ByVal row As Object) As Integer
        Return selection.IndexOf(row)
    End Function
    Public Sub ClearSelection()
        selection.Clear()
        Invalidate()
    End Sub
    Public Sub SelectAll()
        selection.Clear()
        ' fast (won't work if the grid is filtered)
        'if(_view.DataSource is ICollection)
        '	selection.AddRange(((ICollection)_view.DataSource));
        'else
        ' slow:
        For i As Integer = 0 To _view.DataRowCount - 1
            selection.Add(_view.GetRow(i))
        Next i
        Invalidate()
    End Sub
    Public Sub SelectGroup(ByVal rowHandle As Integer, ByVal [select] As Boolean)
        If IsGroupRowSelected(rowHandle) AndAlso [select] Then
            Return
        End If
        For i As Integer = 0 To _view.GetChildRowCount(rowHandle) - 1
            Dim childRowHandle As Integer = _view.GetChildRowHandle(rowHandle, i)
            If _view.IsGroupRow(childRowHandle) Then
                SelectGroup(childRowHandle, [select])
            Else
                SelectRow(childRowHandle, [select], False)
            End If
        Next i
        Invalidate()
    End Sub
    Public Sub SelectRow(ByVal rowHandle As Integer, ByVal [select] As Boolean)
        SelectRow(rowHandle, [select], True)
    End Sub
    Public Sub InvertRowSelection(ByVal rowHandle As Integer)
        If _view.IsDataRow(rowHandle) Then
            SelectRow(rowHandle, (Not IsRowSelected(rowHandle)))
        End If
        If _view.IsGroupRow(rowHandle) Then
            SelectGroup(rowHandle, (Not IsGroupRowSelected(rowHandle)))
        End If
    End Sub
    Public Function IsGroupRowSelected(ByVal rowHandle As Integer) As Boolean
        For i As Integer = 0 To _view.GetChildRowCount(rowHandle) - 1
            Dim row As Integer = _view.GetChildRowHandle(rowHandle, i)
            If _view.IsGroupRow(row) Then
                If (Not IsGroupRowSelected(row)) Then
                    Return False
                End If
            Else
                If (Not IsRowSelected(row)) Then
                    Return False
                End If
            End If
        Next i
        Return True
    End Function
    Public Function IsRowSelected(ByVal rowHandle As Integer) As Boolean
        If _view.IsGroupRow(rowHandle) Then
            Return IsGroupRowSelected(rowHandle)
        End If

        Dim row As Object = _view.GetRow(rowHandle)
        Return GetSelectedIndex(row) <> -1
    End Function
    Private Sub view_MasterRowExpanded(ByVal sender As Object, ByVal e As CustomMasterRowEventArgs)
        Dim masterView As GridView = TryCast(sender, GridView)
        Dim detailView As GridView = TryCast(masterView.GetDetailView(e.RowHandle, e.RelationIndex), GridView)
        Dim i As Integer
        Dim _Exists As Boolean = False
        Try
            detailView.BeginUpdate()
            detailView.OptionsDetail.EnableMasterViewMode = False
            detailView.OptionsBehavior.Editable = False
            Dim tlist As ITypedList = detailView.DataSource

            For Each col As GridColumn In detailView.Columns
                If col.FieldName.Contains("!") Then
                    col.Visible = True
                    col.OptionsColumn.ShowInCustomizationForm = True
                    'Dim pd As PropertyDescriptor = tlist.GetItemProperties(Nothing)(Replace(col.FieldName, "!", ""))
                    'If pd IsNot Nothing Then
                    '    Dim modelClass As IModelClass = Application.Model.BOModel.GetClass(pd.ComponentType)

                    '    If modelClass Is Nothing Then Exit Sub
                    '    Dim modelMember As IModelMember = modelClass.FindMember(col.FieldName)
                    '    If modelMember Is Nothing Then Exit Sub
                    '    col.Caption = modelMember.Caption
                    'End If
                ElseIf Not tlist Is Nothing Then
                    Dim pd As PropertyDescriptor = tlist.GetItemProperties(Nothing)(col.FieldName)
                    If pd Is Nothing Then Exit Sub
                    Dim modelClass As IModelClass = Application.Model.BOModel.GetClass(pd.ComponentType)

                    If modelClass Is Nothing Then Exit Sub
                    Dim modelMember As IModelMember = modelClass.FindMember(col.FieldName)
                    If modelMember Is Nothing Then Exit Sub
                    col.Caption = modelMember.Caption
                    _Exists = False
                    For i = 0 To modelClass.DefaultListView.Columns.Count - 1
                        If col.FieldName = modelClass.DefaultListView.Columns.Item(i).PropertyName Then

                            _Exists = True

                        End If
                    Next
                    col.Visible = _Exists
                End If
            Next col
            detailView.EndUpdate()
        Catch

        End Try
    End Sub
    Private Sub view_MasterRowExpanded_PCI(ByVal sender As Object, ByVal e As CustomMasterRowEventArgs)
        Dim masterView As GridView = TryCast(sender, GridView)
        Dim detailView As GridView = TryCast(masterView.GetDetailView(e.RowHandle, e.RelationIndex), GridView)
    End Sub
End Class