/*
 * Copyright (C) 2007 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.
 */

#define LOG_TAG "SurfaceFlinger"

#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>

#include <utils/Errors.h>
#include <utils/Log.h>

#include <core/SkBitmap.h>

#include <ui/EGLDisplaySurface.h>

#include "LayerBase.h"
#include "LayerOrientationAnim.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
#include "OrientationAnimation.h"

namespace android {
// ---------------------------------------------------------------------------

const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";

// ---------------------------------------------------------------------------

LayerOrientationAnim::LayerOrientationAnim(
        SurfaceFlinger* flinger, DisplayID display, 
        OrientationAnimation* anim, 
        const LayerBitmap& bitmap,
        const LayerBitmap& bitmapIn)
    : LayerBase(flinger, display), mAnim(anim), 
      mBitmap(bitmap), mBitmapIn(bitmapIn), 
      mTextureName(-1), mTextureNameIn(-1)
{
    mStartTime = systemTime();
    mFinishTime = 0;
    mOrientationCompleted = false;
    mFirstRedraw = false;
    mLastNormalizedTime = 0;
    mLastScale = 0;
    mNeedsBlending = false;
}

LayerOrientationAnim::~LayerOrientationAnim()
{
    if (mTextureName != -1U) {
        LayerBase::deletedTextures.add(mTextureName);
    }
    if (mTextureNameIn != -1U) {
        LayerBase::deletedTextures.add(mTextureNameIn);
    }
}

bool LayerOrientationAnim::needsBlending() const 
{
    return mNeedsBlending; 
}

Point LayerOrientationAnim::getPhysicalSize() const
{
    const GraphicPlane& plane(graphicPlane(0));
    const DisplayHardware& hw(plane.displayHardware());
    return Point(hw.getWidth(), hw.getHeight());
}

void LayerOrientationAnim::validateVisibility(const Transform&)
{
    const Layer::State& s(drawingState());
    const Transform tr(s.transform);
    const Point size(getPhysicalSize());
    uint32_t w = size.x;
    uint32_t h = size.y;
    mTransformedBounds = tr.makeBounds(w, h);
    mLeft = tr.tx();
    mTop  = tr.ty();
    transparentRegionScreen.clear();
    mTransformed = true;
    mCanUseCopyBit = false;
    copybit_device_t* copybit = mFlinger->getBlitEngine();
    if (copybit) { 
        mCanUseCopyBit = true;
    }
}

void LayerOrientationAnim::onOrientationCompleted()
{
    mFinishTime = systemTime();
    mOrientationCompleted = true;
    mFirstRedraw = true;
    mNeedsBlending = true;
    mFlinger->invalidateLayerVisibility(this);
}

void LayerOrientationAnim::onDraw(const Region& clip) const
{
    // Animation...
    const float MIN_SCALE = 0.5f;
    const float DURATION = ms2ns(200);
    const float BOUNCES_PER_SECOND = 1.618f;
    const float BOUNCES_AMPLITUDE = 1.0f/32.0f;

    const nsecs_t now = systemTime();
    float scale, alpha;
    
    if (mOrientationCompleted) {
        if (mFirstRedraw) {
            mFirstRedraw = false;
            
            // make a copy of what's on screen
            copybit_image_t image;
            mBitmapIn.getBitmapSurface(&image);
            const DisplayHardware& hw(graphicPlane(0).displayHardware());
            hw.copyBackToImage(image);

            // and erase the screen for this round
            glDisable(GL_BLEND);
            glDisable(GL_DITHER);
            glDisable(GL_SCISSOR_TEST);
            glClearColor(0,0,0,0);
            glClear(GL_COLOR_BUFFER_BIT);
            
            // FIXME: code below is gross
            mNeedsBlending = false;
            LayerOrientationAnim* self(const_cast<LayerOrientationAnim*>(this));
            mFlinger->invalidateLayerVisibility(self);
        }

        // make sure pick-up where we left off
        const float duration = DURATION * mLastNormalizedTime;
        const float normalizedTime = (float(now - mFinishTime) / duration);
        if (normalizedTime <= 1.0f) {
            const float squaredTime = normalizedTime*normalizedTime;
            scale = (1.0f - mLastScale)*squaredTime + mLastScale;
            alpha = (1.0f - normalizedTime);
            alpha *= alpha;
            alpha *= alpha;
        } else {
            mAnim->onAnimationFinished();
            scale = 1.0f;
            alpha = 0.0f;
        }
    } else {
        const float normalizedTime = float(now - mStartTime) / DURATION;
        if (normalizedTime <= 1.0f) {
            mLastNormalizedTime = normalizedTime;
            const float squaredTime = normalizedTime*normalizedTime;
            scale = (MIN_SCALE-1.0f)*squaredTime + 1.0f;
            alpha = 1.0f;
        } else {
            mLastNormalizedTime = 1.0f;
            const float to_seconds = DURATION / seconds(1);
            const float phi = BOUNCES_PER_SECOND * 
                    (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
            scale = MIN_SCALE + BOUNCES_AMPLITUDE * (1.0f - cosf(phi));
            alpha = 1.0f;
        }
        mLastScale = scale;
    }
    drawScaled(scale, alpha);
}

void LayerOrientationAnim::drawScaled(float f, float alpha) const
{
    copybit_image_t dst;
    const GraphicPlane& plane(graphicPlane(0));
    const DisplayHardware& hw(plane.displayHardware());
    hw.getDisplaySurface(&dst);

    // clear screen
    // TODO: with update on demand, we may be able 
    // to not erase the screen at all during the animation 
    if (!mOrientationCompleted) {
        glDisable(GL_BLEND);
        glDisable(GL_DITHER);
        glDisable(GL_SCISSOR_TEST);
        glClearColor(0,0,0,0);
        glClear(GL_COLOR_BUFFER_BIT);
    }
    
    const int w = dst.w*f; 
    const int h = dst.h*f; 
    const int xc = uint32_t(dst.w-w)/2;
    const int yc = uint32_t(dst.h-h)/2;
    const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; 

    copybit_image_t src;
    mBitmap.getBitmapSurface(&src);
    const copybit_rect_t srect = { 0, 0, src.w, src.h };

    int err = NO_ERROR;
    const int can_use_copybit = canUseCopybit();
    if (can_use_copybit)  {
        copybit_device_t* copybit = mFlinger->getBlitEngine();
        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);

        if (alpha < 1.0f) {
            copybit_image_t srcIn;
            mBitmapIn.getBitmapSurface(&srcIn);
            region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
            err = copybit->stretch(copybit, &dst, &srcIn, &drect, &srect, &it);
        }

        if (!err && alpha > 0.0f) {
            region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alpha*255));
            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
        }
        LOGE_IF(err != NO_ERROR, "copybit failed (%s)", strerror(err));
    }
    if (!can_use_copybit || err) {   
        GGLSurface t;
        t.version = sizeof(GGLSurface);
        t.width  = src.w;
        t.height = src.h;
        t.stride = src.w;
        t.vstride= src.h;
        t.format = src.format;
        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);

        Transform tr;
        tr.set(f,0,0,f);
        tr.set(xc, yc);
        
        // FIXME: we should not access mVertices and mDrawingState like that,
        // but since we control the animation, we know it's going to work okay.
        // eventually we'd need a more formal way of doing things like this.
        LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
        tr.transform(self.mVertices[0], 0, 0);
        tr.transform(self.mVertices[1], 0, src.h);
        tr.transform(self.mVertices[2], src.w, src.h);
        tr.transform(self.mVertices[3], src.w, 0);
        if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
            // Too slow to do this in software
            self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
        }

        if (alpha < 1.0f) {
            copybit_image_t src;
            mBitmapIn.getBitmapSurface(&src);
            t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
            if (UNLIKELY(mTextureNameIn == -1LU)) {
                mTextureNameIn = createTexture();
                GLuint w=0, h=0;
                const Region dirty(Rect(t.width, t.height));
                loadTexture(dirty, mTextureNameIn, t, w, h);
            }
            self.mDrawingState.alpha = 255;
            const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
            drawWithOpenGL(clip, mTextureName, t);
        }

        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
        if (UNLIKELY(mTextureName == -1LU)) {
            mTextureName = createTexture();
            GLuint w=0, h=0;
            const Region dirty(Rect(t.width, t.height));
            loadTexture(dirty, mTextureName, t, w, h);
        }
        self.mDrawingState.alpha = int(alpha*255);
        const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
        drawWithOpenGL(clip, mTextureName, t);
    }
}

// ---------------------------------------------------------------------------

}; // namespace android
