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

// TODO:
// background stellar matter:
//  - add some slow horizontal parallax motion, or perhaps veeeeery gradual outward drift

package com.android.launcher2;

import android.animation.AnimatorSet;
import android.animation.TimeAnimator;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.support.v13.dreams.BasicDream;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.android.launcher.R;

import java.util.HashMap;
import java.util.Random;

public class RocketLauncher extends BasicDream {
    public static final boolean ROCKET_LAUNCHER = true;

    public static class Board extends FrameLayout
    {
        public static final boolean FIXED_STARS = true;
        public static final boolean FLYING_STARS = true;
        public static final int NUM_ICONS = 20;

        public static final float MANEUVERING_THRUST_SCALE = 0.1f; // tenth speed
        private boolean mManeuveringThrusters = false;
        private float mSpeedScale = 1.0f;

        public static final int LAUNCH_ZOOM_TIME = 400; // ms

        HashMap<ComponentName, Bitmap> mIcons;
        ComponentName[] mComponentNames;

        static Random sRNG = new Random();

        static float lerp(float a, float b, float f) {
            return (b-a)*f + a;
        }

        static float randfrange(float a, float b) {
            return lerp(a, b, sRNG.nextFloat());
        }

        static int randsign() {
            return sRNG.nextBoolean() ? 1 : -1;
        }

        static <E> E pick(E[] array) {
            if (array.length == 0) return null;
            return array[sRNG.nextInt(array.length)];
        }

        public class FlyingIcon extends ImageView {
            public static final float VMAX = 1000.0f;
            public static final float VMIN = 100.0f;
            public static final float ANGULAR_VMAX = 45f;
            public static final float ANGULAR_VMIN = 0f;
            public static final float SCALE_MIN = 0.5f;
            public static final float SCALE_MAX = 4f;

            public float v, vr;

            public final float[] hsv = new float[3];

            public float angle, anglex, angley;
            public float fuse;
            public float dist;
            public float endscale;
            public float boardCenterX, boardCenterY;

            public ComponentName component;

            public FlyingIcon(Context context, AttributeSet as) {
                super(context, as);
                setLayerType(View.LAYER_TYPE_HARDWARE, null);

                setBackgroundResource(R.drawable.flying_icon_bg);
                //android.util.Log.d("RocketLauncher", "ctor: " + this);
                hsv[1] = 1f;
                hsv[2] = 1f;
            }

            @Override
            public boolean onTouchEvent(MotionEvent event) {
                if (!mManeuveringThrusters || component == null) {
                    return false;
                }
                if (getAlpha() < 0.5f) {
                    setPressed(false);
                    return false;
                }

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        setPressed(true);
                        Board.this.resetWarpTimer();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        final Rect hit = new Rect();
                        final Point offset = new Point();
                        getGlobalVisibleRect(hit, offset);
                        final int globx = (int) event.getX() + offset.x;
                        final int globy = (int) event.getY() + offset.y;
                        setPressed(hit.contains(globx, globy));
                        Board.this.resetWarpTimer();
                        break;
                    case MotionEvent.ACTION_UP:
                        if (isPressed()) {
                            setPressed(false);
                            postDelayed(new Runnable() {
                                public void run() {
                                    try {
                                        getContext().startActivity(new Intent(Intent.ACTION_MAIN)
                                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                                            .setComponent(component));
                                    } catch (android.content.ActivityNotFoundException e) {
                                    } catch (SecurityException e) {
                                    }
                                }
                            }, LAUNCH_ZOOM_TIME);
                            endscale = 0;
                            AnimatorSet s = LauncherAnimUtils.createAnimatorSet();
                            s.playTogether(
                                LauncherAnimUtils.ofFloat(this, "scaleX", 15f),
                                LauncherAnimUtils.ofFloat(this, "scaleY", 15f),
                                LauncherAnimUtils.ofFloat(this, "alpha", 0f)
                            );

                            // make sure things are still moving until the very last instant the
                            // activity is visible
                            s.setDuration((int)(LAUNCH_ZOOM_TIME * 1.25));
                            s.setInterpolator(new android.view.animation.AccelerateInterpolator(3));
                            s.start();
                        }
                        break;
                }
                return true;
            }

