/*
 * page.c
 */

/*
 * mpage:	a program to reduce pages of print so that several pages
 * 	  	of output appear on one printed page.
 *
 * Copyright (c) 1994-2004 Marcel J.E. Mol, The Netherlands
 * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia
 *  
 *     Permission is granted to anyone to make or distribute verbatim
 *     copies of this document as received, in any medium, provided
 *     that this copyright notice is preserved, and that the
 *     distributor grants the recipient permission for further
 *     redistribution as permitted by this notice.
 *
 */


#include "mpage.h"
#include "string.h"

#define PAPERSIZE_FILE  "/etc/papersize"
void
check_papersize()
{
    FILE * psfp;
    char buf[LINESIZE];
    
    if (access(PAPERSIZE_FILE, R_OK))
        return; /* no access or no papersize file. Just do nothing */

    if ((psfp = fopen(PAPERSIZE_FILE, "r")) == NULL)
        return; /* no access or no papersize file. Just do nothing */

    while (fgets(buf, LINESIZE, psfp) != NULL) {
        int i = 0;
        int j = strlen(buf);

        while (i < j && (buf[i] == ' ' || buf[i] == '\t'))
            i++; /* skip leading space */
        while (--j >= 0 && (buf[j] == ' ' || buf[j] == '\t' || buf[j] == '\n' || buf[j] == '\r'))
            buf[j] = '\0'; /* skip trailing space */

        if (strlen(buf + i) && buf[i] != '#' ) {
            select_pagetype(buf + i);
            break;
        }
    }

    fclose (psfp);

    return;

} /* check_papersize */


void
set_page()
{
    int i = select_pagetype(opt_page);
 
    media = paper[i].media;
    ps_width = paper[i].width;
    ps_height = paper[i].height;

    return;

} /* set_page */



int
select_pagetype(char *pt)
{
    int i = 0;

    while (paper[i].media && strcasecmp(pt, paper[i].media))
        i++;
    if (paper[i].media)
        opt_page = paper[i].media;
    else
        fprintf(stderr, "%s: ignoring unknown paper type: %s\n",
                                MPAGE, pt);
    return i;

} /* select_pagetype */



void
show_pagetypes()
{
    int i = 0;

    printf("Mpage knows about the following paper types:\n");
    printf("Type           Points Wide Points High\n");
    printf("-------------- ----------- -----------\n");
    while (paper[i].media) {
        printf("%-14s %11d %11d\n",
               paper[i].media, paper[i].width, paper[i].height);
        i++;
    }

    return;

} /* show_pagetypes */



/*
 * Bases are the base for each page. e.g the corner points for outlines.
 */
   /*  __________________________
    * | ________________________ |
    * ||                        ||
    * ||                        ||
    * ||                 ybase4 ||
    * ||                        Y|
    * ||                        ||
    * ||                        ||
    * ||                 ybase3 ||
    * ||                        Y|
    * ||                        ||
    * ||                        ||
    * ||                 ybase2 ||
    * ||                        Y|
    * ||                        ||
    * ||                        ||
    * ||xbase1   xbase2  ybase1 ||
    * |X___________X____________Y|
    * |__________________________|
    */

int
xbase1()
{
#if 1
        int val;

        if (opt_duplex && ((ps_pagenum % 2) == 0))
                val = sheetmargin_right + sheetheader_right;
        else
                val = sheetmargin_left + sheetheader_left;

        Debug(DB_POINTS, "%%xbase1: %d\n", val);

        return val;
#else

	Debug(DB_POINTS, "%%xbase1: %d\n", sheetmargin_left + sheetheader_left);
	return sheetmargin_left + sheetheader_left;
#endif
} /* xbase1 */



int
xbase2()
{
#if 1
        int val;

        if (opt_duplex && ((ps_pagenum % 2) == 0))
                val = (ps_width - sheetmargin_left - sheetmargin_right
                          - sheetheader_left - sheetheader_right) / 2 +
                sheetmargin_right + sheetheader_right;
        else
                val = (ps_width - sheetmargin_left - sheetmargin_right
                          - sheetheader_left - sheetheader_right) / 2 +
                sheetmargin_left + sheetheader_left;

        Debug(DB_POINTS, "%%xbase2: %d\n", val);
        return  (val);
#else
	Debug(DB_POINTS, "%%xbase2: %d\n",
                (ps_width - sheetmargin_left - sheetmargin_right
                          - sheetheader_left - sheetheader_right) / 2 +
                sheetmargin_left + sheetheader_left);
        return  (ps_width - sheetmargin_left - sheetmargin_right
                          - sheetheader_left - sheetheader_right) / 2 +
                sheetmargin_left + sheetheader_left;
#endif
} /* xbase2 */



