// Copyright 2017 Google Inc.
//
// 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.androidexperiments.meter.drawers;


import android.animation.ArgbEvaluator;
import android.app.Service;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

import android.service.wallpaper.WallpaperService;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;

import java.util.Calendar;

import com.androidexperiments.meter.fonts.RobotoLightTypeface;


/**
 * Class inherited by the other drawers
 */
public class Drawer implements SensorEventListener {
    private Display mDisplay;
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;

    private float[] mLastAccelerometer = new float[3];
    private float[] mLastMagnetometer = new float[3];
    private boolean mLastAccelerometerSet = false;
    private boolean mLastMagnetometerSet = false;

    private float[] mR = new float[9];
    protected float[] mOrientation = new float[3];


    private long prevTapTime = 0;

    protected double textAlpha = 255;
    protected double _textAlpha = 255;
    protected int textFadeCount = 0;

    protected int textColor = Color.WHITE;

    protected float pixelDensity;

    private final ArgbEvaluator ev = new ArgbEvaluator();


    private Paint textPaint;

    public Context context;

    public Drawer(Context context)
    {
        this.context = context;
        this.pixelDensity = context.getResources().getDisplayMetrics().density;
    }

    public void start(){

        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

        mLastAccelerometerSet = false;
        mLastMagnetometerSet = false;
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);

    }

    public void destroy() {
        if( mSensorManager == null ){
            return;
        }
        mSensorManager.unregisterListener(this);
    }

    public void draw(Canvas c){


    }

    public boolean shouldDraw(){
        boolean draw = false;

        return draw;
    }




    public void tap(int x, int y){
        long thistime = Calendar.getInstance().getTimeInMillis();
        if(prevTapTime<thistime) {
            if(thistime - prevTapTime <= 1000){
                doubleTap(x,y);
            }
        }
        prevTapTime = thistime;
    }

    protected void doubleTap(int x, int y){
        textFadeCount = 50;
        textAlpha = (float) 1.0;
    }

    /**
     * Draw the text under the graphics
     */
    protected void drawText(String text1, String text2, int x, int y, Canvas c){
        if( textPaint == null ){
            Paint p = new Paint();
            p.setTypeface(RobotoLightTypeface.getInstance(context));
            p.setColor(textColor);
            p.setTextSize(14 * pixelDensity);
            this.textPaint = p;
        }

        float w = textPaint.measureText(text1, 0, text1.length());
        int offset = (int) w / 2;
        c.drawText(text1, x-offset, y+(18f*pixelDensity), textPaint);

        w = textPaint.measureText(text2, 0, text2.length());
        offset = (int) w / 2;
        c.drawText(text2, x-offset, y+(36f*pixelDensity), textPaint);

    }

    /**
     * Produce a nice lerp between 0...1
     */
    protected  double lerp(double val){
        return val*val*val * (val * (6f*val - 15f) + 10f);
    }

    /**
     * Do a simple animation towards a value with a given speed
     */
    protected double animateValue(double curVal, double goalVal, double speed){
        double ret = curVal;
        if(ret < goalVal){
            ret += speed;
        } else if(ret > goalVal){
            ret -= speed;
        }

        if(Math.abs(ret-goalVal) < speed){
            ret = goalVal;
        }
        return ret;
    }



    /**
     * Interpolate between two HEX colors
     * @param c1 First color
     * @param c2 Second color
     * @param v interpolation value (c1 * (1-v) + c2 * v)
     * @return Interpolated color
     */
    protected int interpolateColor(int c1, int c2, float v){
        return (int) ev.evaluate(v,c1,c2);
    }

    protected float distance(float x1, float y1, float x2, float y2){
        float dX = x2-x1;
        float dY = y2-y1;
        return (float) Math.sqrt(dX*dX+dY*dY);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
            mLastAccelerometerSet = true;
        } else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
            mLastMagnetometerSet = true;
        }
        if (mLastAccelerometerSet && mLastMagnetometerSet) {
            SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);

            try {
                mDisplay = ((WindowManager) ((WallpaperService) context).getApplication().getSystemService(Service.WINDOW_SERVICE))
                        .getDefaultDisplay();
            } catch (Exception ignored){}


            int rotation = Surface.ROTATION_0;
            if(mDisplay != null) {
                rotation = mDisplay.getRotation();
            }

            float[] mRremap = mR.clone();
            if(rotation == Surface.ROTATION_90){
                SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, mRremap);
            }
            if(rotation == Surface.ROTATION_270){
                SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_MINUS_Y, SensorManager.AXIS_X, mRremap);
            }
            if(rotation == Surface.ROTATION_180){
                SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_MINUS_X, SensorManager.AXIS_MINUS_Y, mRremap);
            }

            SensorManager.getOrientation(mRremap, mOrientation);
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}