            public String toString() {
                return String.format("<'%s' @ (%.1f, %.1f) v=%.1f a=%.1f dist/fuse=%.1f/%.1f>",
                        "icon", getX(), getY(), v, angle, dist, fuse);
            }

            public void randomizeIcon() {
                component = pick(mComponentNames);
                setImageBitmap(mIcons.get(component));
            }

            public void randomize() {
                v = randfrange(VMIN, VMAX);
                angle = randfrange(0, 360f);
                anglex = (float) Math.sin(angle / 180. * Math.PI);
                angley = (float) Math.cos(angle / 180. * Math.PI);
                vr = randfrange(ANGULAR_VMIN, ANGULAR_VMAX) * randsign();
                endscale = randfrange(SCALE_MIN, SCALE_MAX);

                randomizeIcon();
            }
            public void reset() {
                randomize();
                boardCenterX = (Board.this.getWidth() - getWidth()) / 2;
                boardCenterY = (Board.this.getHeight() - getHeight()) / 2;
                setX(boardCenterX);
                setY(boardCenterY);
                fuse = (float) Math.max(boardCenterX, boardCenterY);
                setRotation(180-angle);
                setScaleX(0f);
                setScaleY(0f);
                dist = 0;
                setAlpha(0f);
            }
            public void update(float dt) {
                dist += v * dt;
                setX(getX() + anglex * v * dt);
                setY(getY() + angley * v * dt);
                //setRotation(getRotation() + vr * dt);
                if (endscale > 0) {
                    float scale = lerp(0, endscale, (float) Math.sqrt(dist / fuse));
                        setScaleX(scale * lerp(1f, 0.75f, (float) Math.pow((v-VMIN)/(VMAX-VMIN),3)));
                        setScaleY(scale * lerp(1f, 1.5f, (float) Math.pow((v-VMIN)/(VMAX-VMIN),3)));
                    final float q1 = fuse*0.15f;
                    final float q4 = fuse*0.75f;
                    if (dist < q1) {
                        setAlpha((float) Math.sqrt(dist/q1));
                    } else if (dist > q4) {
                        setAlpha((dist >= fuse) ? 0f : (1f-(float)Math.pow((dist-q4)/(fuse-q4),2)));
                    } else {
                        setAlpha(1f);
                    }
                }
            }
        }

        public class FlyingStar extends FlyingIcon {
            public FlyingStar(Context context, AttributeSet as) {
                super(context, as);
            }
            public void randomizeIcon() {
                setImageResource(R.drawable.widget_resize_handle_bottom);
            }
            public void randomize() {
                super.randomize();
                v = randfrange(VMAX*0.75f, VMAX*2f); // fasticate
                endscale = randfrange(1f, 2f); // ensmallen
            }
        }

        TimeAnimator mAnim;

        public Board(Context context, AttributeSet as) {
            super(context, as);

            setBackgroundColor(0xFF000000);

            LauncherApplication app = (LauncherApplication)context.getApplicationContext();
            mIcons = app.getIconCache().getAllIcons();
            mComponentNames = new ComponentName[mIcons.size()];
            mComponentNames = mIcons.keySet().toArray(mComponentNames);
        }

        private void reset() {
            removeAllViews();

            final ViewGroup.LayoutParams wrap = new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT);

            if (FIXED_STARS) {
                for(int i=0; i<20; i++) {
                    ImageView fixedStar = new ImageView(getContext(), null);
                    fixedStar.setImageResource(R.drawable.widget_resize_handle_bottom);
                    final float s = randfrange(0.25f, 0.75f);
                    fixedStar.setScaleX(s);
                    fixedStar.setScaleY(s);
                    fixedStar.setAlpha(0.75f);
                    addView(fixedStar, wrap);
                    fixedStar.setX(randfrange(0, getWidth()));
                    fixedStar.setY(randfrange(0, getHeight()));
                }
            }

