package com.quran.labs.androidquran.widgets;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.PopupMenu;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.quran.labs.androidquran.R;

public class AyahToolBar extends ViewGroup implements
    View.OnClickListener, View.OnLongClickListener {
  public enum PipPosition { UP, DOWN }

  private Context context;
  private Menu menu;
  private Menu currentMenu;
  private int itemWidth;
  private int pipWidth;
  private int pipHeight;
  private boolean isShowing;
  private float pipOffset;
  private LinearLayout menuLayout;
  private AyahToolBarPip toolBarPip;
  private PipPosition pipPosition;
  private MenuItem.OnMenuItemClickListener itemSelectedListener;

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

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

  @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  public AyahToolBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
  }

  private void init(Context context) {
    this.context = context;
    final Resources resources = context.getResources();
    itemWidth = resources.getDimensionPixelSize(R.dimen.toolbar_item_width);
    final int toolBarHeight = resources.getDimensionPixelSize(R.dimen.toolbar_height);
    pipHeight = resources.getDimensionPixelSize(R.dimen.toolbar_pip_height);
    pipWidth = resources.getDimensionPixelSize(R.dimen.toolbar_pip_width);
    final int background = ContextCompat.getColor(context, R.color.toolbar_background);

    menuLayout = new LinearLayout(context);
    menuLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, toolBarHeight));
    menuLayout.setBackgroundColor(background);
    addView(menuLayout);

    pipPosition = PipPosition.DOWN;
    toolBarPip = new AyahToolBarPip(context);
    toolBarPip.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, pipHeight));
    addView(toolBarPip);

    // used to use MenuBuilder, but now it has @RestrictTo, so using this clever trick from
    // StackOverflow - PopupMenu generates a new MenuBuilder internally, so this just lets us
    // get that menu and do whatever we want with it.
    menu = new PopupMenu(this.context, this).getMenu();
    final MenuInflater inflater = new MenuInflater(this.context);
    inflater.inflate(R.menu.ayah_menu, menu);
    showMenu(menu);
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int totalWidth = getMeasuredWidth();
    final int pipWidth = toolBarPip.getMeasuredWidth();
    final int pipHeight = toolBarPip.getMeasuredHeight();
    final int menuWidth = menuLayout.getMeasuredWidth();
    final int menuHeight = menuLayout.getMeasuredHeight();

    int pipLeft = (int) pipOffset;
    if ((pipLeft + pipWidth) > totalWidth) {
      pipLeft = (totalWidth / 2) - (pipWidth / 2);
    }

    // overlap the pip and toolbar by 1px to avoid occasional gap
    if (pipPosition == PipPosition.UP) {
      toolBarPip.layout(pipLeft, 0, pipLeft + pipWidth, pipHeight + 1);
      menuLayout.layout(0, pipHeight, menuWidth, pipHeight + menuHeight);
    } else {
      toolBarPip.layout(pipLeft, menuHeight - 1, pipLeft + pipWidth, menuHeight + pipHeight);
      menuLayout.layout(0, 0, menuWidth, menuHeight);
    }
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    measureChild(menuLayout, widthMeasureSpec, heightMeasureSpec);
    final int width = menuLayout.getMeasuredWidth();
    int height = menuLayout.getMeasuredHeight();
    measureChild(toolBarPip,
        MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
        MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY));
    height += toolBarPip.getMeasuredHeight();
    setMeasuredDimension(resolveSize(width, widthMeasureSpec),
        resolveSize(height, heightMeasureSpec));
  }

  private void showMenu(Menu menu) {
    if (currentMenu == menu) {
      // no need to re-draw
      return;
    }

    menuLayout.removeAllViews();
    final int count = menu.size();
    for (int i=0; i<count; i++) {
      final MenuItem item = menu.getItem(i);
      if (item.isVisible()) {
        final View view = getMenuItemView(item);
        menuLayout.addView(view);
      }
    }

    currentMenu = menu;
  }

  private View getMenuItemView(MenuItem item) {
    final ImageButton button = new ImageButton(context);
    button.setImageDrawable(item.getIcon());
    button.setBackgroundResource(R.drawable.toolbar_button);
    button.setId(item.getItemId());
    button.setLayoutParams(new LayoutParams(itemWidth,
        ViewGroup.LayoutParams.MATCH_PARENT));
    button.setOnClickListener(this);
    button.setOnLongClickListener(this);
    return button;
  }

  public int getToolBarWidth() {
    // relying on getWidth() may give us the width of a shorter
    // submenu instead of the actual menu
    return menu.size() * itemWidth;
  }

  public void setBookmarked(boolean bookmarked) {
    MenuItem bookmarkItem = menu.findItem(R.id.cab_bookmark_ayah);
    bookmarkItem.setIcon(bookmarked ? R.drawable.ic_favorite : R.drawable.ic_not_favorite);
    ImageButton bookmarkButton = (ImageButton) findViewById(R.id.cab_bookmark_ayah);
    if (bookmarkButton != null) {
      bookmarkButton.setImageDrawable(bookmarkItem.getIcon());
    }
  }

  public void updatePosition(AyahToolBarPosition position) {
    boolean needsLayout = position.pipPosition != pipPosition || pipOffset != position.pipOffset;
    ensurePipPosition(position.pipPosition);
    pipOffset = position.pipOffset;
    float x = position.x + position.xScroll;
    float y = position.y + position.yScroll;
    setPosition(x, y);

    if (needsLayout) {
      requestLayout();
    }
  }

  private void setPosition(float x, float y) {
    setTranslationX(x);
    setTranslationY(y);
  }

  private void ensurePipPosition(PipPosition position) {
    pipPosition = position;
    toolBarPip.ensurePosition(position);
  }

  public boolean isShowing() {
    return isShowing;
  }

  public void resetMenu() {
    showMenu(menu);
  }

  public void showMenu() {
    showMenu(menu);
    setVisibility(VISIBLE);
    isShowing = true;
  }

  public void hideMenu() {
    isShowing = false;
    setVisibility(GONE);
  }

  public void setOnItemSelectedListener(
      MenuItem.OnMenuItemClickListener listener) {
    itemSelectedListener = listener;
  }

  @Override
  public void onClick(View v) {
    final MenuItem item = menu.findItem(v.getId());
    if (item == null) return;
    if (item.hasSubMenu()) {
      showMenu(item.getSubMenu());
    } else if (itemSelectedListener != null) {
      itemSelectedListener.onMenuItemClick(item);
    }
  }

  @Override
  public boolean onLongClick(View v) {
    MenuItem item = menu.findItem(v.getId());
    if (item != null && item.getTitle() != null) {
      Toast.makeText(context, item.getTitle(), Toast.LENGTH_SHORT).show();
      return true;
    }
    return false;
  }

  public static class AyahToolBarPosition {
    public float x;
    public float y;
    public float xScroll;
    public float yScroll;
    public float pipOffset;
    public PipPosition pipPosition;
  }
}