' *
' * The project site is at: http://sourceforge.jp/projects/fishbornas/
' *
' * First author tiritomato 2012.
' *
' * Distributed under the FishbornArchiveShelf License (See
' *  file "Licenses/License.txt" contained in a project, or the following link.
' *  http://sourceforge.jp/projects/fishbornas/scm/svn/blobs/head/trunk/Licenses/License.txt)
' *
' * 2012.06.07 Initial Revision (tiritomato)
' *

Partial Public Class AppDlg

    ' Type ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Public Class ToolStripCustomRenderer
        Inherits Windows.Forms.ToolStripProfessionalRenderer
        Private Class ProColorTable
            Inherits ProfessionalColorTable
            Public Overrides ReadOnly Property MenuStripGradientEnd As System.Drawing.Color
                Get
                    Return MenuStripGradientBegin
                End Get
            End Property
        End Class
        Public Sub New()
            MyBase.New(New ProColorTable)
            RoundedEdges = False
        End Sub
    End Class

    ' Constructor //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Public Sub New()
        InitializeComponent()
    End Sub

    Public Sub New(ByVal ConfigPath As Logic.FileSystem.Path)
        Me.New()
        If ConfigPath IsNot Nothing AndAlso ConfigPath.FileExists Then
            Me.AppBase = New AppBase(ConfigPath)
        Else
            Me.AppBase = Nothing
        End If
    End Sub

    ' Properties //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    Private Property AppBase As AppBase
        Get
            Return IIf(m_IsShown, m_AppBase, m_FirstRegistedAppBase)
        End Get
        Set(ByVal value As AppBase)
            If m_IsShown Then
                If value Is Nothing Then value = New AppBase(AppBase.Locations.ConfigurationPath) ' Load Config(appbase can't nothing clear from outside)
                ApplyAppBase(value)
            Else
                m_FirstRegistedAppBase = value
            End If
        End Set
    End Property

    ' Methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Public Sub FileImport()

        Dim ofd As New OpenFileDialog()

        Dim PathList() As Logic.FileSystem.Path = {AppBase.Config.ExportableGroup.LastImportedPath,
                                                   AppBase.Config.ExportableGroup.LastExportedPath}
        For Each Path As Logic.FileSystem.Path In PathList
            If Path IsNot Nothing AndAlso Path.IsNullOrWhiteSpace = False Then ofd.FileName = Path.ToString
        Next
        If String.IsNullOrWhiteSpace(ofd.FileName) Then
            Dim DirList() As Logic.FileSystem.Path = {AppBase.Config.Path.Parent,
                                                      IO.Directory.GetDirectoryRoot(Environment.GetFolderPath(Environment.SpecialFolder.System))}
            For Each Dir As Logic.FileSystem.Path In DirList
                If Dir IsNot Nothing AndAlso Dir.DirectoryExists Then ofd.InitialDirectory = Dir.ToString
            Next
        End If

        ofd.Filter = "設定ファイル (*.xml)|*.xml|すべてのファイル (*.*)|*.*"
        ofd.FilterIndex = 0
        ofd.Title = "設定ファイルのインポート"

        ofd.RestoreDirectory = True
        ofd.CheckFileExists = True
        ofd.CheckPathExists = True

        If ofd.ShowDialog() = DialogResult.OK Then
            AppBase.Config.ExportableGroup.ImportFromXml(ofd.FileName)
            AppBase = AppBase ' Apply config
        End If

    End Sub

    Public Sub FileExport()

        Dim ofd As New SaveFileDialog

        Dim PathList() As Logic.FileSystem.Path = {AppBase.Config.ExportableGroup.LastExportedPath,
                                                   AppBase.Config.ExportableGroup.LastImportedPath}
        For Each Path As Logic.FileSystem.Path In PathList
            If Path IsNot Nothing AndAlso Path.IsNullOrWhiteSpace = False Then ofd.FileName = Path.ToString
        Next
        If String.IsNullOrWhiteSpace(ofd.FileName) Then
            Dim DirList() As Logic.FileSystem.Path = {AppBase.Config.Path.Parent,
                                                      IO.Directory.GetDirectoryRoot(Environment.GetFolderPath(Environment.SpecialFolder.System))}
            For Each Dir As Logic.FileSystem.Path In DirList
                If Dir IsNot Nothing AndAlso Dir.DirectoryExists Then ofd.InitialDirectory = Dir.ToString
            Next
        End If

        ofd.Filter = "設定ファイル (*.xml)|*.xml|すべてのファイル (*.*)|*.*"
        ofd.FilterIndex = 0
        ofd.Title = "設定ファイルのエクスポート"

        ofd.RestoreDirectory = True
        ofd.OverwritePrompt = False
        ofd.CheckPathExists = True

        If ofd.ShowDialog() = DialogResult.OK Then
            If AppBase.Config.ExportableGroup.ExportToXml(ofd.FileName) = False Then MsgBox(AppBase.ResultMessage("ExportFileCreateFailed"))
        End If

    End Sub

    ' Private Implements //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Private ReportDialog_ResizeHandler As New Logic.UniqueEvents(Of EventArgs)
    Private ReportDialog_BaseSplit_SplitterMovedHandler As New Logic.UniqueEvents(Of SplitterEventArgs)
    Private ReportDialog_SampleSplit_SplitterMovedHandler As New Logic.UniqueEvents(Of SplitterEventArgs)
    Private ReportDialog_TreeSplit_SplitterMovedHandler As New Logic.UniqueEvents(Of SplitterEventArgs)
    Private ReportDialog_LogSplit_SplitterMovedHandler As New Logic.UniqueEvents(Of SplitterEventArgs)

    Private m_IsShown As Boolean = False
    Private m_AppBase As AppBase = Nothing
    Private m_FirstRegistedAppBase As AppBase = Nothing
    Private txtCtxMenuInsertTarget As Windows.Forms.TextBox = Nothing

    Private Sub ApplyAppBase(ByVal value As AppBase)

        ReportDialog_ResizeHandler.Clear()
        ReportDialog_BaseSplit_SplitterMovedHandler.Clear()
        ReportDialog_SampleSplit_SplitterMovedHandler.Clear()
        ReportDialog_TreeSplit_SplitterMovedHandler.Clear()
        ReportDialog_LogSplit_SplitterMovedHandler.Clear()

        If value IsNot Nothing Then
            ' oppai
            If value.Config.Locations.WorkFolder.Exists = False Then value.Config.Locations.WorkFolder.Path = AppBase.ExecutingLocation.UserAppDataPath.ToString
            If value.Config.WindowSize.ContainsKey(Windows.Forms.FormWindowState.Normal) Then
                Dim inf As AppBase.WindowSizeConfig = value.Config.WindowSize(Windows.Forms.FormWindowState.Normal)
                If 0 < inf.WndWidth Then Me.Width = inf.WndWidth
                If 0 < inf.WndHeight Then Me.Height = inf.WndHeight
                If 0 < inf.BaseSplitDistance Then MainSplit.SplitterDistance = inf.BaseSplitDistance
                If 0 < inf.SampleSplitDistance Then SampleSplitter.SplitterDistance = inf.SampleSplitDistance
                If 0 < inf.TreeSplitDistance Then TreeSplitter.SplitterDistance = inf.TreeSplitDistance
                LogSplit.SplitterDistance = Math.Max(LogSplit.Panel1MinSize,
                                                     LogSplit.Height - LogSplit.SplitterWidth - IIf(inf.IsLogSingleLineMode, StretchEchoPanel1.MinimumSize.Height, inf.LogSplitDistance))
            End If

            ReportDialog_ResizeHandler.Add(AddressOf ReportDialog_ResizeImpl)
            ReportDialog_BaseSplit_SplitterMovedHandler.Add(AddressOf MainSplit_SplitterMovedImpl)
            ReportDialog_SampleSplit_SplitterMovedHandler.Add(AddressOf SampleSplitter_SplitterMovedImpl)
            ReportDialog_TreeSplit_SplitterMovedHandler.Add(AddressOf TreeSplitter_SplitterMovedImpl)
            ReportDialog_LogSplit_SplitterMovedHandler.Add(AddressOf LogSplit_SplitterMovedImpl)

        End If

        TreeView1.AppBase = value
        lstFile.AppBase = value
        CoverLoader1.AppBase = value
        ArchiveInfoPanel1.AppBase = value
        PresetPanel.AppBase = value
        StretchEchoPanel1.AppBase = value

        m_AppBase = value

    End Sub

    Private Sub WorkThreadPallingExit()
        If InvokeRequired Then
            Invoke(New Logic.Threading.SubDelegate(AddressOf WorkThreadPallingExit))
        Else
            AppBase.MainTask.StopRequest(True)
            Me.Close()
        End If
    End Sub

    Private Sub ReportDialog_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
        txtCtxMenuInsertTarget = Nothing
        ApplyAppBase(Nothing)
    End Sub

    Private Sub ReportDialog_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        If AppBase.MainTask.IsWorkOut = False Then

            e.Cancel = True

            If e.CloseReason = Windows.Forms.CloseReason.UserClosing Then
                If MsgBox("実行中です。" & vbCrLf & "ただちに処理をキャンセルしてアプリケーションを終了しますか？", vbOKCancel) = vbCancel Then Exit Sub
            End If

            ' call stop request
            AppBase.MainTask.StopRequest()
            Me.Enabled = False ' stop flag

        End If

        AppBase.Config.ExportToXml()

    End Sub

    Private Sub MainSplit_SplitterMovedImpl(ByVal sender As System.Object, ByVal e As System.Windows.Forms.SplitterEventArgs)
        If Me.WindowState = FormWindowState.Normal Or Me.WindowState = FormWindowState.Maximized Then
            AppBase.Config.WindowSize(Me.WindowState).BaseSplitDistance = MainSplit.SplitterDistance
        End If
    End Sub

    Private Sub MainSplit_SplitterMoved(ByVal sender As System.Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles MainSplit.SplitterMoved
        ReportDialog_BaseSplit_SplitterMovedHandler.Invoke(sender, e)
    End Sub

    Private Sub SampleSplitter_SplitterMovedImpl(ByVal sender As System.Object, ByVal e As System.Windows.Forms.SplitterEventArgs)
        If Me.WindowState = FormWindowState.Normal Or Me.WindowState = FormWindowState.Maximized Then
            AppBase.Config.WindowSize(Me.WindowState).SampleSplitDistance = SampleSplitter.SplitterDistance
        End If
    End Sub

    Private Sub SampleSplitter_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles SampleSplitter.SplitterMoved
        ReportDialog_SampleSplit_SplitterMovedHandler.Invoke(sender, e)
    End Sub

    Private Sub TreeSplitter_SplitterMovedImpl(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs)
        If Me.WindowState = FormWindowState.Normal Or Me.WindowState = FormWindowState.Maximized Then
            AppBase.Config.WindowSize(Me.WindowState).TreeSplitDistance = TreeSplitter.SplitterDistance
        End If
    End Sub

    Private Sub TreeSplitter_SplitterMoved(ByVal sender As Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles TreeSplitter.SplitterMoved
        ReportDialog_TreeSplit_SplitterMovedHandler.Invoke(sender, e)
    End Sub

    Private Sub LogSplit_SplitterMovedImpl(ByVal sender As System.Object, ByVal e As System.Windows.Forms.SplitterEventArgs)
        If Me.WindowState = FormWindowState.Normal Or Me.WindowState = FormWindowState.Maximized Then
            If (StretchEchoPanel1.SingleLinePermitHeight + StretchEchoPanel1.MinimumSize.Height) <= StretchEchoPanel1.Height Then
                AppBase.Config.WindowSize(Me.WindowState).LogSplitDistance = StretchEchoPanel1.Height
                AppBase.Config.WindowSize(Me.WindowState).IsLogSingleLineMode = False
            Else
                AppBase.Config.WindowSize(Me.WindowState).IsLogSingleLineMode = True
            End If
        End If
    End Sub

    Private Sub LogSplit_MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LogSplit.MouseDoubleClick
        If Me.WindowState = FormWindowState.Normal Or Me.WindowState = FormWindowState.Maximized Then
            ReportDialog_LogSplit_SplitterMovedHandler.Remove(AddressOf LogSplit_SplitterMovedImpl)
            Try
                If StretchEchoPanel1.Height = StretchEchoPanel1.MinimumSize.Height Then
                    LogSplit.SplitterDistance = Math.Max(LogSplit.Panel1MinSize, LogSplit.Height - LogSplit.SplitterWidth - AppBase.Config.WindowSize(Me.WindowState).LogSplitDistance)
                    AppBase.Config.WindowSize(Me.WindowState).IsLogSingleLineMode = False
                Else
                    LogSplit.SplitterDistance = Math.Max(LogSplit.Panel1MinSize, LogSplit.Height - LogSplit.SplitterWidth - StretchEchoPanel1.MinimumSize.Height)
                    AppBase.Config.WindowSize(Me.WindowState).IsLogSingleLineMode = True
                End If
            Catch ex As Exception
                Throw
            Finally
                ReportDialog_LogSplit_SplitterMovedHandler.Add(AddressOf LogSplit_SplitterMovedImpl)
            End Try
        End If
    End Sub

    Private Sub LogSplit_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles LogSplit.Resize
        Dim MainSplitPanel2Height As Integer = MainSplit.Size.Height - MainSplit.SplitterWidth - MainSplit.SplitterDistance
        If MainSplitPanel2Height < (StretchEchoPanel1.Height + lstFile.Height + LogSplit.SplitterWidth) Then
            ReportDialog_LogSplit_SplitterMovedHandler.Remove(AddressOf LogSplit_SplitterMovedImpl)
            Try
                LogSplit.SuspendLayout()
                LogSplit.SplitterDistance = Math.Max(LogSplit.Panel1MinSize, LogSplit.Height - LogSplit.SplitterWidth - StretchEchoPanel1.MinimumSize.Height)
                LogSplit.SplitterDistance = LogSplit.Panel1MinSize
                LogSplit.ResumeLayout()
            Catch ex As Exception
                Throw
            Finally
                ReportDialog_LogSplit_SplitterMovedHandler.Add(AddressOf LogSplit_SplitterMovedImpl)
            End Try
        End If
    End Sub

    Private Sub LogSplit_SplitterMoved(ByVal sender As System.Object, ByVal e As System.Windows.Forms.SplitterEventArgs) Handles LogSplit.SplitterMoved
        ReportDialog_LogSplit_SplitterMovedHandler.Invoke(sender, e)
    End Sub

    Private Sub ReportDialog_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown

        TreeSplitter.Panel1MinSize = TreeView1.MinimumSize.Width
        LogSplit.Panel2MinSize = StretchEchoPanel1.MinimumSize.Height
        MainSplit.Panel2MinSize = LogSplit.Panel1MinSize + LogSplit.Panel2MinSize + LogSplit.SplitterWidth

        m_IsShown = True
        AppBase = m_FirstRegistedAppBase
        m_FirstRegistedAppBase = Nothing

    End Sub

    Private Sub ExecCancelToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        AppBase.MainTask.StopRequest()
        AppBase.Echoing.Log.Echo("キャンセル中...")
    End Sub

    Private Sub ReportDialog_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If (e.Modifiers = Keys.None) And (e.KeyCode = Keys.Escape) Then
            'If ExecCancelToolStripMenuItem.Enabled = True Then ExecCancelToolStripMenuItem_Click(Nothing, Nothing)
        End If
    End Sub

    Private Sub ReportDialog_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        ReportDialog_ResizeHandler.Invoke(sender, e)
    End Sub

    Private Sub ReportDialog_ResizeImpl(ByVal sender As Object, ByVal e As System.EventArgs)
        If Me.WindowState = FormWindowState.Normal Or Me.WindowState = FormWindowState.Maximized Then
            SyncLock AppBase
                Dim inf As AppBase.WindowSizeConfig = AppBase.Config.WindowSize(Me.WindowState)
                inf.WndWidth = Me.Width
                inf.WndHeight = Me.Height
            End SyncLock
        End If
    End Sub

    Private Sub tabMain_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tabMain.SelectedIndexChanged
        PresetPanel.SizeEventEnable = (tabMain.SelectedTab.Name = SettingTabPage.Name)
    End Sub

End Class
