/*
 * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.swing.text.html;

import java.awt.*;
import java.util.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;

import sun.swing.text.html.FrameEditorPaneTag;

/**
 * Implements a FrameView, intended to support the HTML
 * &lt;FRAME&gt; tag.  Supports the frameborder, scrolling,
 * marginwidth and marginheight attributes.
 *
 * @author    Sunita Mani
 */

class FrameView extends ComponentView implements HyperlinkListener {


    JEditorPane htmlPane;
    JScrollPane scroller;
    boolean editable;
    float width;
    float height;
    URL src;
    /** Set to true when the component has been created. */
    private boolean createdComponent;

    /**
     * Creates a new Frame.
     *
     * @param elem the element to represent.
     */
    public FrameView(Element elem) {
        super(elem);
    }

    protected Component createComponent() {

        Element elem = getElement();
        AttributeSet attributes = elem.getAttributes();
        String srcAtt = (String)attributes.getAttribute(HTML.Attribute.SRC);

        if ((srcAtt != null) && (!srcAtt.equals(""))) {
            try {
                URL base = ((HTMLDocument)elem.getDocument()).getBase();
                src = new URL(base, srcAtt);
                htmlPane = new FrameEditorPane();
                htmlPane.addHyperlinkListener(this);
                JEditorPane host = getHostPane();
                boolean isAutoFormSubmission = true;
                if (host != null) {
                    htmlPane.setEditable(host.isEditable());
                    String charset = (String) host.getClientProperty("charset");
                    if (charset != null) {
                        htmlPane.putClientProperty("charset", charset);
                    }
                    HTMLEditorKit hostKit = (HTMLEditorKit)host.getEditorKit();
                    if (hostKit != null) {
                        isAutoFormSubmission = hostKit.isAutoFormSubmission();
                    }
                }
                htmlPane.setPage(src);
                HTMLEditorKit kit = (HTMLEditorKit)htmlPane.getEditorKit();
                if (kit != null) {
                    kit.setAutoFormSubmission(isAutoFormSubmission);
                }

                Document doc = htmlPane.getDocument();
                if (doc instanceof HTMLDocument) {
                    ((HTMLDocument)doc).setFrameDocumentState(true);
                }
                setMargin();
                createScrollPane();
                setBorder();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        createdComponent = true;
        return scroller;
    }

    JEditorPane getHostPane() {
        Container c = getContainer();
        while ((c != null) && ! (c instanceof JEditorPane)) {
            c = c.getParent();
        }
        return (JEditorPane) c;
    }


    /**
     * Sets the parent view for the FrameView.
     * Also determines if the FrameView should be editable
     * or not based on whether the JTextComponent that
     * contains it is editable.
     *
     * @param parent View
     */
    public void setParent(View parent) {
        if (parent != null) {
            JTextComponent t = (JTextComponent)parent.getContainer();
            editable = t.isEditable();
        }
        super.setParent(parent);
    }


    /**
     * Also determines if the FrameView should be editable
     * or not based on whether the JTextComponent that
     * contains it is editable. And then proceeds to call
     * the superclass to do the paint().
     *
     * @param parent View
     * @see text.ComponentView#paint
     */
    public void paint(Graphics g, Shape allocation) {

        Container host = getContainer();
        if (host != null && htmlPane != null &&
            htmlPane.isEditable() != ((JTextComponent)host).isEditable()) {
            editable = ((JTextComponent)host).isEditable();
            htmlPane.setEditable(editable);
        }
        super.paint(g, allocation);
    }


    /**
     * If the marginwidth or marginheight attributes have been specified,
     * then the JEditorPane's margin's are set to the new values.
     */
    private void setMargin() {
        int margin = 0;
        Insets in = htmlPane.getMargin();
        Insets newInsets;
        boolean modified = false;
        AttributeSet attributes = getElement().getAttributes();
        String marginStr = (String)attributes.getAttribute(HTML.Attribute.MARGINWIDTH);
        if ( in != null) {
            newInsets = new Insets(in.top, in.left, in.right, in.bottom);
        } else {
            newInsets = new Insets(0,0,0,0);
        }
        if (marginStr != null) {
            margin = Integer.parseInt(marginStr);
            if (margin > 0) {
                newInsets.left = margin;
                newInsets.right = margin;
                modified = true;
            }
        }
        marginStr = (String)attributes.getAttribute(HTML.Attribute.MARGINHEIGHT);
        if (marginStr != null) {
            margin = Integer.parseInt(marginStr);
            if (margin > 0) {
                newInsets.top = margin;
                newInsets.bottom = margin;
                modified = true;
            }
        }
        if (modified) {
            htmlPane.setMargin(newInsets);
        }
    }

    /**
     * If the frameborder attribute has been specified, either in the frame,
     * or by the frames enclosing frameset, the JScrollPane's setBorder()
     * method is invoked to achieve the desired look.
     */
    private void setBorder() {

        AttributeSet attributes = getElement().getAttributes();
        String frameBorder = (String)attributes.getAttribute(HTML.Attribute.FRAMEBORDER);
        if ((frameBorder != null) &&
            (frameBorder.equals("no") || frameBorder.equals("0"))) {
            // make invisible borders.
            scroller.setBorder(null);
        }
    }


    /**
     * This method creates the JScrollPane.  The scrollbar policy is determined by
     * the scrolling attribute.  If not defined, the default is "auto" which
     * maps to the scrollbar's being displayed as needed.
     */
    private void createScrollPane() {
        AttributeSet attributes = getElement().getAttributes();
        String scrolling = (String)attributes.getAttribute(HTML.Attribute.SCROLLING);
        if (scrolling == null) {
            scrolling = "auto";
        }

        if (!scrolling.equals("no")) {
            if (scrolling.equals("yes")) {
                scroller = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                           JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
            } else {
                // scrollbars will be displayed if needed
                //
                scroller = new JScrollPane();
            }
        } else {
            scroller = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_NEVER,
                                       JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        }

        JViewport vp = scroller.getViewport();
        vp.add(htmlPane);
        vp.setBackingStoreEnabled(true);
        scroller.setMinimumSize(new Dimension(5,5));
        scroller.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
    }


    /**
     * Finds the outermost FrameSetView.  It then
     * returns that FrameSetView's container.
     */
    JEditorPane getOutermostJEditorPane() {

        View parent = getParent();
        FrameSetView frameSetView = null;
        while (parent != null) {
            if (parent instanceof FrameSetView) {
                frameSetView = (FrameSetView)parent;
            }
            parent = parent.getParent();
        }
        if (frameSetView != null) {
            return (JEditorPane)frameSetView.getContainer();
        }
        return null;
    }


    /**
     * Returns true if this frame is contained within
     * a nested frameset.
     */
    private boolean inNestedFrameSet() {
        FrameSetView parent = (FrameSetView)getParent();
        return (parent.getParent() instanceof FrameSetView);
    }


    /**
     * Notification of a change relative to a
     * hyperlink. This method searches for the outermost
     * JEditorPane, and then fires an HTMLFrameHyperlinkEvent
     * to that frame.  In addition, if the target is _parent,
     * and there is not nested framesets then the target is
     * reset to _top.  If the target is _top, in addition to
     * firing the event to the outermost JEditorPane, this
     * method also invokes the setPage() method and explicitly
     * replaces the current document with the destination url.
     *
     * @param HyperlinkEvent
     */
    public void hyperlinkUpdate(HyperlinkEvent evt) {

        JEditorPane c = getOutermostJEditorPane();
        if (c == null) {
            return;
        }

        if (!(evt instanceof HTMLFrameHyperlinkEvent)) {
            c.fireHyperlinkUpdate(evt);
            return;
        }

        HTMLFrameHyperlinkEvent e = (HTMLFrameHyperlinkEvent)evt;

        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
            String target = e.getTarget();
            String postTarget = target;

            if (target.equals("_parent") && !inNestedFrameSet()){
                target = "_top";
            }

            if (evt instanceof FormSubmitEvent) {
                HTMLEditorKit kit = (HTMLEditorKit)c.getEditorKit();
                if (kit != null && kit.isAutoFormSubmission()) {
                    if (target.equals("_top")) {
                        try {
                            movePostData(c, postTarget);
                            c.setPage(e.getURL());
                        } catch (IOException ex) {
                            // Need a way to handle exceptions
                        }
                    } else {
                        HTMLDocument doc = (HTMLDocument)c.getDocument();
                        doc.processHTMLFrameHyperlinkEvent(e);
                    }
                } else {
                    c.fireHyperlinkUpdate(evt);
                }
                return;
            }

            if (target.equals("_top")) {
                try {
                    c.setPage(e.getURL());
                } catch (IOException ex) {
                    // Need a way to handle exceptions
                    // ex.printStackTrace();
                }
            }
            if (!c.isEditable()) {
                c.fireHyperlinkUpdate(new HTMLFrameHyperlinkEvent(c,
                                                                  e.getEventType(),
                                                                  e.getURL(),
                                                                  e.getDescription(),
                                                                  getElement(),
                                                                  e.getInputEvent(),
                                                                  target));
            }
        }
    }

    /**
     * Gives notification from the document that attributes were changed
     * in a location that this view is responsible for.  Currently this view
     * handles changes to its SRC attribute.
     *
     * @param e the change information from the associated document
     * @param a the current allocation of the view
     * @param f the factory to use to rebuild if the view has children
     *
     */
    public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {

        Element elem = getElement();
        AttributeSet attributes = elem.getAttributes();

        URL oldPage = src;

        String srcAtt = (String)attributes.getAttribute(HTML.Attribute.SRC);
        URL base = ((HTMLDocument)elem.getDocument()).getBase();
        try {
            if (!createdComponent) {
                return;
            }

            Object postData = movePostData(htmlPane, null);
            src = new URL(base, srcAtt);
            if (oldPage.equals(src) && (src.getRef() == null) && (postData == null)) {
                return;
            }

            htmlPane.setPage(src);
            Document newDoc = htmlPane.getDocument();
            if (newDoc instanceof HTMLDocument) {
                ((HTMLDocument)newDoc).setFrameDocumentState(true);
            }
        } catch (MalformedURLException e1) {
            // Need a way to handle exceptions
            //e1.printStackTrace();
        } catch (IOException e2) {
            // Need a way to handle exceptions
            //e2.printStackTrace();
        }
    }

    /**
     * Move POST data from temporary storage into the target document property.
     *
     * @return the POST data or null if no data found
     */
    private Object movePostData(JEditorPane targetPane, String frameName) {
        Object postData = null;
        JEditorPane p = getOutermostJEditorPane();
        if (p != null) {
            if (frameName == null) {
                frameName = (String) getElement().getAttributes().getAttribute(
                        HTML.Attribute.NAME);
            }
            if (frameName != null) {
                String propName = FormView.PostDataProperty + "." + frameName;
                Document d = p.getDocument();
                postData = d.getProperty(propName);
                if (postData != null) {
                    targetPane.getDocument().putProperty(
                            FormView.PostDataProperty, postData);
                    d.putProperty(propName, null);
                }
            }
        }

        return postData;
    }

    /**
     * Determines the minimum span for this view along an
     * axis.
     *
     * @param axis may be either <code>View.X_AXIS</code> or
     *  <code>View.Y_AXIS</code>
     * @return the preferred span; given that we do not
     * support resizing of frames, the minimum span returned
     * is the same as the preferred span
     *
     */
    public float getMinimumSpan(int axis) {
      return 5;
    }

    /**
     * Determines the maximum span for this view along an
     * axis.
     *
     * @param axis may be either <code>View.X_AXIS</code> or
     *  <code>View.Y_AXIS</code>
     * @return the preferred span; given that we do not
     * support resizing of frames, the maximum span returned
     * is the same as the preferred span
     *
     */
    public float getMaximumSpan(int axis) {
        return Integer.MAX_VALUE;
    }

    /** Editor pane rendering frame of HTML document
     *  It uses the same editor kits classes as outermost JEditorPane
     */
    class FrameEditorPane extends JEditorPane implements FrameEditorPaneTag {
        public EditorKit getEditorKitForContentType(String type) {
            EditorKit editorKit = super.getEditorKitForContentType(type);
            JEditorPane outerMostJEditorPane = null;
            if ((outerMostJEditorPane = getOutermostJEditorPane()) != null) {
                EditorKit inheritedEditorKit = outerMostJEditorPane.getEditorKitForContentType(type);
                if (! editorKit.getClass().equals(inheritedEditorKit.getClass())) {
                    editorKit = (EditorKit) inheritedEditorKit.clone();
                    setEditorKitForContentType(type, editorKit);
                }
            }
            return editorKit;
        }

        FrameView getFrameView() {
            return FrameView.this;
        }
    }
}
