#!../mofe --f

# for X11R4 users... use merge resources instead of fallbackResources...
if [string match "" [info command fallbackResources]] {
    alias fallbackResources mergeResources
}

# things, we allow the user to change via app-defaults or Xdefaults
fallbackResources topLevel \
    *search_label.labelString          "Search Pattern:"  \
    *replace_label.labelString         "Replace Pattern:" \
    *searchmenu.next.labelString       "Find Next"        \
    *searchmenu.next.mnemonic           N                 \
    *searchmenu.find.labelString       "Find All"         \
    *searchmenu.find.mnemonic           A                 \
    *searchmenu.replace.labelString    "Replace All"      \
    *searchmenu.replace.mnemonic        R                 \
    *searchmenu.clear.labelString      "Clear"            \
    *searchmenu.clear.mnemonic          C                 \
    *File*New.okLabelString             Open              \
    *File*New.dialogTitle              "Open File"        \
    *File*Save.okLabelString            Save              \
    *File*Save.dialogTitle             "Save File"        \
    *menubar.File.mnemonic              F                 \
    *menubar.Edit.mnemonic              E                 \
    *menubar.Search.mnemonic            S                 \
    *menubar.Help.mnemonic              H                 \
    *filemenu.New.mnemonic              N                 \
    *filemenu.Save.mnemonic             S                 \
    *filemenu.Quit.mnemonic             Q                 \
    *editmenu.Cut.mnemonic              C                 \
    *editmenu.Copy.mnemonic             o                 \
    *editmenu.Paste.mnemonic            P                 \
    *editmenu.Clear.mnemonic            l                 \
    *Foreground                         #000000000000     \
    *XmScrollBar*Foreground             #bfbfbfbfbfbf     \
    *XmLabel*Foreground                 #1d1d15155b5b     \
    *XmPushButton*Foreground            #5b5b00000000     \
    *Background                         #bfbfbfbfbfbf     \
    *XmTextField*Background             #9c9c9c9c9c9c     \
    *e*Background                       #dfdfdfdfdfdf     \
    *XmList*Background                  #dfdfdfdfdfdf     \
    *TopShadowColor                     #e7e7e7e7e7e7     \
  *XmCascadeButton.fontList       -*-helvetica-bold-o-normal-*-14-*-iso8859-1 \
  *XmLabel*fontList       -*-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1 \
  *XmPushButtonGadget*fontList  -*-helvetica-medium-r-normal-*-12-*-iso8859-1 \
  *XmText.fontList       -*-lucidatypewriter-medium-r-normal-*-12-*-iso8859-1 \
  *XmTextField.fontList  -*-lucidatypewriter-medium-r-normal-*-12-*-iso8859-1 \
  *XmPushButton*fontList        -*-helvetica-medium-r-normal-*-12-*-iso8859-1 \
  *XmList*fontList              -*-helvetica-medium-r-normal-*-12-*-iso8859-1


# things, we do not want the user to change..
mergeResources topLevel \
    *leftAttachment ATTACH_FORM \
    *rightAttachment ATTACH_FORM \
    *editmenu*activateCallback {editcb %w} \
    *searchmenu*activateCallback {searchcb %w} \
    *filemenu*activateCallback {fileDialog %w}

XmMainWindow main topLevel width 300
  XmMenuBar menubar main

      XmPulldownMenu filemenu menubar unmanaged
        XmPushButtonGadget New filemenu
        XmPushButtonGadget Save filemenu
        XmSeparatorGadget sep filemenu
        XmPushButtonGadget Quit filemenu activateCallback quit \
               accelerator Ctrl<Key>C acceleratorText Ctrl+C
    XmCascadeButton File menubar subMenuId filemenu

      XmPulldownMenu editmenu menubar unmanaged
        XmPushButtonGadget Cut editmenu
        XmPushButtonGadget Copy editmenu
        XmPushButtonGadget Paste editmenu
        XmSeparatorGadget sep editmenu
        XmPushButtonGadget Clear editmenu
    XmCascadeButton Edit menubar subMenuId editmenu

      XmPulldownMenu searchmenu menubar unmanaged
        XmPushButtonGadget next searchmenu 
        XmPushButtonGadget find searchmenu
        XmPushButtonGadget replace searchmenu
        XmSeparatorGadget sep searchmenu
        XmPushButtonGadget clear searchmenu
    XmCascadeButton Search menubar subMenuId searchmenu

      XmPulldownMenu helpmenu menubar unmanaged
        XmPushButtonGadget Help helpmenu \
            activateCallback "manageChild helpbox"
        XmPushButtonGadget Version helpmenu \
            activateCallback "manageChild versionbox"
    XmCascadeButton Help menubar subMenuId helpmenu

XmMessageDialog versionbox helpmenu unmanaged \
        dialogTitle "Motif Editor demo Program using Mofe" \
        okLabelString "Close" \
        messageString "(nc) No Copyright Peter Sylvester, Gustaf Neumann 1994"
unmanageChild \
        [XmMessageBoxGetChild versionbox DIALOG_CANCEL_BUTTON] \
        [XmMessageBoxGetChild versionbox DIALOG_HELP_BUTTON]

