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

package com.android.gallery3d.app;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;

import com.android.gallery3d.R;
import com.android.gallery3d.common.Utils;

/**
 * The time bar view, which includes the current and total time, the progress bar,
 * and the scrubber.
 */
public class TimeBar extends View {

  public interface Listener {
    void onScrubbingStart();
    void onScrubbingMove(int time);
    void onScrubbingEnd(int time);
  }

  // Padding around the scrubber to increase its touch target
  private static final int SCRUBBER_PADDING_IN_DP = 10;

  // The total padding, top plus bottom
  private static final int V_PADDING_IN_DP = 30;

  private static final int TEXT_SIZE_IN_DP = 14;

  private final Listener listener;

  // the bars we use for displaying the progress
  private final Rect progressBar;
  private final Rect playedBar;

  private final Paint progressPaint;
  private final Paint playedPaint;
  private final Paint timeTextPaint;

  private final Bitmap scrubber;
  private final int scrubberPadding; // adds some touch tolerance around the scrubber

  private int scrubberLeft;
  private int scrubberTop;
  private int scrubberCorrection;
  private boolean scrubbing;
  private boolean showTimes;
  private boolean showScrubber;

  private int totalTime;
  private int currentTime;

  private final Rect timeBounds;

  private int vPaddingInPx;

  public TimeBar(Context context, Listener listener) {
    super(context);
    this.listener = Utils.checkNotNull(listener);

    showTimes = true;
    showScrubber = true;

    progressBar = new Rect();
    playedBar = new Rect();

    progressPaint = new Paint();
    progressPaint.setColor(0xFF808080);
    playedPaint = new Paint();
    playedPaint.setColor(0xFFFFFFFF);

    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    float textSizeInPx = metrics.density * TEXT_SIZE_IN_DP;
    timeTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    timeTextPaint.setColor(0xFFCECECE);
    timeTextPaint.setTextSize(textSizeInPx);
    timeTextPaint.setTextAlign(Paint.Align.CENTER);

    timeBounds = new Rect();
    timeTextPaint.getTextBounds("0:00:00", 0, 7, timeBounds);

    scrubber = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_knob);
    scrubberPadding = (int) (metrics.density * SCRUBBER_PADDING_IN_DP);

    vPaddingInPx = (int) (metrics.density * V_PADDING_IN_DP);
  }

  private void update() {
    playedBar.set(progressBar);

    if (totalTime > 0) {
      playedBar.right =
          playedBar.left + (int) ((progressBar.width() * (long) currentTime) / totalTime);
    } else {
      playedBar.right = progressBar.left;
    }

    if (!scrubbing) {
      scrubberLeft = playedBar.right - scrubber.getWidth() / 2;
    }
    invalidate();
  }

  /**
   * @return the preferred height of this view, including invisible padding
   */
  public int getPreferredHeight() {
    return timeBounds.height() + vPaddingInPx + scrubberPadding;
  }

  /**
   * @return the height of the time bar, excluding invisible padding
   */
  public int getBarHeight() {
    return timeBounds.height() + vPaddingInPx;
  }

  public void setTime(int currentTime, int totalTime) {
    if (this.currentTime == currentTime && this.totalTime == totalTime) {
        return;
    }
    this.currentTime = currentTime;
    this.totalTime = totalTime;
    update();
  }

  public void setShowTimes(boolean showTimes) {
    this.showTimes = showTimes;
    requestLayout();
  }

  public void resetTime() {
    setTime(0, 0);
  }

  public void setShowScrubber(boolean showScrubber) {
    this.showScrubber = showScrubber;
    if (!showScrubber && scrubbing) {
      listener.onScrubbingEnd(getScrubberTime());
      scrubbing = false;
    }
    requestLayout();
  }

  private boolean inScrubber(float x, float y) {
    int scrubberRight = scrubberLeft + scrubber.getWidth();
    int scrubberBottom = scrubberTop + scrubber.getHeight();
    return scrubberLeft - scrubberPadding < x && x < scrubberRight + scrubberPadding
        && scrubberTop - scrubberPadding < y && y < scrubberBottom + scrubberPadding;
  }

  private void clampScrubber() {
    int half = scrubber.getWidth() / 2;
    int max = progressBar.right - half;
    int min = progressBar.left - half;
    scrubberLeft = Math.min(max, Math.max(min, scrubberLeft));
  }

  private int getScrubberTime() {
    return (int) ((long) (scrubberLeft + scrubber.getWidth() / 2 - progressBar.left)
        * totalTime / progressBar.width());
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int w = r - l;
    int h = b - t;
    if (!showTimes && !showScrubber) {
      progressBar.set(0, 0, w, h);
    } else {
      int margin = scrubber.getWidth() / 3;
      if (showTimes) {
        margin += timeBounds.width();
      }
      int progressY = (h + scrubberPadding) / 2;
      scrubberTop = progressY - scrubber.getHeight() / 2 + 1;
      progressBar.set(
          getPaddingLeft() + margin, progressY,
          w - getPaddingRight() - margin, progressY + 4);
    }
    update();
  }

  @Override
  public void draw(Canvas canvas) {
    super.draw(canvas);

    // draw progress bars
    canvas.drawRect(progressBar, progressPaint);
    canvas.drawRect(playedBar, playedPaint);

    // draw scrubber and timers
    if (showScrubber) {
      canvas.drawBitmap(scrubber, scrubberLeft, scrubberTop, null);
    }
    if (showTimes) {
      canvas.drawText(
          stringForTime(currentTime),
          timeBounds.width() / 2 + getPaddingLeft(),
          timeBounds.height() + vPaddingInPx / 2 + scrubberPadding + 1,
          timeTextPaint);
      canvas.drawText(
          stringForTime(totalTime),
          getWidth() - getPaddingRight() - timeBounds.width() / 2,
          timeBounds.height() + vPaddingInPx / 2 + scrubberPadding + 1,
          timeTextPaint);
    }
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {

    if (showScrubber) {
      int x = (int) event.getX();
      int y = (int) event.getY();

      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          if (inScrubber(x, y)) {
            scrubbing = true;
            scrubberCorrection = x - scrubberLeft;
            listener.onScrubbingStart();
            return true;
          }
          break;
        case MotionEvent.ACTION_MOVE:
          if (scrubbing) {
            scrubberLeft = x - scrubberCorrection;
            clampScrubber();
            currentTime = getScrubberTime();
            listener.onScrubbingMove(currentTime);
            invalidate();
            return true;
          }
          break;
        case MotionEvent.ACTION_UP:
          if (scrubbing) {
            listener.onScrubbingEnd(getScrubberTime());
            scrubbing = false;
            return true;
          }
          break;
      }
    }
    return false;
  }

  private String stringForTime(long millis) {
    int totalSeconds = (int) millis / 1000;
    int seconds = totalSeconds % 60;
    int minutes = (totalSeconds / 60) % 60;
    int hours = totalSeconds / 3600;
    if (hours > 0) {
      return String.format("%d:%02d:%02d", hours, minutes, seconds).toString();
    } else {
      return String.format("%02d:%02d", minutes, seconds).toString();
    }
  }

}
