#!/bin/bash

# clipsnip-std, for Konch 1.00+
# Author: Alex Ibrado <alex@kdex.org>
# Part of the Konch distribution, http://konch.kdex.org/

# NOTE: You need sed and either a2ps or enscript

NAME="ClipSnip"
TITLE="Snippets"

# KONCH_DATA is the persistent folder for this script
SNIP="$KONCH_DATA/snippets.txt"
CONF="$KONCH_DATA/clipsniprc"

# KONCH_TEMP or KONCH_TMP is the temporary folder 
PDF="$KONCH_TEMP/$NAME.pdf"

# Some options for kdialog
KD_OPTS="--title $NAME --icon editcut"

# Manually-entered snippet, see "add_1"
SNIPPET=""

####################### FUNCTIONS ########################

function make_pdf {
# Create a PDF based on the current snippet file

  HAS_A2PS=`which a2ps 2>/dev/null`
  HAS_ENSCRIPT=`which enscript 2>/dev/null`
  
  if [ -z $HAS_A2PS -a -z $HAS_ENSCRIPT ]; then
    echo popup "Please install enscript or a2ps first."
  else
    if [ $HAS_ENSCRIPT ]; then
      enscript -2rG --word-wrap -p- "$SNIP" -b "$TITLE" | ps2pdf - "$PDF"
    elif [ $HAS_A2PS ]; then 
      a2ps "$SNIP" -o- --center-title="$TITLE" | ps2pdf - "$PDF"
    fi
  fi

}

function view_pdf {
# Update the PDF and show it via kpdf
  make_pdf
  kpdf "$PDF" &
}

function append_snippet {
# Add a snippet to $SNIP given a filename
# The filename can be - as usual, meaning standard input
  FILE=$1

  if [ "$USE_TS" == "1" ]; then
    echo >> "$SNIP"
    date +"$TIMESTAMP" >> "$SNIP"
  fi

  if [ "$SEPARATOR" != "" ]; then
    echo "$SEPARATOR"  >> "$SNIP"
  fi

  echo >> "$SNIP"
  cat "$FILE" >> "$SNIP"
  echo >> "$SNIP"

  if [ "$NOTIFY" == "1" ]; then
    if [ "$FILE" == "-" ]; then
      FIRST_LINE=`echo "$SNIPPET" | tr "\\n" " "`
    else
      FIRST_LINE=`cat "$FILE" | grep -v "^$" | head -1`
    fi
    WC=`echo -n $FIRST_LINE | wc -c`
    if [ $WC -gt 20 ]; then
      SHORT=`echo "$FIRST_LINE" | cut -c1-20`
      ELLIPSES="..."
    else
      SHORT=$FIRST_LINE
      ELLIPSES=""
    fi
    echo balloon "<b>$SHORT$ELLIPSES</b> has been added."
  fi

  echo clipboard text "$SNIP"
}

function read_config {
  . "$CONF"
}

function save_config {
# Creates or updates the configuration file (snipcliprc)
  if [ "$HEADER" == "" ]; then
    HEADER="$TITLE of $USER@$HOSTNAME"
  fi

  if [ "$SEPARATOR" == "" ]; then
    SEPARATOR="----------------------------------------------------------------------"
  fi

  if [ "$TIMESTAMP" == "" ]; then
    TIMESTAMP="%d %b %Y %I:%M:%S %p"
  fi

  if [ "$USE_TS" == "" ]; then
    USE_TS=1
  fi

  if [ "$NOTIFY" == "" ]; then
    NOTIFY=1
  fi

  echo "HEADER=\"$HEADER\"" > "$CONF"
  echo "SEPARATOR=\"$SEPARATOR\"" >> "$CONF"
  echo "TIMESTAMP=\"$TIMESTAMP\"" >> "$CONF"
  echo "USE_TS=$USE_TS" >> "$CONF"
  echo "NOTIFY=$NOTIFY" >> "$CONF"

  read_config
}

function reset_snippets {
# Clears the snippets, adds the default header, and regenerates the PDF
  PROCEED=1

  if [ -e "$SNIP" ]; then
    kdialog $KD_OPTS --warningyesno \
      "Are you sure you want to delete your current snippets?"

    if [ $? == 1 ]; then
      PROCEED= 
    fi
  fi

  if [ $PROCEED ]; then
    echo "$HEADER" > "$SNIP"
    # Disable Copy and Cut
    echo clipboard disable copy, cut
    make_pdf
  fi
}

function urldecode {
  # (C) 2004 GPL by Huidae Cho
  echo -e "$(sed 'y/+/ /; s/%/\\x/g')"
}

####################### MAIN ########################

ID=$1
EVENT=$2
shift 2

read_config

