/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package odfdom.example1;

import java.io.File;
import java.io.FileInputStream;
import java.net.URI;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.odftoolkit.odfdom.doc.OdfDocument;
import org.odftoolkit.odfdom.doc.OdfFileDom;
import org.odftoolkit.odfdom.doc.OdfTextDocument;
import org.odftoolkit.odfdom.doc.element.OdfElementFactory;
import org.odftoolkit.odfdom.doc.element.draw.OdfFrame;
import org.odftoolkit.odfdom.doc.element.draw.OdfImage;
import org.odftoolkit.odfdom.doc.element.text.OdfParagraph;
import org.odftoolkit.odfdom.dom.OdfNamespace;
import org.odftoolkit.odfdom.dom.element.draw.OdfFrameElement;
import org.odftoolkit.odfdom.dom.element.draw.OdfImageElement;
import org.odftoolkit.odfdom.dom.element.text.OdfParagraphElement;
import org.odftoolkit.odfdom.dom.type.OdfAnyURI;
import org.odftoolkit.odfdom.pkg.OdfPackage;

/**
 * Solution for example 1 of the JavaOne ODFDOM lab
 */
public class RunExample1 {

	// Edit the lab root - it's the base directory for reading the input file
	private static final LAB_ROOT = <LAB_ROOT>";
    private static final Logger LOG = Logger.getLogger(RunExample1.class.getName());

    /**
     *  Executes the first lab exercise.
     * 
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            // 1st ODFDOM LAYER - PACKAGE / PHYSICAL LAYER:
            // Creating an ODF package containing an image not shown in the text
            firstExercicePart1();
        } catch (Exception ex) {
            LOG.log(Level.SEVERE, "Something weired happened in the first part..", ex);
        }

        try {
            // 2nd ODFDOM LAYER - TYPED DOM / XML LAYER:
            // Creating an ODF Text document showing the image from the package
            firstExercicePart2();
        } catch (Exception ex) {
            LOG.log(Level.SEVERE, "Something weired happened in the second part..", ex);
        }

        try {
            // 3rd ODFDOM LAYER - CONVENIENCE LAYER:
            // Quite similar to the previous DOM handling, as a DOC layer is always a child
            // of a DOM layer object therefore as well a DOM tree.
            //
            //
            // Two things are done for the user behind the scene:
            //
            // 1) The package handling to insert the image file
            //
            // 2) The default size is received from the image via AWT helper and
            // added to the attributes of the sourrounding draw:frame.
            firstExercicePart3();
        } catch (Exception ex) {
            LOG.log(Level.SEVERE, "Something weired happened in the third part..", ex);
        }
    }

    /**
     * 1st ODFDOM LAYER - PACKAGE / PHYSICAL LAYER:
     * Creating an ODF package containing an image not shown in the text
     *
     * @throws java.lang.Exception
     */
    private static void firstExercicePart1() throws Exception {
        // ODF KNOW-HOW: One ODF Package is only a zipped container for arbitrary files of some document.
        OdfPackage pkg = OdfPackage.loadPackage(LAB_ROOT + "/resources/e1-input.odt");
        // Inserting an image into the 'Pictures' directory within the ODF package.
        pkg.insert(new FileInputStream(LAB_ROOT + "/resources/e1-01_DukeToEmbed.png"),
                "Pictures/e1-01_DukeToEmbed.png");

        // Save the package with the picture; no path used here, will be stored in project root
        pkg.save("output_1_seems-empty.odt");
        // zip can be opened with NetBeans
        pkg.save("output_1_seems-empty.zip");

        // ODF-KNOW-HOW: Only images referenced from the text will be viewed in ODF.
        //              Therefore if the document is being opened (for instance with OpenOffice.org)
        //              The document appears to be empty.
        LOG.info("SUCCESS: You were able to save an ODF Package containing an image, which is not shown!");
    }

