/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.taobao.weex.scalpel;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import java.util.ArrayDeque;
import java.util.BitSet;
import java.util.Deque;

import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static android.graphics.Paint.Style.STROKE;
import static android.graphics.Typeface.NORMAL;
import static android.os.Build.VERSION_CODES.JELLY_BEAN;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.INVALID_POINTER_ID;

/**
 * Renders your view hierarchy as an interactive 3D visualization of layers.
 * <p>
 * Interactions supported:
 * <ul>
 * <li>Single touch: controls the rotation of the model.</li>
 * <li>Two finger vertical pinch: Adjust zoom.</li>
 * <li>Two finger horizontal pinch: Adjust layer spacing.</li>
 * </ul>
 */
public class ScalpelFrameLayout extends FrameLayout {
  private static final int TRACKING_UNKNOWN = 0;
  private static final int TRACKING_VERTICALLY = 1;
  private static final int TRACKING_HORIZONTALLY = -1;
  private static final int ROTATION_MAX = 60;
  private static final int ROTATION_MIN = -ROTATION_MAX;
  private static final int ROTATION_DEFAULT_X = -10;
  private static final int ROTATION_DEFAULT_Y = 15;
  private static final float ZOOM_DEFAULT = 0.6f;
  private static final float ZOOM_MIN = 0.33f;
  private static final float ZOOM_MAX = 2f;
  private static final int SPACING_DEFAULT = 25;
  private static final int SPACING_MIN = 10;
  private static final int SPACING_MAX = 100;
  private static final int CHROME_COLOR = Color.RED;
  private static final int CHROME_SHADOW_COLOR = 0xFF000000;
  private static final int TEXT_OFFSET_DP = 2;
  private static final int TEXT_SIZE_DP = 10;
  private static final int CHILD_COUNT_ESTIMATION = 25;
  private static final boolean DEBUG = false;

  private static void log(String message, Object... args) {
    Log.d("Scalpel", String.format(message, args));
  }

  private static class LayeredView {
    View view;
    int layer;

    void set(View view, int layer) {
      this.view = view;
      this.layer = layer;
    }

    void clear() {
      view = null;
      layer = -1;
    }
  }

  private final Rect viewBoundsRect = new Rect();
  private final Paint viewBorderPaint = new Paint(ANTI_ALIAS_FLAG);
  private final Camera camera = new Camera();
  private final Matrix matrix = new Matrix();
  private final int[] location = new int[2];
  private final BitSet visibilities = new BitSet(CHILD_COUNT_ESTIMATION);
  private final SparseArray<String> idNames = new SparseArray<>();
  private final Deque<LayeredView> layeredViewQueue = new ArrayDeque<>();
  private final Pool<LayeredView> layeredViewPool = new Pool<LayeredView>(CHILD_COUNT_ESTIMATION) {
    @Override protected LayeredView newObject() {
      return new LayeredView();
    }
  };

  private final Resources res;
  private final float density;
  private final float slop;
  private final float textOffset;
  private final float textSize;

  private boolean enabled;
  private boolean drawViews = true;
  private boolean drawIds;

  private int pointerOne = INVALID_POINTER_ID;
  private float lastOneX;
  private float lastOneY;
  private int pointerTwo = INVALID_POINTER_ID;
  private float lastTwoX;
  private float lastTwoY;
  private int multiTouchTracking = TRACKING_UNKNOWN;

  private float rotationY = ROTATION_DEFAULT_Y;
  private float rotationX = ROTATION_DEFAULT_X;
  private float zoom = ZOOM_DEFAULT;
  private float spacing = SPACING_DEFAULT;

  private int chromeColor;
  private int chromeShadowColor;

  public ScalpelFrameLayout(Context context) {
    this(context, null);
  }

  public ScalpelFrameLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public ScalpelFrameLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    res = context.getResources();
    density = context.getResources().getDisplayMetrics().density;
    slop = ViewConfiguration.get(context).getScaledTouchSlop();

    textSize = TEXT_SIZE_DP * density;
    textOffset = TEXT_OFFSET_DP * density;

