package admin;

import javax.swing.*;
import javax.swing.table.*;

import java.awt.print.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.Dimension;

public class AdminApplet extends JApplet implements Printable {

    JTable ppTable;
    JTableHeader tableHeader;
    int [] subTableSplit = null;
    boolean pageinfoCalculated=false;
    int totalNumPages=0;
    int prevPageIndex = 0;
    int subPageIndex = 0;
    int subTableSplitSize = 0;
    double tableHeightOnFullPage, headerHeight;
    double pageWidth, pageHeight;
    int fontHeight, fontDesent;
    double tableHeight, rowHeight;


    public void init() {

        final String[] headers = {"Item Number", "Summary", "Current High Bid", "Closing Date", "Number of Bids"};
        final Object[][] data = {
	    {"40000", "19th Century Martin Guitar", "$4,000", "April 22, 1999", new Integer(12)},
	    {"40001", "18th Century Sundial", "$10,000", "April 20, 1999", new Integer(26)},
	    {"40002", "Colonel Colt, 1851 Presentation Pistol", "$25,000", "April 21, 1999", new Integer(150)},
	    {"40003", "Beaded Purse", "$7,000", "April 22, 1999", new Integer(30)}
	};

        TableModel dataModel = new AbstractTableModel() {
            public int getColumnCount() { return headers.length; }
            public int getRowCount() { return data.length;}
            public Object getValueAt(int row, int col) {return data[row][col];}

            public String getColumnName(int column) {return headers[column];}
            public Class getColumnClass(int col) {return getValueAt(0,col).getClass();}
            public boolean isCellEditable(int row, int col) {return (col==1);}
            public void setValueAt(Object aValue, int row, int column) {
                data[row][column] = aValue;
            }
         };

	ppTable = new JTable(dataModel);
        JScrollPane scrollpane = new JScrollPane(ppTable);

        scrollpane.setPreferredSize(new Dimension(500, 80));
	getContentPane().setLayout(new BorderLayout());
        getContentPane().add(BorderLayout.CENTER,scrollpane);
	JButton printButton= new JButton();

	printButton.setText("print me!");

	getContentPane().add(BorderLayout.SOUTH,printButton);

	// for faster printing turn double buffering off

	RepaintManager.currentManager(this).setDoubleBufferingEnabled(false);

	printButton.addActionListener( new ActionListener(){
	    public void actionPerformed(ActionEvent evt) {
	        PrinterJob pj=PrinterJob.getPrinterJob();

		pj.setPrintable(AdminApplet.this);
		pj.printDialog();

		try{ 
		    pj.print();
		}catch (Exception PrintException) {}
	    }
	});

        setVisible(true);
    }

	public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {

	Graphics2D g2=(Graphics2D)g;

	if(!pageinfoCalculated) {
		getPageInfo(g, pageFormat);
	}

	g2.setColor(Color.black);
	if(pageIndex>=totalNumPages) {
		return NO_SUCH_PAGE;
	}
	if (prevPageIndex != pageIndex) {
		subPageIndex++;
		if( subPageIndex == subTableSplitSize -1) {
			subPageIndex=0;
		}
	}

	g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

	int rowIndex = pageIndex/ (subTableSplitSize -1);
	
	printTablePart(g2, pageFormat, rowIndex, subPageIndex);
	prevPageIndex= pageIndex;

	return Printable.PAGE_EXISTS;
	}


    public void getPageInfo(Graphics g, PageFormat pageFormat) {

        subTableSplit = null;
        subTableSplitSize = 0;
        subPageIndex = 0;
        prevPageIndex = 0;

        fontHeight=g.getFontMetrics().getHeight();
        fontDesent=g.getFontMetrics().getDescent();

        tableHeader = ppTable.getTableHeader();
        double headerWidth = tableHeader.getWidth();
        headerHeight = tableHeader.getHeight() + ppTable.getRowMargin();

        pageHeight = pageFormat.getImageableHeight();
        pageWidth =  pageFormat.getImageableWidth();

        double tableWidth = ppTable.getColumnModel().getTotalColumnWidth();
        tableHeight = ppTable.getHeight();
        rowHeight = ppTable.getRowHeight() + ppTable.getRowMargin();

        tableHeightOnFullPage = (int)(pageHeight - headerHeight - fontHeight*2);
        tableHeightOnFullPage = tableHeightOnFullPage/rowHeight * rowHeight;

        TableColumnModel tableColumnModel = tableHeader.getColumnModel();
        int columns = tableColumnModel.getColumnCount();
        int columnMargin = tableColumnModel.getColumnMargin();

        int [] temp = new int[columns];
        int columnIndex = 0;
        temp[0] = 0;
        int columnWidth;
        int length = 0;
        subTableSplitSize = 0;
        while ( columnIndex < columns ) {

           columnWidth = tableColumnModel.getColumn(columnIndex).getWidth();

           if ( length + columnWidth + columnMargin > pageWidth ) {
              temp[subTableSplitSize+1] = temp[subTableSplitSize] + length;
              length = columnWidth;
              subTableSplitSize++;
            }
            else {
               length += columnWidth + columnMargin;
            }
            columnIndex++;
        } //while

        if ( length > 0 )  {  // if are more columns left, part page
           temp[subTableSplitSize+1] = temp[subTableSplitSize] + length;
           subTableSplitSize++;
        }

        subTableSplitSize++;
        subTableSplit = new int[subTableSplitSize];
        for ( int i=0; i < subTableSplitSize; i++ ) {
           subTableSplit[i]= temp[i];
        }
        totalNumPages = (int)(tableHeight/tableHeightOnFullPage);
        if ( tableHeight%tableHeightOnFullPage >= rowHeight ) { // at least 1 more row left
            totalNumPages++;
        }

        totalNumPages *= (subTableSplitSize-1);
        pageinfoCalculated = true;
    }

    public void printTablePart(Graphics2D g2, PageFormat pageFormat, int rowIndex, int columnIndex) {

        String pageNumber = "Page: "+(rowIndex+1);
        if ( subTableSplitSize > 1 ) {
                pageNumber += "-" + (columnIndex+1);
	}

        int pageLeft = subTableSplit[columnIndex];
        int pageRight = subTableSplit[columnIndex + 1];

        int pageWidth =  pageRight-pageLeft;
	// page number message
        g2.drawString(pageNumber,  pageWidth/2-35, (int)(pageHeight - fontHeight));

        double clipHeight = Math.min(tableHeightOnFullPage, tableHeight - rowIndex*tableHeightOnFullPage);

        g2.translate(-subTableSplit[columnIndex], 0);
        g2.setClip(pageLeft ,0, pageWidth, (int)headerHeight);

        tableHeader.paint(g2);   // draw the header on every page
        g2.translate(0, headerHeight);
        g2.translate(0,  -tableHeightOnFullPage*rowIndex);

        // cut table image and draw on the page

        g2.setClip(pageLeft, (int)tableHeightOnFullPage*rowIndex, pageWidth, (int)clipHeight);
        ppTable.paint(g2);

        double pageTop =  tableHeightOnFullPage*rowIndex - headerHeight;
        double pageBottom = pageTop +  clipHeight + headerHeight;
        g2.drawRect(pageLeft, (int)pageTop, pageWidth, (int)(clipHeight+ headerHeight));
    }



}
