/*
 * Copyright (c) 1997-2019 IDRsolutions (https://www.idrsolutions.com)
 */

package org.jpedal.examples.samples.swing;

import org.jpedal.PdfDecoder;
import org.jpedal.examples.viewer.Commands;
import org.jpedal.examples.viewer.Viewer;
import org.jpedal.exception.PdfException;
import org.jpedal.external.JPedalCustomDrawObject;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.io.File;


public class DrawAdditionalObjects {

    /**
     * example showing how to draw and print additional objects in Swing Viewer
     */
    @SuppressWarnings("OverlyLongMethod")
    DrawAdditionalObjects() {

        final PdfDecoder decode_pdf = getPdfDecoder();

        // sample code to add shapes and text on current page - should be called AFTER page decoded for display
        // (can appear on multiple pages for printing)
        //

        // in this example, we create a rectangle, a filled rectangle and draw some text.

        //initialise objects arrays - we will put 4 shapes on the page
        // (using PDF co-ordinates with origin bottom left corner)
        final int count = 4//adding shapes to page

        // Due to the way some pdf's are created it is necessery to take the offset of a page
        // into account when addding custom objects to the page. Variables mX and mY represent
        // that offset and need to be taken in to account when placing any additional object
        // on a page.

        int mX = decode_pdf.getPdfPageData().getMediaBoxX(1);
        int mY = decode_pdf.getPdfPageData().getMediaBoxY(1);

        //we place Swing Data in these arrays
        final int[] type = new int[count];
        final Color[] colors = new Color[count];
        final Object[] obj = new Object[count];


        
        //example stroked shape
        type[0= org.jpedal.render.DynamicVectorRenderer.STROKEDSHAPE;
        colors[0= Color.RED;
        obj[0new Rectangle(35 + mX, 35 + mY, 51050)//ALSO sets location. Any shape can be used

        //example filled shape
        type[1= org.jpedal.render.DynamicVectorRenderer.FILLEDSHAPE;
        colors[1= Color.GREEN;
        obj[1new Rectangle(40 + mX, 40 + mY, 50040)//ALSO sets location. Any shape can be used

        //example text object
        type[2= org.jpedal.render.DynamicVectorRenderer.STRING;
        final org.jpedal.render.TextObject textObject = new org.jpedal.render.TextObject()//composite object so we can pass in parameters
        textObject.x = 40 + mX;
        textObject.y = 40 + mY;
        textObject.text = "Example text on page";
        textObject.font = new Font("Serif", Font.PLAIN, 48);
        colors[2= Color.BLUE;
        obj[2= textObject; //ALSO sets location

        //example custom
        type[3= org.jpedal.render.DynamicVectorRenderer.CUSTOM;

        final JPedalCustomDrawObject exampleObj = new ExampleCustomDrawObject(-1);
        exampleObj.setMedX(mX);
        exampleObj.setMedY(mY);
       
        obj[3= exampleObj;

        //pass into JPEDAL after page decoded - will be removed automatically on new page/open file
        //BUT PRINTING retains values until manually removed
        try {
            decode_pdf.drawAdditionalObjectsOverPage(decode_pdf.getPageNumber(), type, colors, obj);
        catch (final PdfException e) {
            e.printStackTrace();
        }
        /**/

        
        //this code will remove ALL items already drawn on page

        //try{
        //    decode_pdf.flushAdditionalObjectsOnPage(commonValues.getCurrentPage());
        //}catch(PdfException e){
        //    e.printStackTrace();
        //    //ShowGUIMessage.showGUIMessage( "", new JLabel(e.getMessage()),"Exception adding object to display");
        //}


        

        //Example to PRINT (needs to be create beforehand)
        //objects can be the same as from draw

        for (int pages = 1; pages < decode_pdf.getPageCount() 1; pages++) { //note +1 for last page!!!
            final int count1 = 4;

            // Due to the way some pdf's are created it is necessery to take the offset of a page
            // into account when addding custom objects to the page. Variables mX and mY represent
            // that offset and need to be taken in to account when placing any additional object
            // on a page.

            mX = decode_pdf.getPdfPageData().getMediaBoxX(1);
            mY = decode_pdf.getPdfPageData().getMediaBoxY(1);
            final int[] typePrint = new int[count1];
            final Color[] colorsPrint = new Color[count1];
            final Object[] objPrint = new Object[count1];

            //example custom (from version 3.40)
            typePrint[0= org.jpedal.render.DynamicVectorRenderer.CUSTOM;

            final JPedalCustomDrawObject examplePrintObj = new ExampleCustomDrawObject(-1);
            examplePrintObj.setMedX(mX);
            examplePrintObj.setMedY(mY);

            objPrint[0= examplePrintObj;

            //example stroked shape
            typePrint[1= org.jpedal.render.DynamicVectorRenderer.STROKEDSHAPE;
            colorsPrint[1= Color.RED;
            objPrint[1new Rectangle(35 + mX, 35 + mY, 51050)//ALSO sets location. Any shape can be used

            //example filled shape
            typePrint[2= org.jpedal.render.DynamicVectorRenderer.FILLEDSHAPE;
            colorsPrint[2= Color.GREEN;
            objPrint[2new Rectangle(40 + mX, 40 + mY, 50040)//ALSO sets location. Any shape can be used

            //example text object
            typePrint[3= org.jpedal.render.DynamicVectorRenderer.STRING;
            final org.jpedal.render.TextObject textPrintObject = new org.jpedal.render.TextObject()//composite object so we can pass in parameters
            textPrintObject.x = 40 + mX;
            textPrintObject.y = 40 + mY;
            textPrintObject.text = "Print Ex text on page " + pages;
            textPrintObject.font = new Font("Serif", Font.PLAIN, 48);
            colorsPrint[3= Color.BLUE;
            objPrint[3= textPrintObject; //ALSO sets location

            //pass into JPEDAL after page decoded - will be removed automatically on new page/open file
            //BUT PRINTING retains values until manually removed
            decode_pdf.printAdditionalObjectsOverPage(pages, typePrint, colorsPrint, objPrint);

        }
        /**/


        
        //global printout
        final int count2 = 1;

        // Due to the way some pdf's are created it is necessery to take the offset of a page
        // into account when addding custom objects to the page. Variables medX and medY represent
        // that offset and need to be taken in to account when placing any additional object
        // on a page.

        final int medX = decode_pdf.getPdfPageData().getMediaBoxX(1);
        final int medY = decode_pdf.getPdfPageData().getMediaBoxY(1);
        final int[] typePrint = new int[count];
        final Color[] colorsPrint = new Color[count2];
        final Object[] objPrint = new Object[count2];

        //example custom
        typePrint[0= org.jpedal.render.DynamicVectorRenderer.CUSTOM;

        final JPedalCustomDrawObject exampleGlobalPrintObj = new ExampleCustomDrawObject(JPedalCustomDrawObject.ALLPAGES);
        exampleGlobalPrintObj.setMedX(medX);
        exampleGlobalPrintObj.setMedY(medY);
        exampleGlobalPrintObj.setVisible(true)//default is true so not mandatory

        //JPedalCustomDrawObject examplePrintObj=new ExampleCustomDrawObject();

        objPrint[0= exampleGlobalPrintObj;

        //pass into JPEDAL after page decoded - will be removed automatically on new page/open file
        //BUT PRINTING retains values until manually removed
        decode_pdf.printAdditionalObjectsOverAllPages(typePrint, colorsPrint, objPrint);

    }

    @SuppressWarnings("unused")
    public static void main(final String[] args) {
        new DrawAdditionalObjects();
    }

    PdfDecoder getPdfDecoder() {
        //create and initialise JPedal viewer component
        final Viewer myViewer = new Viewer();
        myViewer.setupViewer();

        myViewer.executeCommand(Commands.OPENFILE, new Object[]{new File("/PDFdata/test_data/Hand_Test/awjune2003.pdf")});

        return (PdfDecodermyViewer.getPdfDecoder();

    }


    

    /**
     * example of a custom draw object
     */
    private class ExampleCustomDrawObject implements JPedalCustomDrawObject {

        private boolean isVisible = true;

        private int page;

        int medX;
        int medY;

        ExampleCustomDrawObject(final Integer option) {
            if (option.equals(JPedalCustomDrawObject.ALLPAGES)) {
                page = -1;
            }
        }

        @Override
        public void print(final Graphics2D g2, final int x) {

            //custom code or just pass through
            if (page == x || page == -|| page == 0) {
                paint(g2);
            }
        }

        @Override
        public void paint(final Graphics2D g2) {
            if (isVisible) {

                //your code here

                //if you alter something, put it back
                final Paint paint = g2.getPaint();

                //loud shape we can see
                g2.setPaint(Color.orange);
                g2.fillRect(100 + medX, 100 + medY, 100100)// PDF co-ordinates due to transform

                g2.setPaint(Color.RED);
                g2.drawRect(100 + medX, 100 + medY, 100100)// PDF co-ordinates due to transform

                //put back values
                g2.setPaint(paint);
            }
            
            /*example onto rotated page*
            if(isVisible){
                
                //your code here
                
                AffineTransform aff=g2.getTransform();
                
                
                //allow for 90 degrees - detect of G2
                double[] matrix=new double[6];
                aff.getMatrix(matrix);
                
                //System.out.println("0="+matrix[0]+" 1="+matrix[1]+" 2="+matrix[2]+" 3="+matrix[3]+" 4="+matrix[4]+" 5="+matrix[5]);
                if(matrix[1]>0 && matrix[2]>0){ //90
                    
                    g2.transform(AffineTransform.getScaleInstance(-1, 1));
                    g2.transform(AffineTransform.getRotateInstance(90 *Math.PI/180));
                    
                    //BOTH X and Y POSITIVE!!!!
                    g2.drawString("hello world", 60,60);
                }else if(matrix[0]<0 && matrix[3]>0){ //180 degrees  (origin now top right)
                    g2.transform(AffineTransform.getScaleInstance(-1, 1));
                    
                    g2.drawString("hello world", -560,60);//subtract cropW from first number to use standard values
                    
                }else if(matrix[1]<0 && matrix[2]<0){ //270
                    
                    g2.transform(AffineTransform.getScaleInstance(-1, 1));
                    g2.transform(AffineTransform.getRotateInstance(-90 *Math.PI/180));
                    
                    //BOTH X and Y NEGATIVE!!!!
                    g2.drawString("hello world", -560,-60); //subtract CropW and CropH if you want standard values
                }else{ //0 degress
                    g2.transform(AffineTransform.getScaleInstance(1, -1));
                    // X ONLY POSITIVE!!!!
                    g2.drawString("hello world", 60,-60);
                }
                
                //restore!!!
                g2.setTransform(aff);
            }
            
            /**/
        }

        @Override
        public void setVisible(final boolean isVisible) {
            this.isVisible = isVisible;
        }

        @Override
        public void setMedX(final int medX) {
            this.medX = medX;
        }

        @Override
        public void setMedY(final int medY) {
            this.medY = medY;
        }
    }
}