#----------------------------------------------------------------------
#  Eskil, Fourway diff section
#
#  Copyright (c) 2018, Peter Spjuth  (peter.spjuth@gmail.com)
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; see the file COPYING.  If not, write to
#  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
#  Boston, MA 02111-1307, USA.
#
#----------------------------------------------------------------------
# $Revision$
#----------------------------------------------------------------------

proc DoFourWayDiff {top} {
    # Copy to convenient local vars
    foreach field $::eskil(fw,fields) {
        set filename($field) $::eskil($top,$field)
        set rev($field)      $::eskil($top,rev,$field)
    }
    # Fill in defaults, if revisions are given for empty files
    foreach {from to} $::eskil(fw,fields) {
        if {$filename($to) eq "" && $rev($to) ne ""} {
            set filename($to) $::eskil($top,$from)
        }
        if {$filename($from) eq "" && $rev($from) ne ""} {
            set filename($from) $::eskil($top,$to)
        }
    }
    parray filename
}

# Browse for file
proc DoOpenFw {top field} {
    upvar \#0 ::eskil($top,$field) filename
    set initDir [pwd]
    if {$filename ne ""} {
        set initDir [file dirname $filename]
    } else {
        # Pick default dir from other files
        foreach other [lreverse $::eskil(fw,fields)] {
            if {$other eq $field} continue
            puts $other
            if {$::eskil($top,$other) ne ""} {
                set initDir [file dirname $::eskil($top,$other)]
                puts $initDir
                break
            }
        }
    }
    set apa [myOpenFile -title "Select file" -initialdir $initDir \
                     -parent $top]
    if {$apa != ""} {
        set filename $apa
    }
}

# File drop using TkDnd
proc fileDropFw {top field files} {
    if {$field eq "any"} {
        # Dropped outside the entry widgets. Try to be clever.
        set todo {}
        # Drop in empty fields first
        foreach field $::eskil(fw,fields) {
            if {$::eskil($top,$field) eq ""} {
                lappend todo $field
            }
        }
        # Fill fields otherwise
        if {[llength $todo] == 0} {
            set todo $::eskil(fw,fields)
        }
    } else {
        set todo [list $field]
    }
    foreach fn $files field $todo {
        # Loop until any list ends
        if {$fn eq "" || $field eq ""} break
        # Sanity check
        if {[file exists $fn]} {
            set ::eskil($top,$field) $fn
        }
    }
}

proc makeFourWayWin {} {
    set top .fourway

    if {[winfo exists $top] && [winfo toplevel $top] eq $top} {
        raise $top
        focus -force $top
        return $top
    }
    destroy $top
    toplevel $top -padx 3 -pady 3
    eskilRegisterToplevel $top

    wm title $top "Four Way Diff"
    wm protocol $top WM_DELETE_WINDOW "cleanupAndExit $top"

    menu $top.m
    $top configure -menu $top.m
    $top.m add cascade -menu $top.m.mf -label "File" -underline 0
    menu $top.m.mf
    $top.m.mf add command -label "Close" -underline 0 \
            -command [list cleanupAndExit $top]
    $top.m.mf add separator
    $top.m.mf add command -label "Quit" -underline 0 \
            -command [list cleanupAndExit all]

    # Four files, with optional revision
    set ::eskil(fw,fields) {base1 change1 base2 change2}
    
    ttk::label $top.l1 -text "Base 1"
    ttk::label $top.l2 -text "Changed 1"
    ttk::label $top.l3 -text "Base 2"
    ttk::label $top.l4 -text "Changed 2"
    set txt1 "First diff is made from Base 1 to Changed 1.\n If a file is empty\
              and have a revision, the other file name is used."
    addBalloon $top.l1 $txt1
    addBalloon $top.l2 $txt1
    set txt2 [string map {1 2 First Second} $txt1]
    addBalloon $top.l3 $txt2
    addBalloon $top.l4 $txt2

    ttk::label $top.el -text "File path"
    ttk::label $top.rl -text "Rev"
    addBalloon $top.rl "If you want to use a revisioned controlled file instead\n of\
                        the one on disk, add a revision here. E.g. 0 can be used\n for\
                        latest commited revision."

    set n 0
    foreach field $::eskil(fw,fields) {
        incr n
        ttk::entryX $top.e$n -width 60 -textvariable ::eskil($top,$field)
        ttk::button $top.b$n -text "Browse" -command [list DoOpenFw $top $field]
        ttk::entryX $top.r$n -width 6 -textvariable ::eskil($top,rev,$field)
    }

    ttk::button $top.bd -text "Diff" -command "DoFourWayDiff $top" -underline 0 \
            -width 8
    bind $top <Alt-d> [list $top.bd invoke]

    grid x       $top.el x       $top.rl -sticky w  -padx 3 -pady 3
    grid $top.l1 $top.e1 $top.b1 $top.r1 -sticky we -padx 3 -pady 3
    grid $top.l2 $top.e2 $top.b2 $top.r2 -sticky we -padx 3 -pady 3
    grid $top.l3 $top.e3 $top.b3 $top.r3 -sticky we -padx 3 -pady {10 3}
    grid $top.l4 $top.e4 $top.b4 $top.r4 -sticky we -padx 3 -pady 3
    grid $top.bd -       -                  -padx 3 -pady {10 3}

    # Set up file dropping in entry windows if TkDnd is available
    if {![catch {package require tkdnd}]} {
        dnd bindtarget $top    text/uri-list <Drop> "fileDropFw $top any     %D"
        dnd bindtarget $top.e1 text/uri-list <Drop> "fileDropFw $top base1   %D"
        dnd bindtarget $top.e2 text/uri-list <Drop> "fileDropFw $top change1 %D"
        dnd bindtarget $top.e3 text/uri-list <Drop> "fileDropFw $top base2   %D"
        dnd bindtarget $top.e4 text/uri-list <Drop> "fileDropFw $top change2 %D"
    }

    return $top
}