int
ybase1()
{
	Debug(DB_POINTS, "%%ybase1: %d\n",
               sheetmargin_bottom + sheetheader_bottom);
	return sheetmargin_bottom + sheetheader_bottom;
} /* ybase1 */



int
ybase2()
{
	Debug(DB_POINTS, "%%ybase2: %d\n",
	        (ps_height - sheetmargin_bottom - sheetmargin_top
                           - sheetheader_bottom - sheetheader_top) / 4
	        + sheetmargin_bottom + sheetheader_bottom);
	return (ps_height - sheetmargin_bottom - sheetmargin_top
                          - sheetheader_bottom - sheetheader_top) / 4
	        + sheetmargin_bottom + sheetheader_bottom;
} /* ybase2 */



int
ybase3()
{
	Debug(DB_POINTS, "%%ybase3: %d\n",
	        (ps_height - sheetmargin_bottom - sheetmargin_top
                           - sheetheader_bottom - sheetheader_top) / 2
	        + sheetmargin_bottom + sheetheader_bottom);
	return (ps_height - sheetmargin_bottom - sheetmargin_top
                          - sheetheader_bottom - sheetheader_top) / 2
	        + sheetmargin_bottom + sheetheader_bottom;
} /* ybase3 */



int
ybase4()
{
	Debug(DB_POINTS, "%%ybase4: %d\n",
	        (ps_height - sheetmargin_bottom - sheetmargin_top
                           - sheetheader_bottom - sheetheader_top) * 3 / 4
	        + sheetmargin_bottom + sheetheader_bottom);
	return  (ps_height - sheetmargin_bottom - sheetmargin_top
                           - sheetheader_bottom - sheetheader_top) * 3 / 4
	        + sheetmargin_bottom + sheetheader_bottom;
} /* ybase4 */



int
ytop1()
{
	Debug(DB_POINTS, "%%ytop1: %d\n", ybase2());
	/* return ybase1() + yht4(); */
	return ybase2();
} /* ytop1 */



int
ytop2()
{
	Debug(DB_POINTS, "%%ytop2: %d\n", ybase3());
	/* return ybase2() + yht4(); */
	return ybase3();
} /* ytop2 */



int
ytop3()
{
	Debug(DB_POINTS, "%%ytop3: %d\n", ybase4());
	/* return ybase3() + yht4(); */
	return ybase4();
} /* ytop3 */



int
ytop4()
{
	Debug(DB_POINTS, "%%ytop4: %d\n", 
	       ps_height - sheetmargin_bottom - sheetmargin_top
	                 - sheetheader_bottom - sheetheader_top
	                 + sheetmargin_bottom + sheetheader_bottom);
	/* return ybase4() + yht4(); */
	return ps_height - sheetmargin_bottom - sheetmargin_top
	                 - sheetheader_bottom - sheetheader_top
	                 + sheetmargin_bottom + sheetheader_bottom;
} /* ytop4 */



int
xwid1()
{
	Debug(DB_POINTS, "%%xwid1: %d\n",
	       ps_width - sheetmargin_left - sheetmargin_right
	                - sheetheader_left - sheetheader_right);
	return ps_width - sheetmargin_left - sheetmargin_right
	                - sheetheader_left - sheetheader_right;
} /* xwid1 */



int
xwid2()
{
	Debug(DB_POINTS, "%%xwid2: %d\n",
	       (ps_width - sheetmargin_left - sheetmargin_right
	                 - sheetheader_left - sheetheader_right) / 2);
	return (ps_width - sheetmargin_left - sheetmargin_right
	                 - sheetheader_left - sheetheader_right) / 2;
} /* xwid2 */



int
yht1()
{
	Debug(DB_POINTS, "%%yht1: %d\n",
	       ps_height - sheetmargin_top - sheetmargin_bottom
	                 - sheetheader_top - sheetheader_bottom);
	return ps_height - sheetmargin_top - sheetmargin_bottom
	                 - sheetheader_top - sheetheader_bottom;
} /* yht1 */



int
yht2()
{
	Debug(DB_POINTS, "%%yht2: %d\n",
	       (ps_height - sheetmargin_top - sheetmargin_bottom
	                  - sheetheader_top - sheetheader_bottom) / 2);
	return (ps_height - sheetmargin_top - sheetmargin_bottom
	                  - sheetheader_top - sheetheader_bottom) / 2;
} /* yht2 */



