// Copyright (C) 2016 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.google.reviewit.util;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.IdRes;
import android.support.annotation.StringRes;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TableRow;
import android.widget.TextView;

import com.google.gerrit.extensions.common.AccountInfo;
import com.google.reviewit.AvatarTask;
import com.google.reviewit.R;
import com.google.reviewit.app.ReviewItApp;

import static com.google.reviewit.util.LayoutUtil.wrapTableRowLayout;

public class WidgetUtil {
  private final Context context;

  public WidgetUtil(Context context) {
    this.context = context;
  }

  public @ColorInt int color(@ColorRes int id) {
    // TODO use getResources().getColor(id, null) with API 23
    return context.getResources().getColor(id);
  }

  public int spToPx(int sp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
        context.getResources().getDisplayMetrics());
  }

  public int dpToPx(int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
        context.getResources().getDisplayMetrics());
  }

  public Drawable getDrawable(@DrawableRes int id) {
    return context.getResources().getDrawable(id);
  }

  public View tableRowRightMargin(View view, int rightMarginDp) {
    TableRow.LayoutParams layoutParams =
        (TableRow.LayoutParams) view.getLayoutParams();
    layoutParams.rightMargin = dpToPx(rightMarginDp);
    view.setLayoutParams(layoutParams);
    return view;
  }

  public TextView createTextView(String text, int textSizeSp) {
    return createTextView(text, textSizeSp, false);
  }

  public TextView createTextView(String text, int textSizeSp, boolean isHtlm) {
    TextView textView = new TextView(context);
    textView.setLayoutParams(wrapTableRowLayout());
    textView.setText(isHtlm ? Html.fromHtml(text) : text);
    textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSp);
    if (isHtlm) {
      textView.setLinkTextColor(color(R.color.hyperlink));
      textView.setMovementMethod(LinkMovementMethod.getInstance());
    }
    return textView;
  }

  public static void underline(TextView textView) {
    textView.setPaintFlags(textView.getPaintFlags()
        | Paint.UNDERLINE_TEXT_FLAG);
  }

  public void showError(@StringRes int id) {
    showError(context.getString(id));
  }

  public void showError(String msg) {
    new AlertDialog.Builder(context)
        .setTitle(context.getString(R.string.error_title))
        .setMessage(msg)
        .setPositiveButton(android.R.string.ok,
            new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int which) {
            // do nothing
          }
        }).setIcon(android.R.drawable.ic_dialog_alert).show();
  }

  public int getDimension(@DimenRes int id) {
    return (int) context.getResources().getDimension(id);
  }

  public float toDimension(String value, float defaultValue) {
    if (value == null) {
      return defaultValue;
    }
    try {
      if (value.endsWith("sp")) {
        value = value.substring(0, value.length() - 2).trim();
        return spToPx(Integer.valueOf(value));
      } else if (value.endsWith("dp")) {
        value = value.substring(0, value.length() - 2).trim();
        return dpToPx(Integer.valueOf(value));
      } else if (value.endsWith("px")) {
        value = value.substring(0, value.length() - 2).trim();
        return Integer.valueOf(value);
      } else {
        return Integer.valueOf(value);
      }
    } catch (NumberFormatException e) {
      return defaultValue;
    }
  }

  public void setBackgroundColor(View view, @ColorRes int colorId) {
    view.setBackgroundColor(color(colorId));
  }

  public static void setBackground(View view, Drawable drawable) {
    // TODO use setBackGround(Drawable) with API 16
    view.setBackgroundDrawable(drawable);
  }

  public static void setXY(View view, int x, int y) {
    view.setX(x);
    view.setY(y);
  }

  public static void setRightMargin(View view, int margin) {
    ViewGroup.MarginLayoutParams layoutParams =
        (ViewGroup.MarginLayoutParams) view.getLayoutParams();
    layoutParams.rightMargin = margin;
  }

  public static View setBottomMargin(View view, int margin) {
    ViewGroup.MarginLayoutParams layoutParams =
        (ViewGroup.MarginLayoutParams) view.getLayoutParams();
    layoutParams.bottomMargin = margin;
    return view;
  }

  public static void setText(View view, String text) {
    if (view instanceof TextView) {
      ((TextView) view).setText(text);
    } else {
      throw new IllegalStateException("unexpected view type "
          + view.getClass().getName() + " for id " + view.getId());
    }
  }

  public static void setText(View base, @IdRes int id, String text) {
    View view = base.findViewById(id);
    if (view instanceof TextView) {
      ((TextView) view).setText(text);
    } else {
      throw new IllegalStateException("unexpected view type "
          + view.getClass().getName() + " for id " + id);
    }
  }

  public static void displayAvatar(
      ReviewItApp app, AccountInfo account, ImageView avatar) {
    new AvatarTask(app, avatar).executeOnExecutor(app.getExecutor(), account);
  }

  public static void setGone(View... views) {
    for (View view : views) {
      view.setVisibility(View.GONE);
    }
  }

  public static void setInvisible(View... views) {
    for (View view : views) {
      view.setVisibility(View.INVISIBLE);
    }
  }

  public static void setVisible(View... views) {
    for (View view : views) {
      view.setVisibility(View.VISIBLE);
    }
  }

  public static void setVisible(boolean visible, View... views) {
    if (visible) {
      setVisible(views);
    } else {
      setGone(views);
    }
  }
}
