'  
'   Rebex Sample Code License
' 
'   Copyright 2025, REBEX CR s.r.o.
'   All rights reserved.
'   https://www.rebex.net/
' 
'   Permission to use, copy, modify, and/or distribute this software for any
'   purpose with or without fee is hereby granted.
' 
'   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
'   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
'   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
'   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
'   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
'   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
'   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
'   OTHER DEALINGS IN THE SOFTWARE.
' 

Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms

Imports Rebex.IO.Compression

''' <summary>
''' A dialog that asks for action when a problem occurs.
''' </summary>
Partial Public Class ProblemDetectedDialog
    Inherits Form

    ' event arguments
    Private _arguments As ZipProblemDetectedEventArgs

    ' list of problem types the user chose to skip
    Private ReadOnly _skipProblemTypes As New Dictionary(Of ArchiveProblemType, Object)()

    ' true if the user chose to overwrite all existing files
    Private _overwriteAll As Boolean

    ' true if the user chose to overwrite all older files
    Private _overwriteOlder As Boolean

    ' true if the user chose to overwrite all files with a different size
    Private _overwriteDifferentSize As Boolean

    ' true if the user chose to overwrite all files with a different checksum
    Private _overwriteDifferentChecksum As Boolean

    ''' <summary>
    ''' Initializes a new instance of the dialog.
    ''' </summary>
    Public Sub New()
        InitializeComponent()
    End Sub

    ''' <summary>
    ''' Shows the form as a modal dialog box.
    ''' The form's buttons are enabled according to the possible actions taken from the given event argument.
    ''' </summary>
    ''' <param name="owner">Owner of the dialog.</param>
    ''' <param name="e">Event argument describing the problem type.</param>
    Public Overloads Sub ShowDialog(ByVal owner As Control, ByVal e As ZipProblemDetectedEventArgs)
        ' if the user chose to skip this problem type, skip it
        If _skipProblemTypes.ContainsKey(e.ProblemType) Then
            e.Action = ArchiveProblemActions.Skip
            Return
        End If

        ' if the problem is FileExists check, whether the user have chosen any default action already
        If e.ProblemType = ArchiveProblemType.FileExists Then
            If _overwriteAll Then
                e.Action = ArchiveProblemActions.Overwrite
                Return
            End If

            If _overwriteDifferentSize Then
                e.Action = ArchiveProblemActions.OverwriteIfDifferentSize
                Return
            End If

            If _overwriteDifferentChecksum Then
                e.Action = ArchiveProblemActions.OverwriteIfDifferentChecksum
                Return
            End If

            If _overwriteOlder Then
                e.Action = ArchiveProblemActions.OverwriteIfOlder
                Return
            End If

            ' format the text according to SftpTransferState (Downloading or Uploading)
            Dim messageFormat As String = "Overwrite file: {0}" & vbCrLf & "    {1} Bytes, {2}" & vbCrLf & vbCrLf & "with file: {3}" & vbCrLf & "    {4} Bytes, {5}"
            If e.Operation = ArchiveOperation.Extract Then
                lblMessage.Text = String.Format(messageFormat, e.ExternalItemPath, e.ExternalItemLength, e.ExternalItemLastWriteTime, e.ArchiveItemPath, e.ArchiveItemLength, _
                 e.ArchiveItemLastWriteTime)
            Else
                lblMessage.Text = String.Format(messageFormat, e.ArchiveItemPath, e.ArchiveItemLength, e.ArchiveItemLastWriteTime, e.ExternalItemPath, e.ExternalItemLength, _
                 e.ExternalItemLastWriteTime)
            End If

            lblMessage.TextAlign = ContentAlignment.MiddleLeft
        Else
            lblMessage.Text = e.Exception.Message
            lblMessage.TextAlign = ContentAlignment.MiddleCenter
        End If

        ' store the event arguments for later use at button click handler
        _arguments = e

        ' only enable buttons that represent a possible action
        btnCancel.Enabled = e.IsActionPossible(ArchiveProblemActions.Cancel)
        btnSkip.Enabled = e.IsActionPossible(ArchiveProblemActions.Skip)
        btnSkipAll.Enabled = e.IsActionPossible(ArchiveProblemActions.Skip)
        btnRetry.Enabled = e.IsActionPossible(ArchiveProblemActions.Retry)
        btnRename.Enabled = e.IsActionPossible(ArchiveProblemActions.Rename)
        btnOverwrite.Enabled = e.IsActionPossible(ArchiveProblemActions.Overwrite)
        btnOverwriteAll.Enabled = e.IsActionPossible(ArchiveProblemActions.Overwrite)
        btnOverwriteOlder.Enabled = e.IsActionPossible(ArchiveProblemActions.OverwriteIfOlder)
        btnOverwriteDiffSize.Enabled = e.IsActionPossible(ArchiveProblemActions.OverwriteIfDifferentSize)
        btnOverwriteDiffChecksum.Enabled = e.IsActionPossible(ArchiveProblemActions.OverwriteIfDifferentChecksum)
        btnFollowLink.Enabled = e.IsActionPossible(ArchiveProblemActions.FollowLink)

        ' select default action button
        SetDefaultActionButton(e.Action)

        ShowDialog(owner)
    End Sub

    ''' <summary>
    ''' Selects the default button according to the default action.
    ''' </summary>
    ''' <param name="action">Default problem action.</param>
    Private Sub SetDefaultActionButton(ByVal action As ArchiveProblemActions)
        Select Case action
            Case ArchiveProblemActions.ThrowException, ArchiveProblemActions.Cancel
                btnCancel.[Select]()
                Exit Select
            Case ArchiveProblemActions.Skip
                btnSkipAll.[Select]()
                Exit Select
            Case ArchiveProblemActions.Retry
                btnRetry.[Select]()
                Exit Select
            Case ArchiveProblemActions.Rename
                btnRename.[Select]()
                Exit Select
            Case ArchiveProblemActions.Overwrite
                btnOverwriteAll.[Select]()
                Exit Select
            Case ArchiveProblemActions.OverwriteIfOlder
                btnOverwriteOlder.[Select]()
                Exit Select
            Case ArchiveProblemActions.OverwriteIfDifferentSize
                btnOverwriteDiffSize.[Select]()
                Exit Select
            Case ArchiveProblemActions.OverwriteIfDifferentChecksum
                btnOverwriteDiffChecksum.[Select]()
                Exit Select
            Case ArchiveProblemActions.FollowLink
                btnFollowLink.[Select]()
                Exit Select
        End Select
    End Sub

    Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        _arguments.Action = ArchiveProblemActions.Cancel
        Close()
    End Sub

    Private Sub btnSkip_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSkip.Click
        _arguments.Action = ArchiveProblemActions.Skip
        Close()
    End Sub

    Private Sub btnSkipAll_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSkipAll.Click
        ' add the problem to the list of automatically skipped problems
        _skipProblemTypes.Add(_arguments.ProblemType, Nothing)

        _arguments.Action = ArchiveProblemActions.Skip
        Close()
    End Sub

    Private Sub btnRetry_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRetry.Click
        _arguments.Action = ArchiveProblemActions.Retry
        Close()
    End Sub

    Private Sub btnRename_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRename.Click
        ' get the filename
        Dim fileName As String = Path.GetFileName(_arguments.ExternalItemPath)

        ' initialize the renaming form
        Dim dialog As New NewNameDialog(fileName, True)

        ' show the form
        Dim result As DialogResult = dialog.ShowDialog(Me)

        ' check whether the user clicked OK
        If result <> DialogResult.OK Then
            Return
        End If

        ' set the appropriate action and new name to the event arguments
        _arguments.Action = ArchiveProblemActions.Rename
        _arguments.NewName = dialog.NewName
        Close()
    End Sub

    Private Sub btnOverwrite_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOverwrite.Click
        _arguments.Action = ArchiveProblemActions.Overwrite
        Close()
    End Sub

    Private Sub btnOverwriteAll_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOverwriteAll.Click
        _arguments.Action = ArchiveProblemActions.Overwrite
        _overwriteAll = True
        Close()
    End Sub

    Private Sub btnOverwriteOlder_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOverwriteOlder.Click
        _arguments.Action = ArchiveProblemActions.OverwriteIfOlder
        _overwriteOlder = True
        Close()
    End Sub

    Private Sub btnOverwriteDiffSize_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOverwriteDiffSize.Click
        _arguments.Action = ArchiveProblemActions.OverwriteIfDifferentSize
        _overwriteDifferentSize = True
        Close()
    End Sub

    Private Sub btnOverwriteDiffChecksum_Click(sender As Object, e As EventArgs) Handles btnOverwriteDiffChecksum.Click
        _arguments.Action = ArchiveProblemActions.OverwriteIfDifferentChecksum
        _overwriteDifferentChecksum = True
        Close()
    End Sub

    Private Sub btnFollowLink_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFollowLink.Click
        _arguments.Action = ArchiveProblemActions.FollowLink
        Close()
    End Sub
End Class
