#! /bin/bash
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:

# follows gzip syntax -- acts in place if filename provided, outputs to
#   stdout with -c, accepts stdin and outputs to stdout if filename is - or absent

# output to stdout?
if [[ "$1" == "-c" ]]; then
    shift;
    stdout=1;
else
    stdout=
fi

# use stdin?
if [[ ! $1 || "$1" == "-" ]]; then
    stdin=1
    stdout=1
elif [[ $1 && ! -f "$1" ]]; then
    echo "usage: dopo [-c] [-|140KdiskImageFilename] 1>&2";
    exit 1;
else
    stdin=
fi

if [[ ! $stdout ]]; then
    #get filename extension, in lowercase
    f="$(tr [:upper:] [:lower:] <<< ${1##*.})";

    #if it's dsk/do/po, get name without extension
    [[ "$f" == "dsk" || "$f" == "do" || "$f" == "po" ]] && of="${1%.*}" || of="$1";

    #if name had .po extension, append .dsk to outfile name, otherwise append .po
    [[ "$f" == "po" ]] && of="$of.dsk" || of="$of.po"

    # set outfile param for dd
    ofile="$of"
else
    ofile="/tmp/$$.dopo_out"
fi

if [[ ! $stdin ]]; then
    # set infile param for dd
    ifile="$1"
elif [[ -t 0 ]]; then
    echo "usage: dopo [-c] [-|140KdiskImageFilename]" 1>&2; exit 1;
else
    ifile="/tmp/$$.dopo_in"
    cat > "$ifile"
fi

# verify file is 140K by successfully reading 140K'th byte, and failing to read the one past
[[ $(dd if="$ifile" of=/dev/null bs=1 skip=143359 2>&1 | tail -1 | cut -d ' ' -f 1) -ne 1 || $(dd if="$ifile" of=/dev/null bs=1 skip=143360 2>&1 | tail -1 | cut -d ' ' -f 1) -ne 0 ]] && badInput=1 || badInput=

if [[ $badInput ]]; then
    if [[ ! $stdin ]]; then
        echo -n "$1 doesn't appear to be a 140K image. Continue? " 1>&2;
        read
        [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]] || exit 1;
    else
        echo "warning: Input file doesn't appear to be a 140K image." 1>&2
        echo "         Output file is likely to be useless." 1>&2
    fi
fi

# for each track
for t in {0..34}; do
 # read each sector in the right sequence to make (or unmake)
 # valid ProDOS blocks (sector pairs)
 for s in 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15; do
        # copy the sector from the old file to the new one
        dd if="$ifile" of="$ofile" bs=256 count=1 skip=$(( t*16 + s )) seek=$(( t*16 + (s==0 || s==15 ? s : 15-s) )) 2> /dev/null
    done
done

# remove the old one
[[ ! $stdin && ! $stdout ]] && rm "$1" &> /dev/null

# dump to stdout if -c or stdin used
[[ $stdout ]] && { cat $ofile; rm $ofile &> /dev/null; }
[[ $stdin ]] && rm $ifile &> /dev/null;