Imports System.Data.Objects.DataClasses
Imports System.Data.Objects
Imports DevExpress.Xpf.Grid
Imports System.Data.Entity
Imports System.Data.Entity.Infrastructure
Imports System.Data
Imports System.IO

Public Module modExtensiones
    <System.Runtime.CompilerServices.Extension()>
    Public Function ObtieneHijoDeTipo(Of T As DependencyObject)(depObj As DependencyObject) As T
        If depObj Is Nothing Then
            Return Nothing
        End If

        For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(depObj) - 1
            Dim child = VisualTreeHelper.GetChild(depObj, i)

            Dim result = If(TryCast(child, T), ObtieneHijoDeTipo(Of T)(child))
            If result IsNot Nothing Then
                Return result
            End If
        Next
        Return Nothing
    End Function

    <System.Runtime.CompilerServices.Extension()>
    Public Sub ObtieneHijosDeTipo(Of T As DependencyObject)(depObj As DependencyObject, ByRef lista As List(Of T))
        If depObj IsNot Nothing Then
            If lista Is Nothing Then lista = New List(Of T)
            For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(depObj) - 1
                Dim child = VisualTreeHelper.GetChild(depObj, i)
                Dim hijo = TryCast(child, T)
                If hijo IsNot Nothing Then
                    lista.Add(hijo)
                Else
                    ObtieneHijosDeTipo(Of T)(child, lista)
                End If
            Next
        End If

    End Sub



    <System.Runtime.CompilerServices.Extension()>
    Public Function ObtienePadreDeTipo(Of T As DependencyObject)(depObj As DependencyObject) As T
        If depObj Is Nothing Then
            Return Nothing
        End If
        Dim parent As DependencyObject
        Do
            parent = VisualTreeHelper.GetParent(depObj)
            If Not parent Is Nothing Then
                Dim result = If(TryCast(parent, T), ObtienePadreDeTipo(Of T)(parent))
                If result IsNot Nothing Then
                    Return result
                End If
            End If
        Loop Until parent Is Nothing
        Return Nothing
    End Function
    <System.Runtime.CompilerServices.Extension()>
    Public Function ObtieneContexto(Entidad As IEntityWithRelationships) As ObjectContext
        If Entidad Is Nothing Then Throw New ArgumentNullException
        Dim relationshipmanager = Entidad.RelationshipManager
        Dim relatedend = relationshipmanager.GetAllRelatedEnds.FirstOrDefault
        If relatedend Is Nothing Then Throw New Exception("No relationships found")
        Dim query As ObjectQuery = relatedend.CreateSourceQuery
        If query Is Nothing Then Throw New Exception("The Entity is Detached")
        Return query.Context
    End Function


    <System.Runtime.CompilerServices.Extension()>
    Public Function GetDataRowHandles(grid As GridControl) As List(Of Integer)
        Dim rowHandles As New List(Of Integer)()
        For i As Integer = 0 To grid.VisibleRowCount - 1
            Dim rowHandle As Integer = grid.GetRowHandleByVisibleIndex(i)
            If grid.IsGroupRowHandle(rowHandle) Then
                If Not grid.IsGroupRowExpanded(rowHandle) Then
                    rowHandles.AddRange(GetDataRowHandlesInGroup(grid, rowHandle))
                End If
            Else
                rowHandles.Add(rowHandle)
            End If
        Next
        Return rowHandles
    End Function
    Private Function GetDataRowHandlesInGroup(grid As GridControl, groupRowHandle As Integer) As List(Of Integer)
        Dim rowHandles As New List(Of Integer)()
        For i As Integer = 0 To grid.GetChildRowCount(groupRowHandle) - 1
            Dim rowHandle As Integer = grid.GetChildRowHandle(groupRowHandle, i)
            If grid.IsGroupRowHandle(rowHandle) Then
                rowHandles.AddRange(GetDataRowHandlesInGroup(grid, rowHandle))
            Else
                rowHandles.Add(rowHandle)
            End If
        Next
        Return rowHandles
    End Function

    Public Function ObtieneCampos(T As Type) As List(Of String)
        Dim lp As New List(Of String)
        Dim propiedades = T.GetProperties
        For Each propiedad In propiedades.Where(Function(x) Not (x.PropertyType.Name.Contains("EntityReference") Or x.PropertyType.Name.Contains("EntityCollection") Or x.PropertyType.Name.Contains("EntityState") Or x.PropertyType.Name.Contains("EntityKey") Or (x.PropertyType.BaseType Is Nothing OrElse x.PropertyType.BaseType.Name = "EntityObject")))
            lp.Add(propiedad.Name)
        Next
        Return lp
    End Function
    Public Sub AgregaTodosCampos(tsgrid As tsGridControl, T As Type, Visible As Boolean, Optional SoloLectura As Boolean = True)
        Try
            Dim lp = ObtieneCampos(T)
            For Each p In lp
                If Not tsgrid.Columns.Any(Function(x) x.FieldName = p) And p.ToLower <> "seleccionar" Then
                    Dim gc As New tsGridColumn
                    gc.FieldName = p
                    gc.IsSmart = True
                    gc.Visible = Visible
                    gc.ReadOnly = SoloLectura
                    tsgrid.Columns.Add(gc)
                End If
            Next
        Catch ex As Exception
            Throw New Exception(ex.Message, ex)
        End Try
    End Sub
    <System.Runtime.CompilerServices.Extension()>
    Public Function ObtieneImagen(ByVal source As UIElement, ByVal scale As Double, ByVal quality As Integer) As Byte()
        Dim actualHeight As Double = source.RenderSize.Height
        Dim actualWidth As Double = source.RenderSize.Width
        Dim renderHeight As Double = actualHeight * scale
        Dim renderWidth As Double = actualWidth * scale
        Dim renderTarget As RenderTargetBitmap = New RenderTargetBitmap(CInt(renderWidth), CInt(renderHeight), 96, 96, PixelFormats.Pbgra32)
        Dim sourceBrush As VisualBrush = New VisualBrush(source)
        Dim drawingVisual As DrawingVisual = New DrawingVisual()
        Dim drawingContext As DrawingContext = drawingVisual.RenderOpen()

        Using drawingContext
            drawingContext.PushTransform(New ScaleTransform(scale, scale))
            drawingContext.DrawRectangle(Brushes.White, Nothing, New Rect(New Point(0, 0), New Point(actualWidth, actualHeight)))
            drawingContext.DrawRectangle(sourceBrush, Nothing, New Rect(New Point(0, 0), New Point(actualWidth, actualHeight)))
        End Using

        renderTarget.Render(drawingVisual)
        Dim jpgEncoder As JpegBitmapEncoder = New JpegBitmapEncoder()
        jpgEncoder.QualityLevel = quality
        jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget))
        Dim _imageArray As Byte()

        Using outputStream As MemoryStream = New MemoryStream()
            jpgEncoder.Save(outputStream)
            _imageArray = outputStream.ToArray()
        End Using

        Return _imageArray
    End Function
#Region "dbContext"
    <System.Runtime.CompilerServices.Extension()>
    Public Function GetEntityKey(Of T As Class)(ByVal context As DbContext, ByVal entity As T) As EntityKey
        Dim oc = (CType(context, IObjectContextAdapter)).ObjectContext
        Dim ose As ObjectStateEntry = Nothing

        If entity IsNot Nothing AndAlso oc.ObjectStateManager.TryGetObjectStateEntry(entity, ose) Then
            Return ose.EntityKey
        End If

        Return Nothing
    End Function
    <System.Runtime.CompilerServices.Extension()>
    Public Function GetEntityKey(Of T As Class)(ByVal context As DbContext, ByVal dbEntityEntry As DbEntityEntry(Of T)) As EntityKey
        If dbEntityEntry IsNot Nothing Then
            Return GetEntityKey(context, dbEntityEntry.Entity)
        End If

        Return Nothing
    End Function
#End Region
End Module
