/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.gecko.widget;

import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import org.mozilla.gecko.util.HardwareUtils;

/**
 * AnchoredPopup is the base class for doorhanger notifications, and is anchored to the urlbar.
 */
public abstract class AnchoredPopup extends PopupWindow {
    public interface OnVisibilityChangeListener {
        public void onDoorHangerShow();
        public void onDoorHangerHide();
    }

    private View mAnchor;
    private OnVisibilityChangeListener onVisibilityChangeListener;

    protected RoundedCornerLayout mContent;
    protected boolean mInflated;

    protected final Context mContext;

    public AnchoredPopup(Context context) {
        super(context);

        mContext = context;

        setAnimationStyle(R.style.PopupAnimation);
    }

    protected void init() {
        // Hide the default window background. Passing null prevents the below setOutTouchable()
        // call from working, so use an empty BitmapDrawable instead.
        setBackgroundDrawable(new BitmapDrawable(mContext.getResources()));

        // Allow the popup to be dismissed when touching outside.
        setOutsideTouchable(true);

        // PopupWindow has a default width and height of 0, so set the width here.
        int width = (int) mContext.getResources().getDimension(R.dimen.doorhanger_width);
        setWindowLayoutMode(0, ViewGroup.LayoutParams.WRAP_CONTENT);
        setWidth(width);

        final LayoutInflater inflater = LayoutInflater.from(mContext);
        final View layout = inflater.inflate(R.layout.anchored_popup, null);
        setContentView(layout);

        mContent = (RoundedCornerLayout) layout.findViewById(R.id.content);

        mInflated = true;
    }

    /**
     * Sets the anchor for this popup.
     *
     * @param anchor Anchor view for positioning the arrow.
     */
    public void setAnchor(View anchor) {
        mAnchor = anchor;
    }

    public void setOnVisibilityChangeListener(OnVisibilityChangeListener listener) {
        onVisibilityChangeListener = listener;
    }

    /**
     * Shows the popup with the arrow pointing to the center of the anchor view. If the anchor
     * isn't visible, the popup will just be shown at the top of the root view.
     */
    public void show() {
        if (!mInflated) {
            throw new IllegalStateException("ArrowPopup#init() must be called before ArrowPopup#show()");
        }

        if (onVisibilityChangeListener != null) {
            onVisibilityChangeListener.onDoorHangerShow();
        }

        final int[] anchorLocation = new int[2];
        if (mAnchor != null) {
            mAnchor.getLocationInWindow(anchorLocation);
        }

        // The doorhanger should overlap the bottom of the urlbar.
        int offsetY = mContext.getResources().getDimensionPixelOffset(R.dimen.doorhanger_offsetY);
        final View decorView = ((Activity) mContext).getWindow().getDecorView();

        // Hack for Gingerbread: showAtLocation ignores window layout parameters so we have to use
        // showAsDropDown() instead.
        // Height and width are always set to 0 dp.
        if (Versions.preHC) {
            setWidth(decorView.getWidth());
            offsetY = mContext.getResources().getDimensionPixelOffset(R.dimen.doorhanger_GB_offsetY);
            if (mAnchor == null) {
              mAnchor = decorView;
            }
            showAsDropDown(mAnchor, 0, -offsetY);
            return;
        }

        final boolean validAnchor = (mAnchor != null) && (anchorLocation[1] > 0);
        if (HardwareUtils.isTablet()) {
            if (validAnchor) {
                showAsDropDown(mAnchor, 0, 0);
            } else {
                // The anchor will be offscreen if the dynamic toolbar is hidden, so anticipate the re-shown position
                // of the toolbar.
                final int offsetX = mContext.getResources().getDimensionPixelOffset(R.dimen.doorhanger_offsetX);
                showAtLocation(decorView, Gravity.TOP | Gravity.LEFT, offsetX, offsetY);
            }
        } else {
            // If the anchor is null or out of the window bounds, just show the popup at the top of the
            // root view.
            final View anchor = validAnchor ? mAnchor : decorView;

            showAtLocation(anchor, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, offsetY);
        }
    }

    @Override
    public void dismiss() {
        super.dismiss();
        if (onVisibilityChangeListener != null) {
            onVisibilityChangeListener.onDoorHangerHide();
        }
    }
}
