#!/bin/sh

#-
# Copyright (C) 2007, 2008, 2009, 2010 Pietro Cerutti <gahr@gahr.ch>
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#

#
# Binaries
#
ASPELL=`which aspell`
BASENAME=`which basename`
CP=`which cp`
EXPR=`which expr`
ID=`which id`
LATEX=`which latex`
DIRNAME=`which dirname`
DVIVIEW=`which xdvi`
PDFVIEW=`which xpdf`
DVIPDF=`which dvipdf`
DVIPS=`which dvips`
MKDIR=`which mkdir`
RM=`which rm`
STAT=`which stat`
TAR=`which tar`

#
# GLOBAL VARIABLES
#
TMAKE_VERSION=0.1
COPYRIGHT="Copyright (C) 2007 Pietro Cerutti <gahr@FreeBSD.ch>"
AUTHOR="`${ID} -P | cut -d ":" -f 8`"
CWD=`pwd`
PROJ_FILE="${CWD}/.tmake.proj"
OUTPUT_DIR="${CWD}/out"
PACK_DIR="${CWD}/pack"
LOG_FILE="${CWD}/tmake.log"
DIC_FILE="${CWD}/.tmake.dic"
SOURCES=`find . -name "*.tex"`

print_header()
{
   _idx=0
   echo -n "*"
   echo ""
   if [ "${PROJECT_NAME}" ]; then
      echo "* ${PROJECT_NAME}"
      echo "*"
   fi
   echo "* TMake ${TMAKE_VERSION}"
   echo "* Copyright (C) 2007 Pietro Cerutti <gahr@gahr.ch>"
   echo "*"
}

create_proj_file()
{
   _latex_path_ok=0
   _main_tex_ok=0
   _dvi_viewer_path_ok=0
   _pdf_viewer_path_ok=0
   _dvi_pdf_path_ok=0
   _dvi_ps_path_ok=0
   _work_dir_ok=0

   print_header

   echo "* Project properties:"
   
   # Project name
   read -p "  -> Project name: " _proj_name

   # Main TeX file
   read -p "  -> Main TeX file (without .tex extension) [${_proj_name}]: " _main_tex
   if [ ! "${_main_tex}" ]; then
      _main_tex="${_proj_name}.tex"
   fi

   # Latex path
   while [ ${_latex_path_ok} -eq 0 ]; do
      read -p "  -> Full path of latex binary [${LATEX}]: " _LATEX
      if [ "${_LATEX}" -a ! -d "${_LATEX}" -a -x "${_LATEX}" ]; then
         LATEX=${_LATEX}
      fi
      if [ "${LATEX}" ]; then _latex_path_ok=1; fi
   done

   # DVI viewer path
   while [ ${_dvi_viewer_path_ok} -eq 0 ]; do
      read -p "  -> Full path of DVI viewer [${DVIVIEW}]: " _DVIVIEW
      if [ "${_DVIVIEW}" -a ! -d  "${_DVIVIEW}" -a -x "${_DVIVIEW}" ]; then
         DVIVIEW=${_DVIVIEW}
      fi
      if [ "${DVIVIEW}" ]; then _dvi_viewer_path_ok=1; fi
   done

   # PDF viewer path
   while [ ${_pdf_viewer_path_ok} -eq 0 ]; do
      read -p "  -> Full path of PDF viewer [${PDFVIEW}]: " _PDFVIEW
      if [ "${_PDFVIEW}" -a ! -d  "${_PDFVIEW}" -a -x "${_PDFVIEW}" ]; then
         PDFVIEW=${_PDFVIEW}
      fi
      if [ "${PDFVIEW}" ]; then _pdf_viewer_path_ok=1; fi
   done

   # DVI 2 PDF
   while [ ${_dvi_pdf_path_ok} -eq 0 ]; do
      read -p "  -> Full path of DVI to PDF converter [${DVIPDF}]: " _DVIPDF
      if [ "${_DVIPDF}" -a ! -d "${_DVIPDF}" -a -x "${_DVIPDF}" ]; then
         DVIPDF=${_DVIPDF}
      fi
      if [ "${DVIPDF}" ]; then _dvi_pdf_path_ok=1; fi
   done

   # DVI 2 PS
   while [ ${_dvi_ps_path_ok} -eq 0 ]; do
      read -p "  -> Full path of the DVI to PS converter [${DVIPS}]: " _DVIPS
      if [ "${_DVIPS}" -a ! -d "${_DVIPS}" -a -x "${_DVIPS}" ]; then
         DVIPS=${_DVIPS}
      fi
      if [ "${DVIPS}" ]; then _dvi_ps_path_ok=1; fi
   done

   echo "PROJECT_NAME=\"${_proj_name}\""  >> ${PROJ_FILE}
   echo "MAIN_TEX=${_main_tex}"           >> ${PROJ_FILE}
   echo "LATEX=${LATEX}"                  >> ${PROJ_FILE}
   echo "DVIVIEW=${DVIVIEW}"              >> ${PROJ_FILE}
   echo "PDFVIEW=${PDFVIEW}"              >> ${PROJ_FILE}
   echo "DVIPDF=${DVIPDF}"                >> ${PROJ_FILE}
   echo "DVIPS=${DVIPS}"                  >> ${PROJ_FILE}

   if [ ! -e "${_main_tex}.tex" ]; then
      touch "${_main_tex}.tex"
      echo "\\documentclass[a4paper,12pt]{article}"   >> "${_main_tex}.tex"
      echo ""                                         >> "${_main_tex}.tex"
      echo "\\title{${_proj_name}}"                   >> "${_main_tex}.tex"
      echo "\\author{${AUTHOR}}"                      >> "${_main_tex}.tex"
      echo "\\begin{document}"                        >> "${_main_tex}.tex"
      echo "\\maketitle"                              >> "${_main_tex}.tex"
      echo "Put your content here."                   >> "${_main_tex}.tex"
      echo "\\end{document}"                          >> "${_main_tex}.tex"
   fi

   echo "* Project generation complete."
}