    setChromeColor(CHROME_COLOR);
    viewBorderPaint.setStyle(STROKE);
    viewBorderPaint.setTextSize(textSize);
    setChromeShadowColor(CHROME_SHADOW_COLOR);
    if (Build.VERSION.SDK_INT >= JELLY_BEAN) {
      viewBorderPaint.setTypeface(Typeface.create("sans-serif-condensed", NORMAL));
    }
  }

  /** Set the view border chrome color. */
  public void setChromeColor(int color) {
    if (chromeColor != color) {
      viewBorderPaint.setColor(color);
      chromeColor = color;
      invalidate();
    }
  }

  /** Get the view border chrome color. */
  public int getChromeColor() {
    return chromeColor;
  }

  /** Set the view border chrome shadow color. */
  public void setChromeShadowColor(int color) {
    if (chromeShadowColor != color) {
      viewBorderPaint.setShadowLayer(1, -1, 1, color);
      chromeShadowColor = color;
      invalidate();
    }
  }

  /** Get the view border chrome shadow color. */
  public int getChromeShadowColor() {
    return chromeShadowColor;
  }

  /** Set whether or not the 3D view layer interaction is enabled. */
  public void setLayerInteractionEnabled(boolean enabled) {
    if (this.enabled != enabled) {
      this.enabled = enabled;
      setWillNotDraw(!enabled);
      invalidate();
    }
  }

  /** Returns true when 3D view layer interaction is enabled. */
  public boolean isLayerInteractionEnabled() {
    return enabled;
  }

  /** Set whether the view layers draw their contents. When false, only wireframes are shown. */
  public void setDrawViews(boolean drawViews) {
    if (this.drawViews != drawViews) {
      this.drawViews = drawViews;
      invalidate();
    }
  }

  /** Returns true when view layers draw their contents. */
  public boolean isDrawingViews() {
    return drawViews;
  }

  /** Set whether the view layers draw their IDs. */
  public void setDrawIds(boolean drawIds) {
    if (this.drawIds != drawIds) {
      this.drawIds = drawIds;
      invalidate();
    }
  }

  /** Returns true when view layers draw their IDs. */
  public boolean isDrawingIds() {
    return drawIds;
  }

  @Override public boolean onInterceptTouchEvent(MotionEvent ev) {
    return enabled || super.onInterceptTouchEvent(ev);
  }

  @Override public boolean onTouchEvent(@SuppressWarnings("NullableProblems") MotionEvent event) {
    if (!enabled) {
      return super.onTouchEvent(event);
    }

    int action = event.getActionMasked();
    switch (action) {
      case MotionEvent.ACTION_DOWN:
      case MotionEvent.ACTION_POINTER_DOWN: {
        int index = (action == ACTION_DOWN) ? 0 : event.getActionIndex();
        if (pointerOne == INVALID_POINTER_ID) {
          pointerOne = event.getPointerId(index);
          lastOneX = event.getX(index);
          lastOneY = event.getY(index);
          if (DEBUG) log("Got pointer 1!  id: %s  x: %s  y: %s", pointerOne, lastOneY, lastOneY);
        } else if (pointerTwo == INVALID_POINTER_ID) {
          pointerTwo = event.getPointerId(index);
          lastTwoX = event.getX(index);
          lastTwoY = event.getY(index);
          if (DEBUG) log("Got pointer 2!  id: %s  x: %s  y: %s", pointerTwo, lastTwoY, lastTwoY);
        } else {
          if (DEBUG) log("Ignoring additional pointer.  id: %s", event.getPointerId(index));
        }
        break;
      }

      case MotionEvent.ACTION_MOVE: {
        if (pointerTwo == INVALID_POINTER_ID) {
          // Single pointer controlling 3D rotation.
          for (int i = 0, count = event.getPointerCount(); i < count; i++) {
            if (pointerOne == event.getPointerId(i)) {
              float eventX = event.getX(i);
              float eventY = event.getY(i);
              float dx = eventX - lastOneX;
              float dy = eventY - lastOneY;
              float drx = 90 * (dx / getWidth());
              float dry = 90 * (-dy / getHeight()); // Invert Y-axis.
              // An 'x' delta affects 'y' rotation and vise versa.
              rotationY = Math.min(Math.max(rotationY + drx, ROTATION_MIN), ROTATION_MAX);
              rotationX = Math.min(Math.max(rotationX + dry, ROTATION_MIN), ROTATION_MAX);
              if (DEBUG) {
                log("Single pointer moved (%s, %s) affecting rotation (%s, %s).", dx, dy, drx, dry);
              }

              lastOneX = eventX;
              lastOneY = eventY;

              invalidate();
            }
          }
        } else {
          // We know there's two pointers and we only care about pointerOne and pointerTwo
          int pointerOneIndex = event.findPointerIndex(pointerOne);
          int pointerTwoIndex = event.findPointerIndex(pointerTwo);

          float xOne = event.getX(pointerOneIndex);
          float yOne = event.getY(pointerOneIndex);
          float xTwo = event.getX(pointerTwoIndex);
          float yTwo = event.getY(pointerTwoIndex);

          float dxOne = xOne - lastOneX;
          float dyOne = yOne - lastOneY;
          float dxTwo = xTwo - lastTwoX;
          float dyTwo = yTwo - lastTwoY;

          if (multiTouchTracking == TRACKING_UNKNOWN) {
            float adx = Math.abs(dxOne) + Math.abs(dxTwo);
            float ady = Math.abs(dyOne) + Math.abs(dyTwo);

            if (adx > slop * 2 || ady > slop * 2) {
              if (adx > ady) {
                // Left/right movement wins. Track horizontal.
                multiTouchTracking = TRACKING_HORIZONTALLY;
              } else {
                // Up/down movement wins. Track vertical.
                multiTouchTracking = TRACKING_VERTICALLY;
              }
            }
          }

          if (multiTouchTracking == TRACKING_VERTICALLY) {
            if (yOne >= yTwo) {
              zoom += dyOne / getHeight() - dyTwo / getHeight();
            } else {
              zoom += dyTwo / getHeight() - dyOne / getHeight();
            }

            zoom = Math.min(Math.max(zoom, ZOOM_MIN), ZOOM_MAX);
            invalidate();
          } else if (multiTouchTracking == TRACKING_HORIZONTALLY) {
            if (xOne >= xTwo) {
              spacing += (dxOne / getWidth() * SPACING_MAX) - (dxTwo / getWidth() * SPACING_MAX);
            } else {
              spacing += (dxTwo / getWidth() * SPACING_MAX) - (dxOne / getWidth() * SPACING_MAX);
            }

            spacing = Math.min(Math.max(spacing, SPACING_MIN), SPACING_MAX);
            invalidate();
          }

          if (multiTouchTracking != TRACKING_UNKNOWN) {
            lastOneX = xOne;
            lastOneY = yOne;
            lastTwoX = xTwo;
            lastTwoY = yTwo;
          }
        }
        break;
      }

      case MotionEvent.ACTION_CANCEL:
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_UP: {
        int index = (action != ACTION_POINTER_UP) ? 0 : event.getActionIndex();
        int pointerId = event.getPointerId(index);
        if (pointerOne == pointerId) {
          // Shift pointer two (real or invalid) up to pointer one.
          pointerOne = pointerTwo;
          lastOneX = lastTwoX;
          lastOneY = lastTwoY;
          if (DEBUG) log("Promoting pointer 2 (%s) to pointer 1.", pointerTwo);
          // Clear pointer two and tracking.
          pointerTwo = INVALID_POINTER_ID;
          multiTouchTracking = TRACKING_UNKNOWN;
        } else if (pointerTwo == pointerId) {
          if (DEBUG) log("Lost pointer 2 (%s).", pointerTwo);
          pointerTwo = INVALID_POINTER_ID;
          multiTouchTracking = TRACKING_UNKNOWN;
        }
        break;
      }
    }

    return true;
  }

  @Override public void draw(@SuppressWarnings("NullableProblems") Canvas canvas) {
    if (!enabled) {
      super.draw(canvas);
      return;
    }

    getLocationInWindow(location);
    float x = location[0];
    float y = location[1];

    int saveCount = canvas.save();

    float cx = getWidth() / 2f;
    float cy = getHeight() / 2f;

    camera.save();
    camera.rotate(rotationX, rotationY, 0);
    camera.getMatrix(matrix);
    camera.restore();

    matrix.preTranslate(-cx, -cy);
    matrix.postTranslate(cx, cy);
    canvas.concat(matrix);
    canvas.scale(zoom, zoom, cx, cy);

    if (!layeredViewQueue.isEmpty()) {
      throw new AssertionError("View queue is not empty.");
    }

    // We don't want to be rendered so seed the queue with our children.
    for (int i = 0, count = getChildCount(); i < count; i++) {
      LayeredView layeredView = layeredViewPool.obtain();
      layeredView.set(getChildAt(i), 0);
      layeredViewQueue.add(layeredView);
    }

    while (!layeredViewQueue.isEmpty()) {
      LayeredView layeredView = layeredViewQueue.removeFirst();
      View view = layeredView.view;
      int layer = layeredView.layer;

      // Restore the object to the pool for use later.
      layeredView.clear();
      layeredViewPool.restore(layeredView);

      // Hide any visible children.
      if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup) view;
        visibilities.clear();
        for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
          View child = viewGroup.getChildAt(i);
          //noinspection ConstantConditions
          if (child.getVisibility() == VISIBLE) {
            visibilities.set(i);
            child.setVisibility(INVISIBLE);
          }
        }
      }

      int viewSaveCount = canvas.save();

      // Scale the layer index translation by the rotation amount.
      float translateShowX = rotationY / ROTATION_MAX;
      float translateShowY = rotationX / ROTATION_MAX;
      float tx = layer * spacing * density * translateShowX;
      float ty = layer * spacing * density * translateShowY;
      canvas.translate(tx, -ty);

      view.getLocationInWindow(location);
      canvas.translate(location[0] - x, location[1] - y);

      viewBoundsRect.set(0, 0, view.getWidth(), view.getHeight());
      canvas.drawRect(viewBoundsRect, viewBorderPaint);

      if (drawViews) {
        view.draw(canvas);
      }

      if (drawIds) {
        int id = view.getId();
        if (id != NO_ID) {
          canvas.drawText(nameForId(id), textOffset, textSize, viewBorderPaint);
        }
      }

      String className=view.getClass().getSimpleName();
      canvas.drawText(className,textOffset,textSize,viewBorderPaint);

      canvas.restoreToCount(viewSaveCount);

      // Restore any hidden children and queue them for later drawing.
      if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup) view;
        for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
          if (visibilities.get(i)) {
            View child = viewGroup.getChildAt(i);
            //noinspection ConstantConditions
            child.setVisibility(VISIBLE);
            LayeredView childLayeredView = layeredViewPool.obtain();
            childLayeredView.set(child, layer + 1);
            layeredViewQueue.add(childLayeredView);
          }
        }
      }
    }

    canvas.restoreToCount(saveCount);
  }

  private String nameForId(int id) {
    String name = idNames.get(id);
    if (name == null) {
      try {
        name = res.getResourceEntryName(id);
      } catch (NotFoundException e) {
        name = String.format("0x%8x", id);
      }
      idNames.put(id, name);
    }
    return name;
  }

  private static abstract class Pool<T> {
    private final Deque<T> pool;

    Pool(int initialSize) {
      pool = new ArrayDeque<>(initialSize);
      for (int i = 0; i < initialSize; i++) {
        pool.addLast(newObject());
      }
    }

    T obtain() {
      return pool.isEmpty() ? newObject() : pool.removeLast();
    }

    void restore(T instance) {
      pool.addLast(instance);
    }

    protected abstract T newObject();
  }
}
