/*
 * 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.filterfw.core;

import android.annotation.UnsupportedAppUsage;
import android.filterfw.core.FrameFormat;
import android.filterfw.core.FrameManager;
import android.graphics.Bitmap;

import java.nio.ByteBuffer;

/**
 * @hide
 */
public abstract class Frame {

    public final static int NO_BINDING = 0;

    public final static long TIMESTAMP_NOT_SET = -2;
    public final static long TIMESTAMP_UNKNOWN = -1;

    private FrameFormat mFormat;
    private FrameManager mFrameManager;
    private boolean mReadOnly = false;
    private boolean mReusable = false;
    private int mRefCount = 1;
    private int mBindingType = NO_BINDING;
    private long mBindingId = 0;
    private long mTimestamp = TIMESTAMP_NOT_SET;

    Frame(FrameFormat format, FrameManager frameManager) {
        mFormat = format.mutableCopy();
        mFrameManager = frameManager;
    }

    Frame(FrameFormat format, FrameManager frameManager, int bindingType, long bindingId) {
        mFormat = format.mutableCopy();
        mFrameManager = frameManager;
        mBindingType = bindingType;
        mBindingId = bindingId;
    }

    @UnsupportedAppUsage
    public FrameFormat getFormat() {
        return mFormat;
    }

    public int getCapacity() {
        return getFormat().getSize();
    }

    public boolean isReadOnly() {
        return mReadOnly;
    }

    public int getBindingType() {
        return mBindingType;
    }

    public long getBindingId() {
        return mBindingId;
    }

    public void setObjectValue(Object object) {
        assertFrameMutable();

        // Attempt to set the value using a specific setter (which may be more optimized), and
        // fall back to the setGenericObjectValue(...) in case of no match.
        if (object instanceof int[]) {
            setInts((int[])object);
        } else if (object instanceof float[]) {
            setFloats((float[])object);
        } else if (object instanceof ByteBuffer) {
            setData((ByteBuffer)object);
        } else if (object instanceof Bitmap) {
            setBitmap((Bitmap)object);
        } else {
            setGenericObjectValue(object);
        }
    }

    public abstract Object getObjectValue();

    @UnsupportedAppUsage
    public abstract void setInts(int[] ints);

    public abstract int[] getInts();

    public abstract void setFloats(float[] floats);

    public abstract float[] getFloats();

    public abstract void setData(ByteBuffer buffer, int offset, int length);

    public void setData(ByteBuffer buffer) {
        setData(buffer, 0, buffer.limit());
    }

    public void setData(byte[] bytes, int offset, int length) {
        setData(ByteBuffer.wrap(bytes, offset, length));
    }

    public abstract ByteBuffer getData();

    public abstract void setBitmap(Bitmap bitmap);

    @UnsupportedAppUsage
    public abstract Bitmap getBitmap();

    @UnsupportedAppUsage
    public void setTimestamp(long timestamp) {
        mTimestamp = timestamp;
    }

    @UnsupportedAppUsage
    public long getTimestamp() {
        return mTimestamp;
    }

    public void setDataFromFrame(Frame frame) {
        setData(frame.getData());
    }

    protected boolean requestResize(int[] newDimensions) {
        return false;
    }

    public int getRefCount() {
        return mRefCount;
    }

    @UnsupportedAppUsage
    public Frame release() {
        if (mFrameManager != null) {
            return mFrameManager.releaseFrame(this);
        } else {
            return this;
        }
    }

    public Frame retain() {
        if (mFrameManager != null) {
            return mFrameManager.retainFrame(this);
        } else {
            return this;
        }
    }

    public FrameManager getFrameManager() {
        return mFrameManager;
    }

    protected void assertFrameMutable() {
        if (isReadOnly()) {
            throw new RuntimeException("Attempting to modify read-only frame!");
        }
    }

    protected void setReusable(boolean reusable) {
        mReusable = reusable;
    }

    protected void setFormat(FrameFormat format) {
        mFormat = format.mutableCopy();
    }

    protected void setGenericObjectValue(Object value) {
        throw new RuntimeException(
            "Cannot set object value of unsupported type: " + value.getClass());
    }

    protected static Bitmap convertBitmapToRGBA(Bitmap bitmap) {
        if (bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
            return bitmap;
        } else {
            Bitmap result = bitmap.copy(Bitmap.Config.ARGB_8888, false);
            if (result == null) {
                throw new RuntimeException("Error converting bitmap to RGBA!");
            } else if (result.getRowBytes() != result.getWidth() * 4) {
                throw new RuntimeException("Unsupported row byte count in bitmap!");
            }
            return result;
        }
    }

    protected void reset(FrameFormat newFormat) {
        mFormat = newFormat.mutableCopy();
        mReadOnly = false;
        mRefCount = 1;
    }

    /**
     * Called just before a frame is stored, such as when storing to a cache or context.
     */
    protected void onFrameStore() {
    }

    /**
     * Called when a frame is fetched from an internal store such as a cache.
     */
    protected void onFrameFetch() {
    }

    // Core internal methods ///////////////////////////////////////////////////////////////////////
    protected abstract boolean hasNativeAllocation();

    protected abstract void releaseNativeAllocation();

    final int incRefCount() {
        ++mRefCount;
        return mRefCount;
    }

    final int decRefCount() {
        --mRefCount;
        return mRefCount;
    }

    final boolean isReusable() {
        return mReusable;
    }

    final void markReadOnly() {
        mReadOnly = true;
    }

}