XmMessageDialog helpbox helpmenu unmanaged \
        dialogTitle "Help" \
        okLabelString "Close" \
        messageString "This program is a simple demo program for Mofe."
unmanageChild \
        [XmMessageBoxGetChild helpbox DIALOG_CANCEL_BUTTON] \
        [XmMessageBoxGetChild helpbox DIALOG_HELP_BUTTON]

sV menubar menuHelpWidget Help

XmForm form main
  XmRowColumn SearchPanel form \
         orientation horizontal packing PACK_TIGHT \
         topAttachment ATTACH_FORM
    XmLabel search_label SearchPanel
    XmTextField search_text SearchPanel
    XmLabel replace_label SearchPanel marginLeft 16
    XmTextField replace_text SearchPanel

  XmText text_output form editable False \
         cursorPositionVisible False shadowThickness 0 \
         bottomAttachment ATTACH_FORM

  XmScrolledText e form \
         rows 20 columns 80 editMode MULTI_LINE_EDIT \
         topAttachment ATTACH_WIDGET topWidget SearchPanel \
         bottomAttachment ATTACH_WIDGET bottomWidget text_output
realize

# create fileDialog the first time it is used...
proc fileDialog {name} {
  if [isWidget File*$name] {
    manageChild $name
    raiseWindow [parent $name]
  } else {
    XmFileSelectionDialog $name File \
	cancelCallback "unmanageChild %W" \
	okCallback "filecb $name %d \"%s\""
  }
}

# for Motif 1.1 users... 
# implementation of XmTextFindString, which is available in Motif 1.2..
if [string match "" [info command XmTextFindString]] {
  proc XmTextFindString {w start string direction pos} {
    upvar $pos returnPos
    switch $direction {
      TEXT_FORWARD {
        set content [string range [gV $w value] $start end]
        set returnPos [string first $string $content]
      }
      TEXT_BACKWARD {
        set content [string range [gV $w value] 0 $start]
        set returnPos [string last $string $content]
      }
    }
    if {$returnPos != -1} {
      incr returnPos $start
      return 1
    } else {
      return 0
    }
  }
}

proc errmsg {txt} {
    infomsg $txt
    bell topLevel 0
}

proc infomsg {txt} {
    sV text_output value $txt
}
proc filecb {op dir fileName} {
  if {[string match "" $fileName] || ![string compare $dir $fileName]} {
    errmsg "Choose a file."
  }
  if ![string compare $op New] {
    if ![file readable $fileName] {
      errmsg "Cannot read file '$fileName'"
      return
    }
    # missing: test for binary file
    set f [open $fileName]
    set content [read $f nonewline]
    close $f
    sV e value $content
    infomsg "Loaded [XmTextGetLastPosition e] bytes from '$fileName'."
  } else { 
    # Save 
    if [catch {set f [open $fileName w]}] {
      errmsg "Cannot write into file '$fileName'."
      return
    }
    puts -nonewline $f [gV e value]
    close $f
    set written [file size $fileName]
    if [string compare $written [XmTextGetLastPosition e]] {
      errmsg "Warning did not write entire file."
    } else {
      infomsg "Saved $written bytes to '$fileName'."
    }
  }
  unmanageChild $op
}

proc searchcb {op} {
  set endPos [XmTextGetLastPosition e]
  if ![string compare $op clear] {
    XmTextSetHighlight e 0 $endPos HIGHLIGHT_NORMAL
    return
  }
  if ![string compare $endPos 0] {
    errmg "No text to search."
    return
  }
  set search_length [string length [gV search_text value]]
  if ![string compare 0 $search_length] {
    errmsg "Specify a search pattern."
    return
  }
   
  if ![string compare $op next] {
    set p [expr [gV e cursorPosition]+1]
    if [XmTextFindString e $p [gV search_text value] TEXT_FORWARD found_pos] {
      XmTextSetHighlight e $found_pos \
	  [expr $found_pos+$search_length] HIGHLIGHT_SELECTED
      infomsg "Pattern found at position $found_pos."
      sV e cursorPosition $found_pos
      return
    }
  } else {
    # we have to handle now findall and replace, which iterate over
    # the whole file
    set p 0
    set count 0
    set found_pos 0
    set rpl [gV replace_text value]
    set rpl_length [string length $rpl]
    # unset old highlighing
    XmTextSetHighlight e 0 $endPos HIGHLIGHT_NORMAL
    set srch [gV search_text value]
    while {[XmTextFindString e $p $srch TEXT_FORWARD found_pos]} {
      set p [expr $found_pos+$search_length]
      if ![string compare $op replace] {
	XmTextReplace e $found_pos $p $rpl
	set p [expr $found_pos+$rpl_length]
      }
      XmTextSetHighlight e $found_pos $p HIGHLIGHT_SELECTED
      incr p
      incr count
    }
    if {$count>0} {
      switch $op {
	find    { infomsg "Found $count occurances." }
	replace { infomsg "Made $count replacements."}
      }
      return
    }
  }
  errmsg "Pattern not found."
}

proc editcb {op} {
  if ![string compare $op Clear] {
    XmTextClearSelection e
    errmsg ""
  } else {
    switch ["XmText$op" e] {
      1 { errmsg ""}
      0 { ermsg "There is no selection" }
    }
  }
}