case $EVENT in

  ### Main events

  init)
    if [ ! -e "$CONF" ]; then
      # If this is the first time it's been run, create defaults
      save_config
      reset_snippets
    fi

    make_pdf

    cat <<END
      name $NAME
      icon klipper
      colorize 0 0 128 100
      overlay editcut

      menu View PDF,pdf,view
      menu Show Drop Target,,showdrop,checkable
      menu -

      submenu editmenu,&Edit
      editmenu &Open in KWrite,kwrite,edit
      editmenu -

      submenu optmenu,&Configure $NAME
      optmenu Use timestamps,clock,use_ts,checkable
      optmenu Show notifications,,notify,checkable
      optmenu -
      optmenu Header,,header
      optmenu Separator,,separator
      optmenu Timestamp,,timestamp

      use selection
      use clipboard editmenu

      clipboard accepts text/plain;charset=UTF-8, text/*

      # Also sends text/plain via clipboard copy/cut 
      clipboard provides text/plain

      # Additional items for the Edit menu
      editmenu -
      editmenu Clear snippets,editdelete,clear

      # Let's enable Drag
      use drag 
      drag provides application/pdf

      # ..and Drop
      use drop
      drop accepts text/uri-list, text/plain

      #use droptarget favorites 96 opaque
      use droptarget favorites

      # Make the current files available via Copy/Cut (text) and Drag (PDF)
      clipboard text $SNIP
      drag file $PDF

      # Let's make it so we can do stuff via DCOP too
      # so we can attach hotkeys via KHotKeys, Input Actions, etc.

      use dcop clipsnip ClipSnip
      dcop void add()
      dcop void add(QString newEntry)
      dcop void show()
      dcop void hide()
      dcop void view()
      dcop void edit()
      dcop void clear()
END

      # If user wants timestamps or notifications, check them
      # These variables are from read_config
      if [ "$USE_TS" == "1" ]; then
        echo check optmenu "Use timestamps"
      fi

      if [ "$NOTIFY" == "1" ]; then
        echo check optmenu "Show notifications"
      fi
  ;;

  rclick)
    echo menu show
  ;;

  dclick)
    view_pdf
  ;;

  click)
    ## Gets the current contents and calls "paste"
    echo clipboard get

    ## For "get", you can have Konch call a custom event instead, 
    #  e.g. "snippy", in case you need to distinguish this event
    #  for special processing, such as saving to disk.
    #echo clipboard get snippy
  ;;

  mclick)
    append_snippet $1
  ;;

  quit)
    echo quit
  ;;

  ### Menu events

  edit)
    kwrite $SNIP &
  ;;

  view)
    view_pdf
  ;;

  showdrop)
    SHOW=$1
    if [ "$SHOW" == "1" ]; then
      echo droptarget show
    else
      echo droptarget hide
    fi
  ;;

  clear)
    # Also used for DCOP
    reset_snippets
  ;;

  use_ts)
    USE_TS=$1
    if [ "$USE_TS" == "1" ]; then
      echo check optmenu "Use timestamps"
    else
      echo uncheck optmenu "Use timestamps"
    fi
    save_config
  ;;

  notify)
    NOTIFY=$1
    if [ "$NOTIFY" == "1" ]; then
      echo check optmenu "Show notifications"
    else
      echo uncheck optmenu "Show notifications"
    fi
    save_config
  ;;

  header)
    NEW_HDR=`kdialog $KD_OPTS --textinputbox "Enter header:" "$HEADER" 600 400`
    if [ "$NEW_HDR" != "" ]; then
      HEADER="$NEW_HDR"
      save_config
    fi
  ;;

  separator)
    NEW_SEP=`kdialog $KD_OPTS --inputbox "Enter separator:" -- "$SEPARATOR"`
    if [ "$NEW_SEP" != "" ]; then
      SEPARATOR="$NEW_SEP"
      save_config
    fi
  ;;

  timestamp)
    NEW_TS=`kdialog $KD_OPTS --inputbox "Enter timestamp format: (See <i>man date</i>)" "$TIMESTAMP"`
    if [ "$NEW_TS" != "" ]; then
      TIMESTAMP="$NEW_TS"
      save_config
    fi
  ;;


  ### Clipboard events

  copy)
    echo clipboard set
  ;; 

  cut)
    echo clipboard set
    reset_snippets
  ;; 

  paste)
    append_snippet $1
  ;;

  # In case you want to test it... See "click"
  snippy)
    append_snippet $1
  ;;


  ### Drag-and-drop events
  
  drag)
    FILE=$1
    MIME=$2
    # Make sure it's the latest
    make_pdf
    if [ "$NOTIFY" == "1" ]; then
      echo balloon "You are dragging <b>$FILE</b> ($MIME)"
    fi
    echo drag start
  ;;

  drop)
    FILE=$1
    MIME=$2
    
    if [ "$MIME" == "text/plain" ]; then
      append_snippet "$FILE"
    elif [ "$MIME" == "text/uri-list" ]; then
      # For each URI, remove the Return character, ...
      cat $FILE | tr -d "\r" | while read F ; do
        # ...make sure it's a local file
        IS_LOCAL=`echo "$F" | grep -e "^file://"`
        if [ "$IS_LOCAL" != "" ]; then
          LOCAL_FILE=`echo "$F" | cut -c 8- | urldecode`
          # ...that contains text
          IS_TEXT=`file -b "$LOCAL_FILE" | grep text`
          if [ "$IS_TEXT" != "" ]; then
            append_snippet "$LOCAL_FILE"
          fi
        fi
      done
    fi
  ;;

  droptarget)
    SHOWN=$1
    if [ "$SHOWN" == "1" ]; then
      echo check menu "Show Drop Target"
    else
      echo uncheck menu "Show Drop Target"
    fi
  ;;

  ### DCOP events

  add)
    NEW=`kdialog $KD_OPTS --textinputbox "Enter new snippet:" "" 600 400`
    echo "$NEW" | append_snippet -
  ;;

  add_1)
    SNIPPET=$1
    echo "$SNIPPET" | append_snippet -
  ;;

  show)
    echo show
  ;;

  hide)
    echo hide
  ;;

esac

