#! @@AWK@@ -f
#
BEGIN {

    ID    = "cdclpsnup 1.0"
    DATE  =                              "2003/02/05 (T.Kagimoto; original is coded by Y.Naito)"
#   MODIFY                                2003/02/10 (T.Kagimoto) 

    EX    = "multiple pages per sheet for dcl.ps"

    USAGE = "% cdclpsnup -nup [-c] [-r] [-l] [-p] <file>..."

    OPTIONS = \
      "\t -nup: number of pages on one sheet\n"\
      "\t -c:   column-major layout\n"\
      "\t -r:   row-major layout\n"\
      "\t -l:   landscape orientation\n"\
      "\t -p:   portrait orientation"

    USAGE_NAWK = "% cdclpsnup nup=<number> [cmajor=1] [rmajor=1] [landscape=1] [portrait=1] <file>..."

    OPTIONS_NAWK = \
      "\t nup:       number of pages on one sheet\n"\
      "\t cmajor:    if the value is 1, column-major layout\n"\
      "\t rmajor:    if the value is 1, row-major layout\n"\
      "\t landscape: if the value is 1, landscape orientation\n"\
      "\t portrait:  if the value is 1, portrait orientation"
#---------------------------------------------------------------------------------------------------
# OPTIONS

    TRUE = 1; FALSE = 0

    rmajor = FALSE
    cmajor = FALSE
    head   = TRUE
    body   = FALSE
    page   = 0
    frame  = 0
    row    = 1
    column = 1
    portrait  = 0
    landscape = 0

    exithelp = FALSE
    AWKCOM = ARGV[0]
    if (ARGV[1] == "-help" || ARGV[1] == "help" || ARGC == 1) print_usage()

    for (n = 0; n < 26; n++) {
        NRPAGE[n] = 0; NCPAGE[n] = 0; scale[n]; rotate[n]; orientation[n]
    }
    NRPAGE[ 2] = 2; NCPAGE[ 2] = 1; scale[ 2] = 0.7071; rotate[ 2] = TRUE;  orientation[ 2] = "Portrait"
    NRPAGE[ 4] = 2; NCPAGE[ 4] = 2; scale[ 4] = 0.5000; rotate[ 4] = FALSE; orientation[ 4] = "Landscape"
    NRPAGE[ 8] = 4; NCPAGE[ 8] = 2; scale[ 8] = 0.3535; rotate[ 8] = TRUE;  orientation[ 8] = "Portrait"
    NRPAGE[ 9] = 3; NCPAGE[ 9] = 3; scale[ 9] = 0.3333; rotate[ 9] = FALSE; orientation[ 9] = "Landscape"
    NRPAGE[16] = 4; NCPAGE[16] = 4; scale[16] = 0.2500; rotate[16] = FALSE; orientation[16] = "Landscape"
    NRPAGE[25] = 5; NCPAGE[25] = 5; scale[25] = 0.2000; rotate[25] = FALSE; orientation[25] = "Landscape"

    n = 0
    for (i = 1; i < ARGC; i++) {
      if (ARGV[i] ~ /^-[0-9]+/) {
          nup = substr(ARGV[i],2)+0
          if (NRPAGE[nup] == 0 || NCPAGE[nup] == 0) {
              print "*** ERROR(cdclpsnup)***  "nup "-up is not supported."
              exithelp = TRUE
              exit
          }
          delete ARGV[i]
          continue
      }
      if (ARGV[i] == "-r") {
          rmajor = TRUE; cmajor = FALSE
          delete ARGV[i]
          continue
      }
      if (ARGV[i] == "-c") {
          cmajor = TRUE; rmajor = FALSE
          delete ARGV[i]
          continue
      }
      if (ARGV[i] == "-p") {
          portrait  = TRUE
          landscape = FALSE
          delete ARGV[i]
      }
      if (ARGV[i] == "-l") {
          portrait  = FALSE
          landscape = TRUE
          delete ARGV[i]
      }
      if (ARGV[i] ~ /^-.*/) print_usage()
      FILE[n] = ARGV[i]; n++
    }
    nfile = n
    if (nfile < 1) print_usage()
}

