/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed 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 android.media.effect;

import java.lang.reflect.Constructor;

/**
 * <p>The EffectFactory class defines the list of available Effects, and provides functionality to
 * inspect and instantiate them. Some effects may not be available on all platforms, so before
 * creating a certain effect, the application should confirm that the effect is supported on this
 * platform by calling {@link #isEffectSupported(String)}.</p>
 */
public class EffectFactory {

    private EffectContext mEffectContext;

    private final static String[] EFFECT_PACKAGES = {
        "android.media.effect.effects.",  // Default effect package
        ""                                // Allows specifying full class path
    };

    /** List of Effects */
    /**
     * <p>Copies the input texture to the output.</p>
     * <p>Available parameters: None</p>
     * @hide
     */
    public final static String EFFECT_IDENTITY = "IdentityEffect";

    /**
     * <p>Adjusts the brightness of the image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>brightness</code></td>
     *     <td>The brightness multiplier.</td>
     *     <td>Positive float. 1.0 means no change;
               larger values will increase brightness.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_BRIGHTNESS =
            "android.media.effect.effects.BrightnessEffect";

    /**
     * <p>Adjusts the contrast of the image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>contrast</code></td>
     *     <td>The contrast multiplier.</td>
     *     <td>Float. 1.0 means no change;
               larger values will increase contrast.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_CONTRAST =
            "android.media.effect.effects.ContrastEffect";

    /**
     * <p>Applies a fisheye lens distortion to the image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>scale</code></td>
     *     <td>The scale of the distortion.</td>
     *     <td>Float, between 0 and 1. Zero means no distortion.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_FISHEYE =
            "android.media.effect.effects.FisheyeEffect";

    /**
     * <p>Replaces the background of the input frames with frames from a
     * selected video.  Requires an initial learning period with only the
     * background visible before the effect becomes active. The effect will wait
     * until it does not see any motion in the scene before learning the
     * background and starting the effect.</p>
     *
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>source</code></td>
     *     <td>A URI for the background video to use. This parameter must be
     *         supplied before calling apply() for the first time.</td>
     *     <td>String, such as from
     *         {@link android.net.Uri#toString Uri.toString()}</td>
     * </tr>
     * </table>
     *
     * <p>If the update listener is set for this effect using
     * {@link Effect#setUpdateListener}, it will be called when the effect has
     * finished learning the background, with a null value for the info
     * parameter.</p>
     */
    public final static String EFFECT_BACKDROPPER =
            "android.media.effect.effects.BackDropperEffect";

    /**
     * <p>Attempts to auto-fix the image based on histogram equalization.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>scale</code></td>
     *     <td>The scale of the adjustment.</td>
     *     <td>Float, between 0 and 1. Zero means no adjustment, while 1 indicates the maximum
     *     amount of adjustment.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_AUTOFIX =
            "android.media.effect.effects.AutoFixEffect";

    /**
     * <p>Adjusts the range of minimal and maximal color pixel intensities.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>black</code></td>
     *     <td>The value of the minimal pixel.</td>
     *     <td>Float, between 0 and 1.</td>
     * </tr>
     * <tr><td><code>white</code></td>
     *     <td>The value of the maximal pixel.</td>
     *     <td>Float, between 0 and 1.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_BLACKWHITE =
            "android.media.effect.effects.BlackWhiteEffect";

    /**
     * <p>Crops an upright rectangular area from the image. If the crop region falls outside of
     * the image bounds, the results are undefined.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>xorigin</code></td>
     *     <td>The origin's x-value.</td>
     *     <td>Integer, between 0 and width of the image.</td>
     * </tr>
     * <tr><td><code>yorigin</code></td>
     *     <td>The origin's y-value.</td>
     *     <td>Integer, between 0 and height of the image.</td>
     * </tr>
     * <tr><td><code>width</code></td>
     *     <td>The width of the cropped image.</td>
     *     <td>Integer, between 1 and the width of the image minus xorigin.</td>
     * </tr>
     * <tr><td><code>height</code></td>
     *     <td>The height of the cropped image.</td>
     *     <td>Integer, between 1 and the height of the image minus yorigin.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_CROP =
            "android.media.effect.effects.CropEffect";

    /**
     * <p>Applies a cross process effect on image, in which the red and green channels are
     * enhanced while the blue channel is restricted.</p>
     * <p>Available parameters: None</p>
     */
    public final static String EFFECT_CROSSPROCESS =
            "android.media.effect.effects.CrossProcessEffect";

