/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.examples.hssf.usermodel;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.RenderingHints;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.EscherGraphics;
import org.apache.poi.hssf.usermodel.EscherGraphics2d;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFShapeGroup;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

/**
 * Demonstrates the use of the EscherGraphics2d library.
 *
 * @author Glen Stampoultzis (glens at apache.org)
 */
public class OfficeDrawingWithGraphics {
    public static void main( String[] args ) throws IOException {
        // Create a workbook with one sheet and size the first three somewhat
        // larger so we can fit the chemical structure diagram in.
        try (HSSFWorkbook wb = new HSSFWorkbook()) {
            HSSFSheet sheet = wb.createSheet("my drawing");
            sheet.setColumnWidth(1, 256 * 27);
            HSSFRow row1 = sheet.createRow(0);
            row1.setHeightInPoints(10 * 15f);
            HSSFRow row2 = sheet.createRow(1);
            row2.setHeightInPoints(5 * 15f);
            HSSFRow row3 = sheet.createRow(2);
            row3.setHeightInPoints(10 * 15f);

            // Add some cells so we can test that the anchoring works when we
            // sort them.
            row1.createCell(0).setCellValue("C");
            row2.createCell(0).setCellValue("A");
            row3.createCell(0).setCellValue("B");

            // Create the top level drawing patriarch.
            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();

            HSSFClientAnchor a;
            HSSFShapeGroup group;
            EscherGraphics g;
            EscherGraphics2d g2d;
            // Anchor entirely within one cell.
            a = new HSSFClientAnchor(0, 0, 1023, 255, (short) 1, 0, (short) 1, 0);
            group = patriarch.createGroup(a);
            group.setCoordinates(0, 0, 320, 276);
            float verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / Math.abs(group.getY2() - group.getY1());
            g = new EscherGraphics(group, wb, Color.black, verticalPointsPerPixel);
            g2d = new EscherGraphics2d(g);
            drawStar(g2d);

            a = new HSSFClientAnchor(0, 0, 1023, 255, (short) 1, 1, (short) 1, 1);
            group = patriarch.createGroup(a);
            group.setCoordinates(0, 0, 640, 276);
            verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / Math.abs(group.getY2() - group.getY1());
//        verticalPixelsPerPoint = (float)Math.abs(group.getY2() - group.getY1()) / a.getAnchorHeightInPoints(sheet);
            g = new EscherGraphics(group, wb, Color.black, verticalPointsPerPixel);
            g2d = new EscherGraphics2d(g);
            drawStar(g2d);

            try (FileOutputStream out = new FileOutputStream("workbook.xls")) {
                wb.write(out);
            }
        }
    }

    private static void drawStar( EscherGraphics2d g2d )
    {
        g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
        for (double i = 0; i < Math.PI; i += 0.1)
        {
            g2d.setColor( new Color((int)(i * 5343062d) ) );
            int x1 = (int) ( Math.cos(i) * 160.0 ) + 160;
            int y1 = (int) ( Math.sin(i) * 138.0 ) + 138;
            int x2 = (int) ( -Math.cos(i) * 160.0 ) + 160;
            int y2 = (int) ( -Math.sin(i) * 138.0 ) + 138;
            g2d.setStroke(new BasicStroke(2));
            g2d.drawLine(x1,y1,x2,y2);
        }
        g2d.setFont(new Font("SansSerif",Font.BOLD | Font.ITALIC, 20));
        g2d.drawString("EscherGraphics2d",70,100);
        g2d.setColor(Color.yellow);
        g2d.fillOval( 160-20,138-20,40,40);
        g2d.setColor(Color.black);
        g2d.fillPolygon(new int[] {-10+160,0+160,10+160,0+160}, new int[] {0+138,10+138,0+138,-10+138}, 4);
        g2d.drawPolygon(new int[] {-160+160,0+160,160+160,0+160}, new int[] {0+138,138+138,0+138,-138+138}, 4);
    }
}