NR == 1 {
    if (portrait)
         orientation[nup] = "Portrait"
    else if (landscape)
         orientation[nup] = "Landscape"
    else if (! portrait && ! landscape) {
        if (orientation[nup] ==  "Portrait")  portrait = TRUE
        if (orientation[nup] == "Landscape") landscape = TRUE
    }

    if ((rotate[nup] && landscape) || (! rotate[nup] && portrait)) {
        tmp = NRPAGE[nup]
        NRPAGE[nup] = NCPAGE[nup]
        NCPAGE[nup] = tmp
    }
    if (rmajor == cmajor) rmajor = TRUE
}

#---- get boundingbox ----
/^%%BoundingBox:/ {
    llx = $2; lly = $3; urx = $4; ury = $5
    xwidth = (urx-llx)*scale[nup]; ywidth = (ury-lly)*scale[nup]
    print
    next
}

/^%%Orientation:/ {
    print "%%Orientation:",orientation[nup]
}

#---- remove background white area ----
/^%%BeginObject: background/ {
    while ($0 != "%%EndObject") getline
    next
}

/^%%Page:/ {
    body = TRUE; head = FALSE; frame++
    if (frame == 1) {
        row = 1; column = 1
        page++; print "%%Page:", page, page
    }
    next
}

/concat$/ {
#
#     /x'\   / a  c \ /x\   /e\
#     |  | = |      | | | + | |  <=>  [a b c d e f] concat
#     \y'/   \ b  d / \y/   \f/
#
    gsub(/\[/,""); gsub(/\]/,"")
    a = $1; b = $2; c = $3; d = $4; e = $5; f = $6
    if (! rotate[nup]) {
        aa = a * scale[nup]
        bb = b * scale[nup]
        cc = c * scale[nup]
        dd = d * scale[nup]
        if (landscape) {
            ee = llx + xwidth*row
            ff = f + ywidth*(column-1)
        } else if (portrait) {
            ee = llx + xwidth*column
            ff = f + ywidth*(NRPAGE[nup]-row)
        }
    } else {
        if (portrait) {
            aa =-c * scale[nup]
            bb = d * scale[nup]
            cc = a * scale[nup]
            dd = b * scale[nup]
            ee = llx + ywidth*(column-1)
            ff = ury - xwidth*row
        } else if (landscape) {
            aa = c * scale[nup]
            bb = d * scale[nup]
            cc = a * scale[nup]
            dd =-b * scale[nup]
            ee = urx - ywidth*(NRPAGE[nup]-row)
            ff = lly + xwidth*column
        }
    }
    print "[",aa,bb,cc,dd,ee,ff,"] concat"; next
}

/showpage/ {
    body = FALSE
    if (frame == nup) {
        frame = 0
        print
    }
    if (rmajor) {
        column++
        if (column > NCPAGE[nup]) {
            column = 1
            row++
        }
    }
    if (cmajor) {
        row++
        if (row > NRPAGE[nup]) {
            row = 1
            column++
        }
    }
    next
}

{
    if (head || body) print
}

END {
    if (! exithelp) {
        if (frame != 0) print "showpage"
        print "%%Trailer"
        print "%%Pages:", page
        print "%%EOF"
    }
}

function print_usage () {
    exithelp = TRUE
    print "  " ID, DATE
    print " --- " EX
    if (AWKCOM ~ /gawk/) {
        print " usage : " USAGE
        print OPTIONS
    } else if (AWKCOM ~ /nawk/) {
        print " usage : " USAGE_NAWK
        print OPTIONS_NAWK
    }
    exit
}

function max(val1, val2) {
    if (val1 < val2)
        return val2
    else
        return val1
}

function mod(i,j) {
    k = int(i/j)
    return i-j*k
}