    /**
     * <p>Applies black and white documentary style effect on image..</p>
     * <p>Available parameters: None</p>
     */
    public final static String EFFECT_DOCUMENTARY =
            "android.media.effect.effects.DocumentaryEffect";


    /**
     * <p>Overlays a bitmap (with premultiplied alpha channel) onto the input image. The bitmap
     * is stretched to fit the input image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>bitmap</code></td>
     *     <td>The overlay bitmap.</td>
     *     <td>A non-null Bitmap instance.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_BITMAPOVERLAY =
            "android.media.effect.effects.BitmapOverlayEffect";

    /**
     * <p>Representation of photo using only two color tones.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>first_color</code></td>
     *     <td>The first color tone.</td>
     *     <td>Integer, representing an ARGB color with 8 bits per channel. May be created using
     *     {@link android.graphics.Color Color} class.</td>
     * </tr>
     * <tr><td><code>second_color</code></td>
     *     <td>The second color tone.</td>
     *     <td>Integer, representing an ARGB color with 8 bits per channel. May be created using
     *     {@link android.graphics.Color Color} class.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_DUOTONE =
            "android.media.effect.effects.DuotoneEffect";

    /**
     * <p>Applies back-light filling to the image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>strength</code></td>
     *     <td>The strength of the backlight.</td>
     *     <td>Float, between 0 and 1. Zero means no change.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_FILLLIGHT =
            "android.media.effect.effects.FillLightEffect";

    /**
     * <p>Flips image vertically and/or horizontally.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>vertical</code></td>
     *     <td>Whether to flip image vertically.</td>
     *     <td>Boolean</td>
     * </tr>
     * <tr><td><code>horizontal</code></td>
     *     <td>Whether to flip image horizontally.</td>
     *     <td>Boolean</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_FLIP =
            "android.media.effect.effects.FlipEffect";

    /**
     * <p>Applies film grain effect to image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>strength</code></td>
     *     <td>The strength of the grain effect.</td>
     *     <td>Float, between 0 and 1. Zero means no change.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_GRAIN =
            "android.media.effect.effects.GrainEffect";

    /**
     * <p>Converts image to grayscale.</p>
     * <p>Available parameters: None</p>
     */
    public final static String EFFECT_GRAYSCALE =
            "android.media.effect.effects.GrayscaleEffect";

    /**
     * <p>Applies lomo-camera style effect to image.</p>
     * <p>Available parameters: None</p>
     */
    public final static String EFFECT_LOMOISH =
            "android.media.effect.effects.LomoishEffect";

    /**
     * <p>Inverts the image colors.</p>
     * <p>Available parameters: None</p>
     */
    public final static String EFFECT_NEGATIVE =
            "android.media.effect.effects.NegativeEffect";

    /**
     * <p>Applies posterization effect to image.</p>
     * <p>Available parameters: None</p>
     */
    public final static String EFFECT_POSTERIZE =
            "android.media.effect.effects.PosterizeEffect";

    /**
     * <p>Removes red eyes on specified region.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>centers</code></td>
     *     <td>Multiple center points (x, y) of the red eye regions.</td>
     *     <td>An array of floats, where (f[2*i], f[2*i+1]) specifies the center of the i'th eye.
     *     Coordinate values are expected to be normalized between 0 and 1.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_REDEYE =
            "android.media.effect.effects.RedEyeEffect";

    /**
     * <p>Rotates the image. The output frame size must be able to fit the rotated version of
     * the input image. Note that the rotation snaps to a the closest multiple of 90 degrees.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>angle</code></td>
     *     <td>The angle of rotation in degrees.</td>
     *     <td>Integer value. This will be rounded to the nearest multiple of 90.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_ROTATE =
            "android.media.effect.effects.RotateEffect";

    /**
     * <p>Adjusts color saturation of image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>scale</code></td>
     *     <td>The scale of color saturation.</td>
     *     <td>Float, between -1 and 1. 0 means no change, while -1 indicates full desaturation,
     *     i.e. grayscale.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_SATURATE =
            "android.media.effect.effects.SaturateEffect";

    /**
     * <p>Converts image to sepia tone.</p>
     * <p>Available parameters: None</p>
     */
    public final static String EFFECT_SEPIA =
            "android.media.effect.effects.SepiaEffect";

