/*
 * Copyright (C) 2014 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 com.example.android.wearable.watchface;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.support.wearable.watchface.Gles2WatchFaceService;
import android.support.wearable.watchface.WatchFaceStyle;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;

import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

/**
 * Sample watch face using OpenGL. The watch face is rendered using
 * {@link Gles2ColoredTriangleList}s. The camera moves around in interactive mode and stops moving
 * when the watch enters ambient mode.
 */
public class OpenGLWatchFaceService extends Gles2WatchFaceService {

    private static final String TAG = "OpenGLWatchFaceService";

    /** Expected frame rate in interactive mode. */
    private static final long FPS = 60;

    /** Z distance from the camera to the watchface. */
    private static final float EYE_Z = -2.3f;

    /** How long each frame is displayed at expected frame rate. */
    private static final long FRAME_PERIOD_MS = TimeUnit.SECONDS.toMillis(1) / FPS;

    @Override
    public Engine onCreateEngine() {
        return new Engine();
    }

    private class Engine extends Gles2WatchFaceService.Engine {
        /** Cycle time before the camera motion repeats. */
        private static final long CYCLE_PERIOD_SECONDS = 5;

        /** Number of camera angles to precompute. */
        private final int mNumCameraAngles = (int) (CYCLE_PERIOD_SECONDS * FPS);

        /** Projection transformation matrix. Converts from 3D to 2D. */
        private final float[] mProjectionMatrix = new float[16];

        /**
         * View transformation matrices to use in interactive mode. Converts from world to camera-
         * relative coordinates. One matrix per camera position.
         */
        private final float[][] mViewMatrices = new float[mNumCameraAngles][16];

        /** The view transformation matrix to use in ambient mode */
        private final float[] mAmbientViewMatrix = new float[16];

        /**
         * Model transformation matrices. Converts from model-relative coordinates to world
         * coordinates. One matrix per degree of rotation.
         */
        private final float[][] mModelMatrices = new float[360][16];

        /**
         * Products of {@link #mViewMatrices} and {@link #mProjectionMatrix}. One matrix per camera
         * position.
         */
        private final float[][] mVpMatrices = new float[mNumCameraAngles][16];

        /** The product of {@link #mAmbientViewMatrix} and {@link #mProjectionMatrix} */
        private final float[] mAmbientVpMatrix = new float[16];

        /**
         * Product of {@link #mModelMatrices}, {@link #mViewMatrices}, and
         * {@link #mProjectionMatrix}.
         */
        private final float[] mMvpMatrix = new float[16];

        /** Triangles for the 4 major ticks. These are grouped together to speed up rendering. */
        private Gles2ColoredTriangleList mMajorTickTriangles;

        /** Triangles for the 8 minor ticks. These are grouped together to speed up rendering. */
        private Gles2ColoredTriangleList mMinorTickTriangles;

        /** Triangle for the second hand. */
        private Gles2ColoredTriangleList mSecondHandTriangle;

        /** Triangle for the minute hand. */
        private Gles2ColoredTriangleList mMinuteHandTriangle;

        /** Triangle for the hour hand. */
        private Gles2ColoredTriangleList mHourHandTriangle;

        private Calendar mCalendar = Calendar.getInstance();

        /** Whether we've registered {@link #mTimeZoneReceiver}. */
        private boolean mRegisteredTimeZoneReceiver;