            for(int i=0; i<NUM_ICONS*2; i++) {
                FlyingIcon nv = (FLYING_STARS && (i < NUM_ICONS))
                    ? new FlyingStar(getContext(), null)
                    : new FlyingIcon(getContext(), null);
                addView(nv, wrap);
                nv.reset();
            }

            mAnim = new TimeAnimator();
            mAnim.setTimeListener(new TimeAnimator.TimeListener() {
                public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
                    // setRotation(totalTime * 0.01f); // not as cool as you would think

                    final int START_ZOOM_TIME = 3000;
                    if (totalTime < START_ZOOM_TIME) {
                        final float x = totalTime/(float)START_ZOOM_TIME;
                        final float s = 1f-(float)Math.pow(x-1, 4);
                        setScaleX(s); setScaleY(s);
                    } else {
                        setScaleX(1.0f); setScaleY(1.0f);
                    }

                    if (mManeuveringThrusters) {
                        if (mSpeedScale > MANEUVERING_THRUST_SCALE) {
                            mSpeedScale -= (2*deltaTime/1000f);
                        }
                        if (mSpeedScale < MANEUVERING_THRUST_SCALE) {
                            mSpeedScale = MANEUVERING_THRUST_SCALE;
                        }
                    } else {
                        if (mSpeedScale < 1.0f) {
                            mSpeedScale += (deltaTime/1000f);
                        }
                        if (mSpeedScale > 1.0f) {
                            mSpeedScale = 1.0f;
                        }
                    }

                    for (int i=0; i<getChildCount(); i++) {
                        View v = getChildAt(i);
                        if (!(v instanceof FlyingIcon)) continue;
                        FlyingIcon nv = (FlyingIcon) v;
                        nv.update(deltaTime / 1000f * mSpeedScale);
                        final float scaledWidth = nv.getWidth() * nv.getScaleX();
                        final float scaledHeight = nv.getHeight() * nv.getScaleY();
                        if (   nv.getX() + scaledWidth < 0
                            || nv.getX() - scaledWidth > getWidth()
                            || nv.getY() + scaledHeight < 0 
                            || nv.getY() - scaledHeight > getHeight())
                        {
                            nv.reset();
                        }
                    }
                }
            });
        }

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            setLayerType(View.LAYER_TYPE_HARDWARE, null);
            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);

            reset();
            mAnim.start();
        }

        protected void onSizeChanged (int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w,h,oldw,oldh);
            mAnim.cancel();
            reset();
            mAnim.start();
        }


        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            mAnim.cancel();
        }

        @Override
        public boolean isOpaque() {
            return true;
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent e) {
            // we want to eat touch events ourselves if we're in warp speed
            return (!(ROCKET_LAUNCHER && mManeuveringThrusters));
        }

        final Runnable mEngageWarp = new Runnable() {
            @Override
            public void run() {
                mManeuveringThrusters = false;
            }
        };
        public void resetWarpTimer() {
            final Handler h = getHandler();
            h.removeCallbacks(mEngageWarp);
            h.postDelayed(mEngageWarp, 5000);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (!ROCKET_LAUNCHER) {
                return true;
            }

            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (!mManeuveringThrusters) {
                    mManeuveringThrusters = true;
                    resetWarpTimer();
                    return true;
                }
            }

            return false;
        }
    }

    @Override
    public void onStart() {
        super.onStart();

        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        final int longside = metrics.widthPixels > metrics.heightPixels 
            ? metrics.widthPixels : metrics.heightPixels;

        Board b = new Board(this, null);
        setContentView(b, new ViewGroup.LayoutParams(longside, longside));
        b.setX((metrics.widthPixels - longside) / 2);
        b.setY((metrics.heightPixels - longside) / 2);
    }

    @Override
    public void onUserInteraction() {
        if (!ROCKET_LAUNCHER) {
            finish();
        }
    }
}
