#!/bin/bash

if [[ $- = *x* ]]; then
    opt_x=-x
else
    opt_x=+x
fi

prog=${0##*/}
progdir=${0%/*}


function fail {
    echo "$prog:" "$@" >&2
    exit 1
}


function ask_yn {
    echo "$@"
    while read; do
        case $REPLY in
            [Yy]*) return 0;;
            [Nn]*) return 1;;
            *) echo "Enter yes or no";;
        esac
    done
    return 2  # EOF
}


function wehave {
    command -v "$1" &>/dev/null
}


default_template_dir=~/.templates
default_editor=vi
editor=${VISUAL:-${EDITOR:-$default_editor}}

function usage {
    ret=$1
    echo "Usage: $prog [-Ef] [<template>] [<destination>]"
    echo
    echo "Create a file or directory from the given template."
    echo "Templates are taken from the template directory is controlled by the TEMPLATE_DIR variable."
    echo "$default_template_dir is used if unset.  If the result is a file, it will be opened with"
    echo "$editor unless -E is passed."
    echo
    echo "Flags:"
    echo "-f    Force overwrite existing file"
    echo "-E    Don't edit the file"
    exit $ret
}

TEMPLATE_DIR=${TEMPLATE_DIR:-$default_template_dir}
[[ -d $TEMPLATE_DIR ]] || fail "No templates found in $TEMPLATE_DIR"

edit=true
force=false
OPTIND=1

while getopts :Efh opt; do
    case $opt in
        E) edit=false ;;
        f) force=true ;;
        h) usage 0 ;;
        *) usage 2 ;;
    esac
done
shift $((OPTIND-1))
OPTIND=1



if [[ $# -eq 2 ]]; then
    # absolute paths should be treated as filenames
    if [[ ${1:0:1} != [~/] ]]; then
        template=$TEMPLATE_DIR/$1
    else
        template=$1
    fi
    dest=$2
elif [[ $# -lt 2 ]]; then
    if [[ $# -eq 0 ]]; then
        echo -n "New file or directory name? "
        read -r dest
    else
        dest=$1
    fi
    if [[ -z $dest ]]; then exit; fi
    pushd "$TEMPLATE_DIR" || exit
    select t in *; do
        template=$TEMPLATE_DIR/$t
        break
    done
    popd || exit
else
    echo "Incorrect number of arguments" >&2
    usage 2
fi

if [[ -d $dest ]]; then
    dest=$dest/$(basename "$template")
fi
if [[ -e $dest ]]; then
    if [[ -d $dest ]]; then
        echo "Not overwriting existing directory $dest"
        exit 1
    fi
    if $force || ask_yn "Overwrite $dest?"; then
        rm -f "$dest.bak" || :
        mv -f "$dest" "$dest.bak"
    else
        echo "Destination already exists."
        exit 0
    fi
fi

cp -r "$template" "$dest" || fail "Copy failed"
echo "Created $dest"
if $edit && [[ -f $dest ]]; then
    exec "$editor" "$dest"
fi

# vim:et:sw=4:sts=4:ts=8
