/*
 * 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.felix.example.extenderbased.host;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import javax.swing.ImageIcon;
import org.apache.felix.example.extenderbased.host.extension.SimpleShape;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/**
 * This class is used as a proxy to defer object creation from shape
 * provider bundles and also as a placeholder shape when previously
 * used shapes are no longer available. These two purposes are
 * actually orthogonal, but were combined into a single class to
 * reduce the number of classes in the application. The proxy-related
 * functionality is introduced as a way to lazily create shape
 * objects in an effort to improve performance; this level of
 * indirection could be removed if eager creation of objects is not
 * a concern.
**/
class DefaultShape implements SimpleShape
{
    private SimpleShape m_shape;
    private ImageIcon m_icon;
    private BundleContext m_context;
    private long m_bundleId;
    private String m_className;

    /**
     * This constructs a placeholder shape that draws a default
     * icon. It is used when a previously drawn shape is no longer
     * available.
    **/
    public DefaultShape()
    {
        // Do nothing.
    }

    /**
     * This constructs a proxy shape that lazily instantiates the
     * shape class from the associated extension bundle.
     * @param context The bundle context to use for retrieving the extension bundle.
     * @param bundleId The bundle ID of the extension bundle.
     * @param className The class name of the shape.
    **/
    public DefaultShape(BundleContext context, long bundleId, String className)
    {
        m_context = context;
        m_bundleId = bundleId;
        m_className = className;
    }

    /**
     * Implements the <tt>SimpleShape</tt> interface method. When acting as
     * a proxy, this method lazily loads and instantiates the shape class and
     * then uses it to draw the shape. When acting as a placeholder shape,
     * this method draws the default icon.
     * @param g2 The graphics object used for painting.
     * @param p The position to paint the triangle.
    **/
    public void draw(Graphics2D g2, Point p)
    {
        // If this is a proxy shape, instantiate the shape class
        // and use it to draw the shape.
        if (m_context != null)
        {
            try
            {
                if (m_shape == null)
                {
                    // Get the bundle.
                    Bundle bundle = m_context.getBundle(m_bundleId);
                    // Load the class and instantiate it.
                    Class<?> clazz = bundle.loadClass(m_className);
                    m_shape = (SimpleShape) clazz.newInstance();
                }
                // Draw the shape.
                m_shape.draw(g2, p);
                // If everything was successful, then simply return.
                return;
            }
            catch (Exception ex)
            {
                // This generally should not happen, but if it does then
                // we can just fall through and paint the default icon.
            }
        }

        // If the proxied shape could not be drawn for any reason or if
        // this shape is simply a placeholder, then draw the default icon.
        if (m_icon == null)
        {
            try
            {
                m_icon = new ImageIcon(this.getClass().getResource("underc.png"));
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
                g2.setColor(Color.red);
                g2.fillRect(0, 0, 60, 60);
                return;
            }
        }
        g2.drawImage(m_icon.getImage(), 0, 0, null);
    }
}