    /**
     * <p>Sharpens the image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>scale</code></td>
     *     <td>The degree of sharpening.</td>
     *     <td>Float, between 0 and 1. 0 means no change.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_SHARPEN =
            "android.media.effect.effects.SharpenEffect";

    /**
     * <p>Rotates the image according to the specified angle, and crops the image so that no
     * non-image portions are visible.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>angle</code></td>
     *     <td>The angle of rotation.</td>
     *     <td>Float, between -45 and +45.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_STRAIGHTEN =
            "android.media.effect.effects.StraightenEffect";

    /**
     * <p>Adjusts color temperature of the image.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>scale</code></td>
     *     <td>The value of color temperature.</td>
     *     <td>Float, between 0 and 1, with 0 indicating cool, and 1 indicating warm. A value of
     *     of 0.5 indicates no change.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_TEMPERATURE =
            "android.media.effect.effects.ColorTemperatureEffect";

    /**
     * <p>Tints the photo with specified color.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>tint</code></td>
     *     <td>The color of the tint.</td>
     *     <td>Integer, representing an ARGB color with 8 bits per channel. May be created using
     *     {@link android.graphics.Color Color} class.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_TINT =
            "android.media.effect.effects.TintEffect";

    /**
     * <p>Adds a vignette effect to image, i.e. fades away the outer image edges.</p>
     * <p>Available parameters:</p>
     * <table>
     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
     * <tr><td><code>scale</code></td>
     *     <td>The scale of vignetting.</td>
     *     <td>Float, between 0 and 1. 0 means no change.</td>
     * </tr>
     * </table>
     */
    public final static String EFFECT_VIGNETTE =
            "android.media.effect.effects.VignetteEffect";

    EffectFactory(EffectContext effectContext) {
        mEffectContext = effectContext;
    }

    /**
     * Instantiate a new effect with the given effect name.
     *
     * <p>The effect's parameters will be set to their default values.</p>
     *
     * <p>Note that the EGL context associated with the current EffectContext need not be made
     * current when creating an effect. This allows the host application to instantiate effects
     * before any EGL context has become current.</p>
     *
     * @param effectName The name of the effect to create.
     * @return A new Effect instance.
     * @throws IllegalArgumentException if the effect with the specified name is not supported or
     *         not known.
     */
    public Effect createEffect(String effectName) {
        Class effectClass = getEffectClassByName(effectName);
        if (effectClass == null) {
            throw new IllegalArgumentException("Cannot instantiate unknown effect '" +
                effectName + "'!");
        }
        return instantiateEffect(effectClass, effectName);
    }

    /**
     * Check if an effect is supported on this platform.
     *
     * <p>Some effects may only be available on certain platforms. Use this method before
     * instantiating an effect to make sure it is supported.</p>
     *
     * @param effectName The name of the effect.
     * @return true, if the effect is supported on this platform.
     * @throws IllegalArgumentException if the effect name is not known.
     */
    public static boolean isEffectSupported(String effectName) {
        return getEffectClassByName(effectName) != null;
    }

    private static Class getEffectClassByName(String className) {
        Class effectClass = null;

        // Get context's classloader; otherwise cannot load non-framework effects
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

        // Look for the class in the imported packages
        for (String packageName : EFFECT_PACKAGES) {
            try {
                effectClass = contextClassLoader.loadClass(packageName + className);
            } catch (ClassNotFoundException e) {
                continue;
            }
            // Exit loop if class was found.
            if (effectClass != null) {
                break;
            }
        }
        return effectClass;
    }

    private Effect instantiateEffect(Class effectClass, String name) {
        // Make sure this is an Effect subclass
        try {
            effectClass.asSubclass(Effect.class);
        } catch (ClassCastException e) {
            throw new IllegalArgumentException("Attempting to allocate effect '" + effectClass
                + "' which is not a subclass of Effect!", e);
        }

        // Look for the correct constructor
        Constructor effectConstructor = null;
        try {
            effectConstructor = effectClass.getConstructor(EffectContext.class, String.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("The effect class '" + effectClass + "' does not have "
                + "the required constructor.", e);
        }

        // Construct the effect
        Effect effect = null;
        try {
            effect = (Effect)effectConstructor.newInstance(mEffectContext, name);
        } catch (Throwable t) {
            throw new RuntimeException("There was an error constructing the effect '" + effectClass
                + "'!", t);
        }

        return effect;
    }
}