#
# Build the project
#

#
# If project file doesn't exist in
# current directory, create a new one
#
if [ ! -f ${PROJ_FILE} ]; then
   create_proj_file
   exit 0
else
   . ${PROJ_FILE}
   print_header
fi

check_dvi()
{
   if [ ! -f ${OUTPUT_DIR}/${MAIN_TEX}.dvi ]; then
      return 1
   fi
   for tex in ${SOURCES}; do
      if [ `${STAT} -f %m "$tex"` -gt `${STAT} -f %m ${OUTPUT_DIR}/${MAIN_TEX}.dvi` ]; then
         return 1
      fi
   done

   return 0
}

check_pdf()
{
   if [ ! -f ${OUTPUT_DIR}/${MAIN_TEX}.pdf ]; then
      return 1
   fi
   for tex in ${SOURCES}; do
      if [ `${STAT} -f %m "$tex"` -gt `${STAT} -f %m ${OUTPUT_DIR}/${MAIN_TEX}.pdf` ]; then
         return 1
      fi
   done

   return 0
}

build()
{
   cleantex
   if [ ! -d "${OUTPUT_DIR}" ]; then 
      mkdir "${OUTPUT_DIR}"
   fi
   if check_dvi; then
      return
   fi
   echo "" > ${LOG_FILE}
   echo "**** GENERATING DVI ****" >> ${LOG_FILE}
   echo -n " -> generating DVI... "
   while ( ${LATEX} ${MAIN_TEX} >> ${LOG_FILE}; grep -q "Rerun to get cross" ${LOG_FILE} ); do
      echo -n "."
   done
   mv ${MAIN_TEX}.dvi ${OUTPUT_DIR}/
   echo "done."
   cleantex
   echo "" >> ${LOG_FILE}
   echo "**** GENERATING POSTSCRIPT ****" >> ${LOG_FILE}
   echo -n " -> generating PostScript... "
   ${DVIPS} ${OUTPUT_DIR}/${MAIN_TEX} 2>> ${LOG_FILE}
   mv ${MAIN_TEX}.ps ${OUTPUT_DIR}/
   echo "done."
}

view()
{
   build
   if [ -e "${OUTPUT_DIR}/${MAIN_TEX}.dvi" ]; then
      ${DVIVIEW} "${OUTPUT_DIR}/${MAIN_TEX}"
   fi
}