        private final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                mCalendar.setTimeZone(TimeZone.getDefault());
                invalidate();
            }
        };

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "onCreate");
            }
            super.onCreate(surfaceHolder);
            setWatchFaceStyle(new WatchFaceStyle.Builder(OpenGLWatchFaceService.this)
                    .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT)
                    .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
                    .setStatusBarGravity(Gravity.RIGHT | Gravity.TOP)
                    .setHotwordIndicatorGravity(Gravity.LEFT | Gravity.TOP)
                    .setShowSystemUiTime(false)
                    .build());
        }

        @Override
        public void onGlContextCreated() {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "onGlContextCreated");
            }
            super.onGlContextCreated();

            // Create program for drawing triangles.
            Gles2ColoredTriangleList.Program triangleProgram =
                    new Gles2ColoredTriangleList.Program();

            // We only draw triangles which all use the same program so we don't need to switch
            // programs mid-frame. This means we can tell OpenGL to use this program only once
            // rather than having to do so for each frame. This makes OpenGL draw faster.
            triangleProgram.use();

            // Create triangles for the ticks.
            mMajorTickTriangles = createMajorTicks(triangleProgram);
            mMinorTickTriangles = createMinorTicks(triangleProgram);

            // Create triangles for the hands.
            mSecondHandTriangle = createHand(
                    triangleProgram,
                    0.02f /* width */,
                    1.0f /* height */,
                    new float[]{
                            1.0f /* red */,
                            0.0f /* green */,
                            0.0f /* blue */,
                            1.0f /* alpha */
                    }
            );
            mMinuteHandTriangle = createHand(
                    triangleProgram,
                    0.06f /* width */,
                    1f /* height */,
                    new float[]{
                            0.7f /* red */,
                            0.7f /* green */,
                            0.7f /* blue */,
                            1.0f /* alpha */
                    }
            );
            mHourHandTriangle = createHand(
                    triangleProgram,
                    0.1f /* width */,
                    0.6f /* height */,
                    new float[]{
                            0.9f /* red */,
                            0.9f /* green */,
                            0.9f /* blue */,
                            1.0f /* alpha */
                    }
            );

            // Precompute the clock angles.
            for (int i = 0; i < mModelMatrices.length; ++i) {
                Matrix.setRotateM(mModelMatrices[i], 0, i, 0, 0, 1);
            }

            // Precompute the camera angles.
            for (int i = 0; i < mNumCameraAngles; ++i) {
                // Set the camera position (View matrix). When active, move the eye around to show
                // off that this is 3D.
                final float cameraAngle = (float) (((float) i) / mNumCameraAngles * 2 * Math.PI);
                final float eyeX = (float) Math.cos(cameraAngle);
                final float eyeY = (float) Math.sin(cameraAngle);
                Matrix.setLookAtM(mViewMatrices[i],
                        0, // dest index
                        eyeX, eyeY, EYE_Z, // eye
                        0, 0, 0, // center
                        0, 1, 0); // up vector
            }

            Matrix.setLookAtM(mAmbientViewMatrix,
                    0, // dest index
                    0, 0, EYE_Z, // eye
                    0, 0, 0, // center
                    0, 1, 0); // up vector
        }

        @Override
        public void onGlSurfaceCreated(int width, int height) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "onGlSurfaceCreated: " + width + " x " + height);
            }
            super.onGlSurfaceCreated(width, height);

            // Update the projection matrix based on the new aspect ratio.
            final float aspectRatio = (float) width / height;
            Matrix.frustumM(mProjectionMatrix,
                    0 /* offset */,
                    -aspectRatio /* left */,
                    aspectRatio /* right */,
                    -1 /* bottom */,
                    1 /* top */,
                    2 /* near */,
                    7 /* far */);

            // Precompute the products of Projection and View matrices for each camera angle.
            for (int i = 0; i < mNumCameraAngles; ++i) {
                Matrix.multiplyMM(mVpMatrices[i], 0, mProjectionMatrix, 0, mViewMatrices[i], 0);
            }

            Matrix.multiplyMM(mAmbientVpMatrix, 0, mProjectionMatrix, 0, mAmbientViewMatrix, 0);
        }

        /**
         * Creates a triangle for a hand on the watch face.
         *
         * @param program program for drawing triangles
         * @param width width of base of triangle
         * @param length length of triangle
         * @param color color in RGBA order, each in the range [0, 1]
         */
        private Gles2ColoredTriangleList createHand(Gles2ColoredTriangleList.Program program,
                float width, float length, float[] color) {
            // Create the data for the VBO.
            float[] triangleCoords = new float[]{
                    // in counterclockwise order:
                    0, length, 0,   // top
                    -width / 2, 0, 0,   // bottom left
                    width / 2, 0, 0    // bottom right
            };
            return new Gles2ColoredTriangleList(program, triangleCoords, color);
        }

        /**
         * Creates a triangle list for the major ticks on the watch face.
         *
         * @param program program for drawing triangles
         */
        private Gles2ColoredTriangleList createMajorTicks(
                Gles2ColoredTriangleList.Program program) {
            // Create the data for the VBO.
            float[] trianglesCoords = new float[9 * 4];
            for (int i = 0; i < 4; i++) {
                float[] triangleCoords = getMajorTickTriangleCoords(i);
                System.arraycopy(triangleCoords, 0, trianglesCoords, i * 9, triangleCoords.length);
            }

            return new Gles2ColoredTriangleList(program, trianglesCoords,
                    new float[]{
                            1.0f /* red */,
                            1.0f /* green */,
                            1.0f /* blue */,
                            1.0f /* alpha */
                    }
            );
        }

        /**
         * Creates a triangle list for the minor ticks on the watch face.
         *
         * @param program program for drawing triangles
         */
        private Gles2ColoredTriangleList createMinorTicks(
                Gles2ColoredTriangleList.Program program) {
            // Create the data for the VBO.
            float[] trianglesCoords = new float[9 * (12 - 4)];
            int index = 0;
            for (int i = 0; i < 12; i++) {
                if (i % 3 == 0) {
                    // This is where a major tick goes, so skip it.
                    continue;
                }
                float[] triangleCoords = getMinorTickTriangleCoords(i);
                System.arraycopy(triangleCoords, 0, trianglesCoords, index, triangleCoords.length);
                index += 9;
            }

            return new Gles2ColoredTriangleList(program, trianglesCoords,
                    new float[]{
                            0.5f /* red */,
                            0.5f /* green */,
                            0.5f /* blue */,
                            1.0f /* alpha */
                    }
            );
        }

        private float[] getMajorTickTriangleCoords(int index) {
            return getTickTriangleCoords(0.03f /* width */, 0.09f /* length */,
                    index * 360 / 4 /* angleDegrees */);
        }

        private float[] getMinorTickTriangleCoords(int index) {
            return getTickTriangleCoords(0.02f /* width */, 0.06f /* length */,
                    index * 360 / 12 /* angleDegrees */);
        }

        private float[] getTickTriangleCoords(float width, float length, int angleDegrees) {
            // Create the data for the VBO.
            float[] coords = new float[]{
                    // in counterclockwise order:
                    0, 1, 0,   // top
                    width / 2, length + 1, 0,   // bottom left
                    -width / 2, length + 1, 0    // bottom right
            };

            rotateCoords(coords, angleDegrees);
            return coords;
        }

        /**
         * Destructively rotates the given coordinates in the XY plane about the origin by the given
         * angle.
         *
         * @param coords flattened 3D coordinates
         * @param angleDegrees angle in degrees clockwise when viewed from negative infinity on the
         *                     Z axis
         */
        private void rotateCoords(float[] coords, int angleDegrees) {
            double angleRadians = Math.toRadians(angleDegrees);
            double cos = Math.cos(angleRadians);
            double sin = Math.sin(angleRadians);
            for (int i = 0; i < coords.length; i += 3) {
                float x = coords[i];
                float y = coords[i + 1];
                coords[i] = (float) (cos * x - sin * y);
                coords[i + 1] = (float) (sin * x + cos * y);
            }
        }

        @Override
        public void onAmbientModeChanged(boolean inAmbientMode) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode);
            }
            super.onAmbientModeChanged(inAmbientMode);
            invalidate();
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "onVisibilityChanged: " + visible);
            }
            super.onVisibilityChanged(visible);
            if (visible) {
                registerReceiver();

                // Update time zone in case it changed while we were detached.
                mCalendar.setTimeZone(TimeZone.getDefault());

                invalidate();
            } else {
                unregisterReceiver();
            }
        }

        private void registerReceiver() {
            if (mRegisteredTimeZoneReceiver) {
                return;
            }
            mRegisteredTimeZoneReceiver = true;
            IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
            OpenGLWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter);
        }

        private void unregisterReceiver() {
            if (!mRegisteredTimeZoneReceiver) {
                return;
            }
            mRegisteredTimeZoneReceiver = false;
            OpenGLWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver);
        }

        @Override
        public void onTimeTick() {
            super.onTimeTick();
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "onTimeTick: ambient = " + isInAmbientMode());
            }
            invalidate();
        }

        @Override
        public void onDraw() {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "onDraw");
            }
            super.onDraw();
            final float[] vpMatrix;

            // Draw background color and select the appropriate view projection matrix. The
            // background should always be black in ambient mode. The view projection matrix used is
            // overhead in ambient. In interactive mode, it's tilted depending on the current time.
            if (isInAmbientMode()) {
                GLES20.glClearColor(0, 0, 0, 1);
                vpMatrix = mAmbientVpMatrix;
            } else {
                GLES20.glClearColor(0.5f, 0.2f, 0.2f, 1);
                final int cameraIndex =
                        (int) ((System.currentTimeMillis() / FRAME_PERIOD_MS) % mNumCameraAngles);
                vpMatrix = mVpMatrices[cameraIndex];
            }
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

            // Compute angle indices for the three hands.
            mCalendar.setTimeInMillis(System.currentTimeMillis());
            float seconds =
                    mCalendar.get(Calendar.SECOND) + mCalendar.get(Calendar.MILLISECOND) / 1000f;
            float minutes = mCalendar.get(Calendar.MINUTE) + seconds / 60f;
            float hours = mCalendar.get(Calendar.HOUR) + minutes / 60f;
            final int secIndex = (int) (seconds / 60f * 360f);
            final int minIndex = (int) (minutes / 60f * 360f);
            final int hoursIndex = (int) (hours / 12f * 360f);

            // Draw triangles from back to front. Don't draw the second hand in ambient mode.

            // Combine the model matrix with the projection and camera view.
            Matrix.multiplyMM(mMvpMatrix, 0, vpMatrix, 0, mModelMatrices[hoursIndex], 0);

            // Draw the triangle.
            mHourHandTriangle.draw(mMvpMatrix);

            // Combine the model matrix with the projection and camera view.
            Matrix.multiplyMM(mMvpMatrix, 0, vpMatrix, 0, mModelMatrices[minIndex], 0);

            // Draw the triangle.
            mMinuteHandTriangle.draw(mMvpMatrix);
            if (!isInAmbientMode()) {
                // Combine the model matrix with the projection and camera view.
                Matrix.multiplyMM(mMvpMatrix, 0, vpMatrix, 0, mModelMatrices[secIndex], 0);

                // Draw the triangle.
                mSecondHandTriangle.draw(mMvpMatrix);
            }

            // Draw the major and minor ticks.
            mMajorTickTriangles.draw(vpMatrix);
            mMinorTickTriangles.draw(vpMatrix);

            // Draw every frame as long as we're visible and in interactive mode.
            if (isVisible() && !isInAmbientMode()) {
                invalidate();
            }
        }
    }
}