    /**
     * 2nd ODFDOM LAYER - TYPED DOM / XML LAYER
     * Creating an ODF Text document showing the image from the package
     *
     * @throws java.lang.Exception
     */
    private static void firstExercicePart2() throws Exception {
        // ODF-KNOW-HOW: An ODF Package contains one or more ODF Documents.
        //               The ODF XML elements part of an ODF Document.
        // Load the ODF Package as an ODF Document.
        OdfDocument odfDoc = OdfDocument.loadDocument("output_1_seems-empty.odt");

        // Get the ODF XML content as DOM tree representation.
        OdfFileDom odfContent = odfDoc.getContentDom();

        // ODF KNOW-HOW: The element name of a paragraph is <text:p>
        // Receiving the first paragraph  "//text:p[1]" (using XPath functionality from JDK).
        XPath xpath = getXPathForODF();
        OdfParagraphElement para = (OdfParagraphElement) xpath.evaluate("//text:p[1]", odfContent, XPathConstants.NODE);

        // ODF KNOW-HOW: An image consists always of a <draw:frame> parent and an embedded <draw:image> child.
        // Create the <draw:frame> ODF element.
        OdfFrameElement odfFrame = (OdfFrameElement) OdfElementFactory.createOdfElement(odfContent, OdfFrame.ELEMENT_NAME);

        // Add the created frame to the earlier found first paragraph.
        para.appendChild(odfFrame);

        // create the <draw:image> ODF element viewing the previous (Part1 )inserted image
        OdfImageElement odfImage = (OdfImageElement) OdfElementFactory.createOdfElement(odfContent, OdfImage.ELEMENT_NAME);

        // Add the created image to the earlier created frame.
        odfFrame.appendChild(odfImage);

        // setting the xlink:href attribute
        odfImage.setHref(new OdfAnyURI("Pictures/e1-01_DukeToEmbed.png"));

        // Save the document; no path used here, will be stored in project root
        odfDoc.save("output_2_image-visible-small.odt");
        // zip can be opened with NetBeans
        odfDoc.save("output_2_image-visible-small.zip");
        LOG.info("SUCCESS: You were able to save an ODF Document again, now showing the earlier added image (small)!!");

    }

    /**
     * 3rd ODFDOM LAYER - CONVENIENCE LAYER:
     * Quite similar to the previous DOM handling, as a DOC layer is always a child
     * of a DOM layer object therefore as well a DOM tree.
     *
     *
     * Two things are done for the user behind the scene:
     *
     * 1) The package handling to insert the image file
     * 
     * 2) The default size is received from the image via AWT helper and
     * added to the attributes of the sourrounding draw:frame.
     *
     * @throws java.lang.Exception
     */
    private static void firstExercicePart3() throws Exception {

        OdfTextDocument odfText = OdfTextDocument.createTextDocument();
        // Get the ODF XML content as DOM tree representation.
        OdfFileDom odfContent = odfText.getContentDom();

        // ODF KNOW-HOW: The element name of a paragraph is <text:p>
        // Receiving the first paragraph  "//text:p[1]" (using XPath functionality from JDK).
        XPath xpath = getXPathForODF();
        OdfParagraph para = (OdfParagraph) xpath.evaluate("//text:p[1]", odfContent, XPathConstants.NODE);

        // ODF KNOW-HOW: An image consists always of a <draw:frame> parent and an embedded <draw:image> child.
        // Create the <draw:frame> ODF element.
        OdfFrame odfFrame = (OdfFrame) OdfElementFactory.createOdfElement(odfContent, OdfFrame.ELEMENT_NAME);

        // Add the created frame to the earlier found first paragraph.
        para.appendChild(odfFrame);

        // create the <draw:image> ODF element to view the similar image file
        OdfImage odfImage = (OdfImage) OdfElementFactory.createOdfElement(odfContent, OdfImage.ELEMENT_NAME);

        // Add the created image to the earlier created frame.
        odfFrame.appendChild(odfImage);
        // NOTE: Loading the image (relativ to <LABROOT>/solution/solution1
        // Adding the image to the package, getting the default
        // size via AWT helper and setting the size at the draw:frame parent.
        odfImage.insertImage(new URI(LAB_ROOT + "/resources/e1-01_DukeToEmbed.png"));

        // Save the document; no path used here, will be stored in project root
        odfText.save("output_3_image-visible-big.odt");
        // zip can be opened with NetBeans
        odfText.save("output_3_image-visible-big.zip");
        LOG.info("SUCCESS: You were able to add an image into an ODF Text Document using the convenient API!!");


    }

    private RunExample1() {
    }
    private static XPath mXPath;

    private static XPath getXPathForODF() {
        if (mXPath == null) {
            // W3C XPath initialization (i.e. JDK5 functionality)  -
            // XPath is the path within the XML file
            mXPath = XPathFactory.newInstance().newXPath();
            mXPath.setNamespaceContext(new OdfNamespace());
        }
        return mXPath;
    }
}