int
yht4()
{
	Debug(DB_POINTS, "%%yht4: %d\n",
	       (ps_height - sheetmargin_top - sheetmargin_bottom
	                  - sheetheader_top - sheetheader_bottom) / 4);
	return (ps_height - sheetmargin_top - sheetmargin_bottom
	                  - sheetheader_top - sheetheader_bottom) / 4;
} /* yht4 */



void
outline_1(outfd)
 FILE *outfd;
{
	/* one page outline */
	fprintf(outfd, "0 setlinewidth\n");
        fprintf(outfd, "%d %d moveto 0 %d rlineto\n",
                       xbase1(), ybase1(), yht1());
	fprintf(outfd, "%d 0 rlineto 0 %d rlineto closepath stroke\n",
                       xwid1(), -yht1());

        return;
} /* outline_1 */



void
outline_2(outfd)
 FILE *outfd;
{
	/* two page outline */
	outline_1(outfd);
	fprintf(outfd, "%d %d moveto %d 0 rlineto stroke\n",
                xbase1(), ybase3(), xwid1());

        return;
} /* outline_2 */



void
outline_4(outfd)
 FILE *outfd;
{
	/* four page outline */
	outline_2(outfd);
	fprintf(outfd, "%d %d moveto 0 %d rlineto stroke\n",
                xbase2(), ybase1(), yht1());

        return;
} /* outline_4 */



void
outline_8(outfd)
 FILE *outfd;
{
	/* eight page outline */
	outline_4(outfd);
	fprintf(outfd, "%d %d moveto %d 0 rlineto stroke\n",
                xbase1(), ybase2(), xwid1());
	fprintf(outfd, "%d %d moveto %d 0 rlineto stroke\n",
                xbase1(), ybase4(), xwid1());

        return;
} /* outline_8 */



void
mp_outline(outfd, asheet)
 FILE *outfd;
 struct sheet *asheet;
{

    if (opt_outline) {
        (*asheet->sh_outline)(outfd);
    }

    return;

} /* mp_outline */



void
sheetheader(outfd, fname)
 FILE *outfd;
 char *fname;
{

    if (opt_sheetheader) {
        fprintf(outfd, "gsave\nheaderfont setfont\n");
        switch (orientation) {
            case PORTRAIT:
                sheetheader_top = 14;
#if 0
		/* centered text... */
                fprintf(outfd, "%d %d (%s) stringwidth pop sub 2 div add %d moveto",
                               xbase1(), xwid1(), sheethead,
                               ytop4() + fsize / 4);
                fprintf(outfd, " (%s) show\n", sheethead);
#endif
                /*
                 * Filename/Header on the left
                 */
                fprintf(outfd, "%d %d moveto (%s) show\n",
                            xbase1() + 3, ytop4() + fsize / 4,
			    *sheethead != '\0' ? sheethead : fname);
                /*
                 * Pagenumber on the right
                 */
                fprintf(outfd, "%d (Page %d) stringwidth pop sub 3 sub %d moveto",
                            xbase1() + xwid1(), ps_pagenum,
                            ytop4() + fsize / 4);
                fprintf(outfd, " (Page %d) show\n", ps_pagenum);
                break;
            case LANDSCAPE:
            case LANDSCAPE_PORTRAIT:
                sheetheader_right = 14;
#if 0
                fprintf(outfd, "%d %d (%s) stringwidth pop 2 div add moveto",
                               xbase1() + xwid1() + fsize/4,
                               ybase3(), sheethead);
                fprintf(outfd, " -90 rotate (%s) show\n", sheethead);
#endif
                /*
                 * Filename/Header on the left
                 */
                fprintf(outfd, "%d %d moveto -90 rotate (%s) show\n",
                            xbase1() + xwid1() + fsize/4, ytop4() - 3,
			    *sheethead != '\0' ? sheethead : fname);
                /*
                 * Pagenumber on the right
                 */
                fprintf(outfd, "90 rotate %d %d (Page %d) stringwidth pop ",
                                   xbase1() + xwid1() + fsize/4,
                                   ybase1() + 3, ps_pagenum);
                fprintf(outfd, "add moveto -90 rotate (Page %d) show\n",
                                   ps_pagenum);
                break;
        }
        fprintf(outfd, "grestore\n");
    }

    return;

} /* sheetheader */

