/*  EditPanel.java
 *
 *  This class is the panel that the user edit and creates 
 *  the programs in. 
 *
 *  Author: Michael A. Piskuric (2537405) Summer 2005
 */

import Robot.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PrintQuality;


public class EditPanel extends JPanel implements KeyListener, Printable, AdjustmentListener {
    	
    private TeachVAL    parent;                             // parent window
    private JTextArea   textArea,lineNumbers;               // 2 text areas
    private JScrollPane scrollPane,lineNumPane;             // 2 scroll panes
    private String      jobName = "Print Job for "+System.getProperty("user.name");
    private int         left_margin = inchesToPage(0.5);    // used for print purposes
    private int         right_margin = inchesToPage(0.5);
    private int         top_margin = inchesToPage(0.5);
    private int         bottom_margin = inchesToPage(0.5);
    
    // create a new instance of editPanel and add it to parent window
    public EditPanel(TeachVAL tv) {    		
        parent = tv;
        int width = parent.getWidth()-20;
        int height = (int)((parent.getHeight()-80)*.6); 			
        setPreferredSize(new Dimension(width,height));
        setBorder(new javax.swing.border.TitledBorder("Editor"));
        
        textArea = new JTextArea((int)(height/17.5),(int)(width/11.75));        
        textArea.addKeyListener(this);
        textArea.setTabSize(2);
        
        lineNumbers = new JTextArea((int)(height/17.5),2);
        lineNumbers.setEditable(false);
        lineNumbers.setBackground(parent.getBackground());
        for(int i=2; i<=999; i++)lineNumbers.append(Integer.toString(i) + '\n');
        
        scrollPane = new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        lineNumPane = new JScrollPane(lineNumbers,JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        add(lineNumPane);
        add(scrollPane);        
        
        lineNumPane.setBorder(null);
        lineNumPane.setWheelScrollingEnabled(false);     
        lineNumbers.setEnabled(false);
        
        scrollPane.getVerticalScrollBar().addAdjustmentListener(this);
        parent.add(this);
    }
    
    // sets the text in the window
    public void setText(String text) {
        textArea.setText(text);
    }
    
    // gets the text in the window
    public String getText() {
        return textArea.getText();
    }
    
    // implements copy (<CTRL>+C)
    public void copy() {
        textArea.copy();
    }
    
    // implements cut (<CTRL>+X)
    public void cut() {
        textArea.cut();
    }
    
    // implements paste (<CTRL>+V)
    public void paste() {
        textArea.paste();
    }
    
    // inserts text into specific places int the the window
    public void insertText(String text, int where) {
        textArea.insert(text,where);
    }
    
    // used to print
    int inchesToPage(double inches) {
        return (int)(inches*72.0);
    }
    
    //method borrowed from http://forum.java.sun.com/thread.jspa?forumID=57&threadID=212065
    public void print() {
        // Create a printerJob object
        final PrinterJob printJob = PrinterJob.getPrinterJob();

        // Set the printable class to this one since we
        // are implementing the Printable interface
        printJob.setPrintable(this);
        printJob.setJobName(jobName);

        //Collect the print request attributes.
        final HashPrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
        attrs.add(OrientationRequested.PORTRAIT);
        attrs.add(Chromaticity.COLOR);
        attrs.add(Chromaticity.MONOCHROME);
        attrs.add(PrintQuality.NORMAL);
        attrs.add(PrintQuality.DRAFT);
        attrs.add(PrintQuality.HIGH);

        //Assume US Letter size, someone else can do magic for other paper formats
        attrs.add(new MediaPrintableArea(0.25f, 0.25f, 8.0f, 10.5f, MediaPrintableArea.INCH));

        // Show a print dialog to the user. If the user
        // clicks the print button, then print, otherwise
        // cancel the print job
        if (printJob.printDialog()) {
            //You may want to do the printing in a thread or SwingWorker
            //But this gets the job done all the same.
            try {
                printJob.print(attrs);
            } catch (Exception PrintException) {
                PrintException.printStackTrace();
            }
        }
}
    //method borrowed from http://forum.java.sun.com/thread.jspa?forumID=57&threadID=212065
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
        Graphics2D g2 = (Graphics2D) graphics;

        //Found it unwise to use the TextArea font's size,
        //We area just printing text so use a a font size that will
        //be generally useful.
        g2.setFont(getFont().deriveFont(9.0f));

        int bodyheight = (int)pageFormat.getImageableHeight();
        int bodywidth = (int)pageFormat.getImageableWidth();
        int lineheight = g2.getFontMetrics().getHeight()-(g2.getFontMetrics().getLeading()/2);
        int lines_per_page = (bodyheight-top_margin-bottom_margin)/lineheight;
        int start_line = lines_per_page*pageIndex;
       
        if (start_line > textArea.getLineCount()) {
            return NO_SUCH_PAGE;
        }
        int page_count = (textArea.getLineCount()/lines_per_page)+1;
        int end_line = start_line + lines_per_page;
        int linepos = (int)top_margin;
        int lines = textArea.getLineCount();

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

        for (int line = start_line; line < end_line; line++) {
            try {
                String linetext = textArea.getText(
                textArea.getLineStartOffset(line),
                textArea.getLineEndOffset(line)-textArea.getLineStartOffset(line));
                g2.drawString(linetext, left_margin, linepos);
            } catch (Exception e) {
                //never a bad location
            }
            linepos += lineheight;
            if (linepos > bodyheight-bottom_margin) {
                break;
            }
        }
        return Printable.PAGE_EXISTS;
    }
    
    // used to synchronize the line nuimbers scroll pane to 
    // the editor text pane
    public void adjustmentValueChanged(AdjustmentEvent e){
        lineNumPane.getVerticalScrollBar().setValue(e.getValue());
    }
    
    // user must recompile after they type something
    public void keyTyped(KeyEvent evt) {
        parent.getMenu().setRun(false);
        parent.getMenu().setCompile(true);
    }    
    public void keyReleased(KeyEvent evt){ }
    public void keyPressed(KeyEvent evt){ }
}