/* ====================================================================
   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.hwmf;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import javax.imageio.ImageIO;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.poi.POIDataSamples;
import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
import org.apache.poi.hwmf.record.HwmfFont;
import org.apache.poi.hwmf.record.HwmfRecord;
import org.apache.poi.hwmf.record.HwmfRecordType;
import org.apache.poi.hwmf.record.HwmfText;
import org.apache.poi.hwmf.usermodel.HwmfPicture;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.Units;
import org.junit.Ignore;
import org.junit.Test;

public class TestHwmfParsing {
    @Test
    public void parse() throws IOException {
        File f = POIDataSamples.getSlideShowInstance().getFile("santa.wmf");
        FileInputStream fis = new FileInputStream(f);
        HwmfPicture wmf = new HwmfPicture(fis);
        fis.close();
        List<HwmfRecord> records = wmf.getRecords();
        assertEquals(581, records.size());
    }
    
    @Test
    @Ignore("This is work-in-progress and not a real unit test ...")
    public void paint() throws IOException {
        File f = POIDataSamples.getSlideShowInstance().getFile("santa.wmf");
        // File f = new File("bla.wmf");
        FileInputStream fis = new FileInputStream(f);
        HwmfPicture wmf = new HwmfPicture(fis);
        fis.close();
        
        Dimension dim = wmf.getSize();
        int width = Units.pointsToPixel(dim.getWidth());
        // keep aspect ratio for height
        int height = Units.pointsToPixel(dim.getHeight());
        double max = Math.max(width, height);
        if (max > 1500) {
            width *= 1500/max;
            height *= 1500/max;
        }
        
        BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = bufImg.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        
        wmf.draw(g, new Rectangle2D.Double(0,0,width,height));

        g.dispose();
        
        ImageIO.write(bufImg, "PNG", new File("bla.png"));
    }

    @Test
    @Ignore("This is work-in-progress and not a real unit test ...")
    public void fetchWmfFromGovdocs() throws IOException {
        URL url = new URL("http://digitalcorpora.org/corpora/files/govdocs1/by_type/ppt.zip");
        File outdir = new File("build/ppt");
        outdir.mkdirs();
        ZipInputStream zis = new ZipInputStream(url.openStream());
        ZipEntry ze;
        while ((ze = zis.getNextEntry()) != null) {
            String basename = ze.getName().replaceAll(".*?([^/]+)\\.wmf", "$1");
            FilterInputStream fis = new FilterInputStream(zis){
                @Override
                public void close() throws IOException {}
            };
            try {
                SlideShow<?,?> ss = SlideShowFactory.create(fis);
                int wmfIdx = 1;
                for (PictureData pd : ss.getPictureData()) {
                    if (pd.getType() != PictureType.WMF) continue;
                    byte wmfData[] = pd.getData();
                    String filename = String.format(Locale.ROOT, "%s-%04d.wmf", basename, wmfIdx);
                    FileOutputStream fos = new FileOutputStream(new File(outdir, filename));
                    fos.write(wmfData);
                    fos.close();
                    wmfIdx++;
                }
                ss.close();
            } catch (Exception e) {
                System.out.println(ze.getName()+" ignored.");
            }
        }
    }

    @Test
    @Ignore("This is work-in-progress and not a real unit test ...")
    public void parseWmfs() throws IOException {
        // parse and render the extracted wmfs from the fetchWmfFromGovdocs step
        boolean outputFiles = false;
        boolean renderWmf = true;
        File indir = new File("E:\\project\\poi\\misc\\govdocs-ppt");
        File outdir = new File("build/wmf");
        outdir.mkdirs();
        final String startFile = "";
        File files[] = indir.listFiles(new FileFilter() {
            boolean foundStartFile = false;
            @Override
            public boolean accept(File pathname) {
                foundStartFile |= startFile.isEmpty() || pathname.getName().contains(startFile);
                return foundStartFile && pathname.getName().matches("(?i).*\\.wmf?$");
            }
        });
        for (File f : files) {
            try {
                String basename = f.getName().replaceAll(".*?([^/]+)\\.wmf", "$1");
                FileInputStream fis = new FileInputStream(f);
                HwmfPicture wmf = new HwmfPicture(fis);
                fis.close();
                
                int bmpIndex = 1;
                for (HwmfRecord r : wmf.getRecords()) {
                    if (r instanceof HwmfImageRecord) {
                        BufferedImage bi = ((HwmfImageRecord)r).getImage();
                        if (bi != null && outputFiles) {
                            String filename = String.format(Locale.ROOT, "%s-%04d.png", basename, bmpIndex);
                            ImageIO.write(bi, "PNG", new File(outdir, filename));
                        }
                        bmpIndex++;
                    }
                }

                if (renderWmf) {
                    Dimension dim = wmf.getSize();
                    int width = Units.pointsToPixel(dim.getWidth());
                    // keep aspect ratio for height
                    int height = Units.pointsToPixel(dim.getHeight());
                    
                    BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                    Graphics2D g = bufImg.createGraphics();
                    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                    g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
                    
                    wmf.draw(g);

                    g.dispose();
                    
                    ImageIO.write(bufImg, "PNG", new File(outdir, basename+".png"));
                }
            } catch (Exception e) {
                System.out.println(f.getName()+" ignored.");                
            }
        }
    }

    @Test
    @Ignore("If we decide we can use common crawl file specified, we can turn this back on")
    public void testCyrillic() throws Exception {
        //TODO: move test file to framework and fix this
        File dir = new File("C:/somethingOrOther");
        File f = new File(dir, "ZMLH54SPLI76NQ7XMKVB7SMUJA2HTXTS-2.wmf");
        HwmfPicture wmf = new HwmfPicture(new FileInputStream(f));

        Charset charset = LocaleUtil.CHARSET_1252;
        StringBuilder sb = new StringBuilder();
        //this is pure hackery for specifying the font
        //this happens to work on this test file, but you need to
        //do what Graphics does by maintaining the stack, etc.!
        for (HwmfRecord r : wmf.getRecords()) {
            if (r.getRecordType().equals(HwmfRecordType.createFontIndirect)) {
                HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
                charset = (font.getCharSet().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharSet().getCharset();
            }
            if (r.getRecordType().equals(HwmfRecordType.extTextOut)) {
                HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
                sb.append(textOut.getText(charset)).append("\n");
            }
        }
        String txt = sb.toString();
        assertTrue(txt.contains("\u041E\u0431\u0449\u043E"));
        assertTrue(txt.contains("\u0411\u0430\u043B\u0430\u043D\u0441"));
    }

}