viewpdf()
{
   pdf
   if [ -e "${OUTPUT_DIR}/${MAIN_TEX}.pdf" ]; then
       ${PDFVIEW} "${OUTPUT_DIR}/${MAIN_TEX}.pdf"
   fi
}

pdf()
{
   build
   if check_pdf; then
      return 0
   fi
   echo -n " -> generating PDF... "
   ${DVIPDF} "${OUTPUT_DIR}/${MAIN_TEX}.dvi" "${OUTPUT_DIR}/${MAIN_TEX}.pdf"
   echo "done (${OUTPUT_DIR}/${MAIN_TEX}.pdf)."
}

cleantex()
{
   find . -maxdepth 1 -type f \( -name "*.aux" -o \
                                 -name "*.toc" -o \
                                 -name "*.dvi" -o \
                                 -name "*${MAIN_TEX}.log" \
                              \) -delete
}

clean()
{
   cleantex
   if [ -d "${OUTPUT_DIR}" ]; then
      ${RM} -r "${OUTPUT_DIR}"
   fi
   if [ -f "${LOG_FILE}" ]; then
      ${RM} "${LOG_FILE}"
   fi
   if [ -d "${PACK_DIR}" ]; then
      ${RM} -r "${PACK_DIR}"
   fi
   if [ -f "${PROJECT_NAME}.tar.bz2" ]; then
      ${RM} "${PROJECT_NAME}.tar.bz2"
   fi
}

print()
{
   build
   if [ ${1} ]; then
      _p="${1}"
   else
      _p="${PRINTER}"
   fi

   echo  -n " -> printing on ${_p}... "
   read -t 3 -p " -> press enter within 3 seconds to abort... " key
   if [ $? -ne 1 ]; then
      return
   fi
   lpr -P ${_p} ${OUTPUT_DIR}/${MAIN_TEX}.ps
   echo "done."
}

pack()
{
   pdf
   _sources="$SOURCES"
   if [ -d "${PACK_DIR}" ]; then
      ${RM} -r ${PACK_DIR}
   fi
   ${MKDIR} ${PACK_DIR}
   echo -n " -> creating the tarball... "
   for tex in ${_sources}; do
      _basename=`${BASENAME} "${tex}"`
      _dirname=`${DIRNAME} "$tex"`
      if [ ! -d "${PACK_DIR}/${_dirname}" ]; then
         mkdir -p "${PACK_DIR}/${_dirname}"
      fi
      ln "$tex" "${PACK_DIR}/${_dirname}/${_basename}"
   done
   ${CP} ${OUTPUT_DIR}/${MAIN_TEX}.pdf ${PACK_DIR}
   cd ${PACK_DIR};
   ${TAR} --exclude "${PROJECT_NAME}.tar.bz2" -cjf "${PROJECT_NAME}.tar.bz2" .
   cd -
   ${CP} "${PACK_DIR}/${PROJECT_NAME}.tar.bz2" .
   ${RM} -r ${PACK_DIR}
   echo "done (${PROJECT_NAME}.tar.bz2)."
}

spell()
{
   if [ $1 ]; then
      ${ASPELL} -p ${DIC_FILE} -c $1
   else
      for tex in ${SOURCES}; do
         ${ASPELL} -p ${DIC_FILE} -c ${tex}
      done
   fi

   if [ -f "*.tex.bak" ]; then
      for tex in "*.tex.bak"; do
         ${RM} $tex
      done
   fi

}

#
# Call functions basing on options
#
if [ $# -eq 0 -o "$1" = "build" ]; then build; exit 0;
elif [ "$1" = "rebuild" ]; then clean; build; exit 0;
elif [ "$1" = "clean" ]; then clean; exit 0;
elif [ "$1" = "view" ]; then view; exit 0;
elif [ "$1" = "viewpdf" ]; then viewpdf; exit 0;
elif [ "$1" = "pdf" ]; then pdf; return 0;
elif [ "$1" = "print" ]; then print $2; return 0;
elif [ "$1" = "pack" ]; then pack; return 0;
elif [ "$1" = "spell" ]; then spell $2; return 0;
else echo "Unknown command \"$1\""; exit 1;
fi
