/*
 * Copyright (C) 2009 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.android.wallpaper.polarclock;

import android.service.wallpaper.WallpaperService;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Paint;
import android.graphics.Color;
import android.graphics.RectF;
import android.view.SurfaceHolder;
import android.content.IntentFilter;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.XmlResourceParser;

import android.os.Handler;
import android.os.SystemClock;
import android.text.format.Time;
import android.util.MathUtils;
import android.util.Log;

import java.util.HashMap;
import java.util.TimeZone;
import java.io.IOException;

import org.xmlpull.v1.XmlPullParserException;
import static org.xmlpull.v1.XmlPullParser.*;

import com.android.wallpaper.R;

public class PolarClockWallpaper extends WallpaperService {
    private static final String LOG_TAG = "PolarClock";
    
    static final String SHARED_PREFS_NAME = "polar_clock_settings";

    static final String PREF_SHOW_SECONDS = "show_seconds";
    static final String PREF_VARIABLE_LINE_WIDTH = "variable_line_width";
    static final String PREF_PALETTE = "palette";

    static final int BACKGROUND_COLOR = 0xffffffff;

    static abstract class ClockPalette {
        public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) {
            String kind = xrp.getAttributeValue(null, "kind");
            if ("cycling".equals(kind)) {
                return CyclingClockPalette.parseXmlPaletteTag(xrp);
            } else {
                return FixedClockPalette.parseXmlPaletteTag(xrp);
            }
        }

        public abstract int getBackgroundColor();

        // forAngle should be on [0.0,1.0) but 1.0 must be tolerated
        public abstract int getSecondColor(float forAngle);

        public abstract int getMinuteColor(float forAngle);

        public abstract int getHourColor(float forAngle);

        public abstract int getDayColor(float forAngle);

        public abstract int getMonthColor(float forAngle);

        public abstract String getId();

    }

    static class FixedClockPalette extends ClockPalette {
        protected String mId;
        protected int mBackgroundColor;
        protected int mSecondColor;
        protected int mMinuteColor;
        protected int mHourColor;
        protected int mDayColor;
        protected int mMonthColor;

        private static FixedClockPalette sFallbackPalette = null;

        public static FixedClockPalette getFallback() {
            if (sFallbackPalette == null) {
                sFallbackPalette = new FixedClockPalette();
                sFallbackPalette.mId = "default";
                sFallbackPalette.mBackgroundColor = Color.WHITE;
                sFallbackPalette.mSecondColor =
                    sFallbackPalette.mMinuteColor =
                    sFallbackPalette.mHourColor =
                    sFallbackPalette.mDayColor =
                    sFallbackPalette.mMonthColor =
                    Color.BLACK;
            }
            return sFallbackPalette;
        }

        private FixedClockPalette() { }

        public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) {
            final FixedClockPalette pal = new FixedClockPalette();
            pal.mId = xrp.getAttributeValue(null, "id");
            String val;
            if ((val = xrp.getAttributeValue(null, "background")) != null)
                pal.mBackgroundColor = Color.parseColor(val);
            if ((val = xrp.getAttributeValue(null, "second")) != null)
                pal.mSecondColor = Color.parseColor(val);
            if ((val = xrp.getAttributeValue(null, "minute")) != null)
                pal.mMinuteColor = Color.parseColor(val);
            if ((val = xrp.getAttributeValue(null, "hour")) != null)
                pal.mHourColor = Color.parseColor(val);
            if ((val = xrp.getAttributeValue(null, "day")) != null)
                pal.mDayColor = Color.parseColor(val);
            if ((val = xrp.getAttributeValue(null, "month")) != null)
                pal.mMonthColor = Color.parseColor(val);
            return (pal.mId == null) ? null : pal;
        }

        @Override
        public int getBackgroundColor() {
            return mBackgroundColor;
        }

        @Override
        public int getSecondColor(float forAngle) {
            return mSecondColor;
        }

        @Override
        public int getMinuteColor(float forAngle) {
            return mMinuteColor;
        }

        @Override
        public int getHourColor(float forAngle) {
            return mHourColor;
        }

        @Override
        public int getDayColor(float forAngle) {
            return mDayColor;
        }

        @Override
        public int getMonthColor(float forAngle) {
            return mMonthColor;
        }

        @Override
        public String getId() {
            return mId;
        }

    }

    static class CyclingClockPalette extends ClockPalette {
        protected String mId;
        protected int mBackgroundColor;
        protected float mSaturation;
        protected float mBrightness;

        private static final int COLORS_CACHE_COUNT = 720;
        private final int[] mColors = new int[COLORS_CACHE_COUNT];

        private static CyclingClockPalette sFallbackPalette = null;

        public static CyclingClockPalette getFallback() {
            if (sFallbackPalette == null) {
                sFallbackPalette = new CyclingClockPalette();
                sFallbackPalette.mId = "default_c";
                sFallbackPalette.mBackgroundColor = Color.WHITE;
                sFallbackPalette.mSaturation = 0.8f;
                sFallbackPalette.mBrightness = 0.9f;
                sFallbackPalette.computeIntermediateColors();
            }
            return sFallbackPalette;
        }

        private CyclingClockPalette() { }

        private void computeIntermediateColors() {
            final int[] colors = mColors;
            final int count = colors.length;
            float invCount = 1.0f / (float) COLORS_CACHE_COUNT;
            for (int i = 0; i < count; i++) {
                colors[i] = Color.HSBtoColor(i * invCount, mSaturation, mBrightness);
            }
        }

        public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) {
            final CyclingClockPalette pal = new CyclingClockPalette();
            pal.mId = xrp.getAttributeValue(null, "id");
            String val;
            if ((val = xrp.getAttributeValue(null, "background")) != null)
                pal.mBackgroundColor = Color.parseColor(val);
            if ((val = xrp.getAttributeValue(null, "saturation")) != null)
                pal.mSaturation = Float.parseFloat(val);
            if ((val = xrp.getAttributeValue(null, "brightness")) != null)
                pal.mBrightness = Float.parseFloat(val);
            if (pal.mId == null) {
                return null;
            } else {
                pal.computeIntermediateColors();
                return pal;
            }
        }
        @Override
        public int getBackgroundColor() {
            return mBackgroundColor;
        }

        @Override
        public int getSecondColor(float forAngle) {
            if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f;
            return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
        }

        @Override
        public int getMinuteColor(float forAngle) {
            if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f;
            return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
        }

        @Override
        public int getHourColor(float forAngle) {
            if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f;
            return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
        }

        @Override
        public int getDayColor(float forAngle) {
            if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f;
            return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
        }

        @Override
        public int getMonthColor(float forAngle) {
            if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f;
            return mColors[((int) (forAngle * COLORS_CACHE_COUNT))];
        }

        @Override
        public String getId() {
            return mId;
        }
    }

    private final Handler mHandler = new Handler();

    private IntentFilter mFilter;

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

        mFilter = new IntentFilter();
        mFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public Engine onCreateEngine() {
        return new ClockEngine();
    }

    class ClockEngine extends Engine implements SharedPreferences.OnSharedPreferenceChangeListener {
        private static final float SMALL_RING_THICKNESS = 8.0f;
        private static final float MEDIUM_RING_THICKNESS = 16.0f;
        private static final float LARGE_RING_THICKNESS = 32.0f;

        private static final float DEFAULT_RING_THICKNESS = 24.0f;

        private static final float SMALL_GAP = 14.0f;
        private static final float LARGE_GAP = 38.0f;

        private final HashMap<String, ClockPalette> mPalettes = new HashMap<String, ClockPalette>();
        private ClockPalette mPalette;

        private SharedPreferences mPrefs;
        private boolean mShowSeconds;
        private boolean mVariableLineWidth;

        private boolean mWatcherRegistered;
        private Time mCalendar;

        private final Paint mPaint = new Paint();
        private final RectF mRect = new RectF();

        private float mOffsetX;

        private final BroadcastReceiver mWatcher = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                final String timeZone = intent.getStringExtra("time-zone");
                mCalendar = new Time(TimeZone.getTimeZone(timeZone).getID());
                drawFrame();
            }
        };

        private final Runnable mDrawClock = new Runnable() {
            public void run() {
                drawFrame();
            }
        };
        private boolean mVisible;

        ClockEngine() {
            XmlResourceParser xrp = getResources().getXml(R.xml.polar_clock_palettes);
            try {
                int what = xrp.getEventType();
                while (what != END_DOCUMENT) {
                    if (what == START_TAG) {
                        if ("palette".equals(xrp.getName())) {
                            ClockPalette pal = ClockPalette.parseXmlPaletteTag(xrp);
                            if (pal.getId() != null) {
                                mPalettes.put(pal.getId(), pal);
                            }
                        }
                    }
                    what = xrp.next();
                }
            } catch (IOException e) {
                Log.e(LOG_TAG, "An error occured during wallpaper configuration:", e);
            } catch (XmlPullParserException e) {
                Log.e(LOG_TAG, "An error occured during wallpaper configuration:", e);
            } finally {
                xrp.close();
            }

            mPalette = CyclingClockPalette.getFallback();
        }

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            super.onCreate(surfaceHolder);

            mPrefs = PolarClockWallpaper.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
            mPrefs.registerOnSharedPreferenceChangeListener(this);

            // load up user's settings
            onSharedPreferenceChanged(mPrefs, null);

            mCalendar = new Time();
            mCalendar.setToNow();

            final Paint paint = mPaint;
            paint.setAntiAlias(true);
            paint.setStrokeWidth(DEFAULT_RING_THICKNESS);
            paint.setStrokeCap(Paint.Cap.ROUND);
            paint.setStyle(Paint.Style.STROKE);

            if (isPreview()) {
                mOffsetX = 0.5f;            
            }
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            if (mWatcherRegistered) {
                mWatcherRegistered = false;
                unregisterReceiver(mWatcher);
            }
            mHandler.removeCallbacks(mDrawClock);
        }

        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
                String key) {

            boolean changed = false;
            if (key == null || PREF_SHOW_SECONDS.equals(key)) {
                mShowSeconds = sharedPreferences.getBoolean(
                    PREF_SHOW_SECONDS, true);
                changed = true;
            }
            if (key == null || PREF_VARIABLE_LINE_WIDTH.equals(key)) {
                mVariableLineWidth = sharedPreferences.getBoolean(
                    PREF_VARIABLE_LINE_WIDTH, true);
                changed = true;
            }
            if (key == null || PREF_PALETTE.equals(key)) {
                String paletteId = sharedPreferences.getString(
                    PREF_PALETTE, "");
                ClockPalette pal = mPalettes.get(paletteId);
                if (pal != null) {
                    mPalette = pal;
                    changed = true;
                }
            }

            if (mVisible && changed) {
                drawFrame();
            }
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            mVisible = visible;
            if (visible) {
                if (!mWatcherRegistered) {
                    mWatcherRegistered = true;
                    registerReceiver(mWatcher, mFilter, null, mHandler);
                }
                mCalendar = new Time();
                mCalendar.setToNow();
            } else {
                if (mWatcherRegistered) {
                    mWatcherRegistered = false;
                    unregisterReceiver(mWatcher);
                }
                mHandler.removeCallbacks(mDrawClock);
            }
            drawFrame();
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            super.onSurfaceChanged(holder, format, width, height);
            drawFrame();
        }

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
        }

        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mVisible = false;
            mHandler.removeCallbacks(mDrawClock);
        }

        @Override
        public void onOffsetsChanged(float xOffset, float yOffset,
                float xStep, float yStep, int xPixels, int yPixels) {
            mOffsetX = xOffset;
            drawFrame();
        }

        void drawFrame() {
            if (mPalette == null) {
                Log.w("PolarClockWallpaper", "no palette?!");
                return;
            }

            final SurfaceHolder holder = getSurfaceHolder();
            final Rect frame = holder.getSurfaceFrame();
            final int width = frame.width();
            final int height = frame.height();

            Canvas c = null;
            try {
                c = holder.lockCanvas();
                if (c != null) {
                    final Time calendar = mCalendar;
                    final Paint paint = mPaint;

                    final long millis = System.currentTimeMillis();
                    calendar.set(millis);
                    calendar.normalize(false);

                    int s = width / 2;
                    int t = height / 2;

                    c.drawColor(mPalette.getBackgroundColor());

                    c.translate(s + MathUtils.lerp(s, -s, mOffsetX), t);
                    c.rotate(-90.0f);
                    if (height < width) {
                        c.scale(0.9f, 0.9f);
                    }

                    float size = Math.min(width, height) * 0.5f - DEFAULT_RING_THICKNESS;
                    final RectF rect = mRect;
                    rect.set(-size, -size, size, size);
                    float angle;

                    float lastRingThickness = DEFAULT_RING_THICKNESS;

                    if (mShowSeconds) {
                        // Draw seconds  
                        angle = (float) (millis % 60000) / 60000.0f;
                        //Log.d("PolarClock", "millis=" + millis + ", angle=" + angle);
                        paint.setColor(mPalette.getSecondColor(angle));

                        if (mVariableLineWidth) {
                            lastRingThickness = SMALL_RING_THICKNESS;
                            paint.setStrokeWidth(lastRingThickness);
                        }
                        c.drawArc(rect, 0.0f, angle * 360.0f, false, paint);
                    }

                    // Draw minutes
                    size -= (SMALL_GAP + lastRingThickness);
                    rect.set(-size, -size, size, size);

                    angle = ((calendar.minute * 60.0f + calendar.second) % 3600) / 3600.0f;
                    paint.setColor(mPalette.getMinuteColor(angle));

                    if (mVariableLineWidth) {
                        lastRingThickness = MEDIUM_RING_THICKNESS;
                        paint.setStrokeWidth(lastRingThickness);
                    }
                    c.drawArc(rect, 0.0f, angle * 360.0f, false, paint);

                    // Draw hours
                    size -= (SMALL_GAP + lastRingThickness);
                    rect.set(-size, -size, size, size);

                    angle = ((calendar.hour * 60.0f + calendar.minute) % 1440) / 1440.0f;
                    paint.setColor(mPalette.getHourColor(angle));

                    if (mVariableLineWidth) {
                        lastRingThickness = LARGE_RING_THICKNESS;
                        paint.setStrokeWidth(lastRingThickness);
                    }
                    c.drawArc(rect, 0.0f, angle * 360.0f, false, paint);

                    // Draw day
                    size -= (LARGE_GAP + lastRingThickness);
                    rect.set(-size, -size, size, size);

                    angle = (calendar.monthDay - 1) /
                            (float) (calendar.getActualMaximum(Time.MONTH_DAY) - 1);
                    paint.setColor(mPalette.getDayColor(angle));

                    if (mVariableLineWidth) {
                        lastRingThickness = MEDIUM_RING_THICKNESS;
                        paint.setStrokeWidth(lastRingThickness);
                    }
                    c.drawArc(rect, 0.0f, angle * 360.0f, false, paint);

                    // Draw month
                    size -= (SMALL_GAP + lastRingThickness);
                    rect.set(-size, -size, size, size);

                    angle = (calendar.month) / 11.0f; // NB: month is already on [0..11]

                    paint.setColor(mPalette.getMonthColor(angle));

                    if (mVariableLineWidth) {
                        lastRingThickness = LARGE_RING_THICKNESS;
                        paint.setStrokeWidth(lastRingThickness);
                    }
                    c.drawArc(rect, 0.0f, angle * 360.0f, false, paint);
                }
            } finally {
                if (c != null) holder.unlockCanvasAndPost(c);
            }

            mHandler.removeCallbacks(mDrawClock);
            if (mVisible) {
                if (mShowSeconds) {
                    mHandler.postDelayed(mDrawClock, 1000 / 25);
                } else {
                    // If we aren't showing seconds, we don't need to update
                    // nearly as often.
                    mHandler.postDelayed(mDrawClock, 2000);
                }
            }
        }
    }
}
