import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.affairal.network.VolleyHelper;
import com.android.volley.toolbox.NetworkImageView;

/**
 * Created by Yajnesh
 */

public class ViewUtil {

    private static int sScreenWidth;
    private static int sScreenHeight;

    /**
     * This method converts dp unit to equivalent pixels, depending on device density.
     *
     * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
     * @return A float value to represent px equivalent to dp depending on device density
     */
    public static int convertDpToPixel(float dp) {
        DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
        return (int) (dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
    }

    /**
     * This method converts device specific pixels to density independent pixels.
     *
     * @param px A value in px (pixels) unit. Which we need to convert into dp
     * @return A float value to represent dp equivalent to px value
     */
    public static int convertPixelsToDp(float px) {
        DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
        return (int) (px / ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
    }

    /**
     * This method converts device specific pixels to scale independent pixels.
     *
     * @param sp A value in sp unit. Which we need to convert into pixel
     * @return A float value to represent sp equivalent to px value
     */
    public static int convertSpToPixel(float sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                sp, Resources.getSystem().getDisplayMetrics());
    }


    /**
     * Compute Screen width and height and save it statically, call this once from application class<br/>
     * access this value by <br/>
     * {@link ViewUtil#getScreenWidth()} and {@link ViewUtil#getScreenHeight()}
     *
     * @param c Context
     */
    public static void computeCommonParams(Context c) {
        sScreenWidth = computeScreenWidth(c);
        sScreenHeight = computeScreenHeight(c);
    }

    /**
     * Compute the screen width
     *
     * @param c Context
     * @return width in pixels
     */
    private static int computeScreenWidth(Context c) {
        try {
            return getPoint(c).x;
        } catch (Throwable e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * Compute the screen height
     *
     * @param c Context
     * @return width in height
     */
    private static int computeScreenHeight(Context c) {
        try {
            return getPoint(c).y;
        } catch (Throwable e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * Get point for screen dimension calcualtion
     *
     * @param c Context
     * @return point which has screen dimension info
     */
    private static Point getPoint(Context c) {
        WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }

    /**
     * Get the screen width (Make sure you have called {@link ViewUtil#computeCommonParams(Context)} atleast once before invoking {@link #getScreenWidth}
     *
     * @return the screen width
     */
    public static int getScreenWidth() {
        return sScreenWidth;
    }

    /**
     * Get the screen height (Make sure you have called {@link ViewUtil#computeCommonParams(Context)} atleast once before invoking {@link #getScreenWidth}
     *
     * @return the screen height
     */
    public static int getScreenHeight() {
        return sScreenHeight;
    }

    /**
     * Open keyboard
     *
     * @param v with respect to this view
     */
    public static void openKeyBoard(View v) {
        try {
            InputMethodManager inputMethodManager = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.toggleSoftInputFromWindow(v.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);
        } catch (Throwable e) {
            //Not the end of the world. Keyborad didn't show up, that's it.
            e.printStackTrace();
        }
    }

    /**
     * Hide keyboard, the view is automatically detected from the activity
     *
     * @param a Activity
     */
    public static void hideKeyboard(Activity a) {
        // Check if no view has focus:
        try {
            View view = a.getCurrentFocus();
            if (view != null) {
                InputMethodManager inputManager = (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
                inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        } catch (Throwable e) {
            //Not the end of the world. Keyborad didn't hide, that's it.
            e.printStackTrace();
        }
    }

    /**
     * Hide keyboard
     *
     * @param a    Activity
     * @param view with respect to this view
     */
    public static void hideKeyboard(Activity a, View view) {
        // Check if no view has focus:
        try {
            if (view != null) {
                InputMethodManager inputManager = (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
                inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        } catch (Throwable e) {
            //Not the end of the world. Keyborad didn't hide, that's it.
            e.printStackTrace();
        }
    }

    /**
     * Remove global listener set to view
     *
     * @param v        The view from which the global listener to be removed
     * @param listener The listener to be removed
     */
    public static void removeGloabalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener) {
        if (v == null || v.getViewTreeObserver() == null) {
            return;
        }
        if (Build.VERSION.SDK_INT > 16) {
            v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
        } else {
            v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
        }
    }

    public static void setImageUrl(NetworkImageView niv, String url, Integer defaultImage) {
        if (niv == null) {
            return;
        }
        niv.setDefaultImageResId(defaultImage == null ? 0 : defaultImage);
        niv.setImageUrl(url, VolleyHelper.getInstance().getImageLoader());
    }

    public static LinearLayout.LayoutParams getLinearLayoutParams(View v) {
        LinearLayout.LayoutParams genericParam = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        if (v == null) {
            return genericParam;
        }
        LinearLayout.LayoutParams viewParams = (LinearLayout.LayoutParams) v.getLayoutParams();
        if (viewParams != null) {
            return viewParams;
        } else {
            return genericParam;
        }

    }

    public static RelativeLayout.LayoutParams getRelativeLayoutParams(View v) {
        RelativeLayout.LayoutParams genericParam = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        if (v == null) {
            return genericParam;
        }
        RelativeLayout.LayoutParams viewParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
        if (viewParams != null) {
            return viewParams;
        } else {
            return genericParam;
        }

    }
}