/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.bebop;

import com.arsdigita.xml.Element;

import com.arsdigita.util.Assert;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.event.PrintEvent;

/**
 * A simple wrapper class for images.
 *
 * @author David Lutterkort 
 * @author Stanislav Freidin 
 *
 * @version $Id: //core-platform/dev/src/com/arsdigita/bebop/Image.java#8 $
 */

public class Image extends BlockStylable  {

    public static final String versionId = "$Id: //core-platform/dev/src/com/arsdigita/bebop/Image.java#8 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";
    private final String IMAGE_URL = "src";
    private final String ALT       = "alt";
    private final String HEIGHT    = "height";
    private final String WIDTH     = "width";
    private final String BORDER    = "border";

    private PrintListener m_printListener;

    public Image(String imageURL, String alt) {
        super();
        setImageURL(imageURL);
        setAlt(alt);
    }

    public Image(String imageURL) {
        this(imageURL, "");
    }

    /**
     * Creates a new <code>Image</code> that uses the print listener
     * to generate output.
     *
     * @param l the print listener used to produce output
     */
    public Image(PrintListener l) {
        this("");
        addPrintListener(l);
    }

    public void setImageURL(String imageURL) {
        Assert.assertNotLocked(this);
        setAttribute(IMAGE_URL, imageURL);
    }

    public void setAlt(String alt) {
        Assert.assertNotLocked(this);
        setAttribute(ALT, alt);
    }
    /**
     * 
     *
     */
    public void setHeight(String height) {
        Assert.assertNotLocked(this);
        setAttribute(HEIGHT, height);
    }

    /**
     * 
     *
     */
    public void setWidth(String width) {
        Assert.assertNotLocked(this);
        setAttribute(WIDTH, width);
    }

    /**
     * 
     *
     */
    public void setBorder(String border) {
        Assert.assertNotLocked(this);
        setAttribute(BORDER, border);
    }

    /**
     * Adds a print listener. Only one print listener can be set for an
     * image, since the <code>PrintListener</code> is expected to modify the
     * target of the <code>PrintEvent</code>.
     * @param listener the print listener
     * @throws IlegalArgumentException if <code>listener</code> is null.
     * @throws IllegalStateException if a print listener has previously been
     *         added.
     * @pre listener != null */
    public void addPrintListener(PrintListener listener)
        throws IllegalStateException, IllegalArgumentException
    {
        if ( listener == null ) {
            throw new IllegalArgumentException
                ("Argument listener can not be null");
        }
        if ( m_printListener != null ) {
            throw new IllegalStateException
                ("Too many listeners. Can only have one");
        }
        m_printListener = listener;
    }

    /**
     * Removes a previously added print listener. If <code>listener</code> is
     * not the listener that was added with {@link #addPrintListener
     * addPrintListener}, an IllegalArgumentException will be thrown.
     * @param listener the listener that was previously added with
     *      <code>addPrintListener</code>
     * @throws IllegalArgumentException if <code>listener</code> is not the
     *      currently registered print listener or is <code>null</code>.
     * @pre listener != null
     */
    public void removePrintListener(PrintListener listener)
        throws IllegalArgumentException
    {
        if ( listener == null ) {
            throw new IllegalArgumentException("listener can not be null");
        }
        if ( listener != m_printListener ) {
            throw new IllegalArgumentException
                ("listener is not registered with this widget");
        }
        m_printListener = null;
    }

    /**
     * Writes the output to a DOM to be used with the XSLT template
     * to produce the appropriate output.
     *
     * <p>Generates DOM fragment:
     * <p><code><pre>
     * &lt;bebop:image [src=...] [alt=...] [height=...]
     *       [width=...] [border=...]/>
     * </pre></code>
     *
     * @param pageState the pageState used to determine values of form
     * widgets and page state attributes
     * @param parent the XML element to which the form adds its XML representation
     * */
    public void generateXML(PageState state, Element parent) {

        if ( ! isVisible(state) ) {
            return;
        }

        Image target = firePrintEvent(state);
        Element image = parent.newChildElement ("bebop:image", BEBOP_XML_NS);
        target.exportAttributes(image);
    }

    protected Image firePrintEvent(PageState state) {
        Image i = this;
        if ( m_printListener != null ) {
            try {
                i = (Image) this.clone();
                m_printListener.prepare(new PrintEvent(this, state, i));
            } catch ( CloneNotSupportedException e ) {
                // FIXME: Failing silently here isn't so great
                //   It probably indicates a serious programming error
                i = this;
            }
        }
        return i;
    }

}
