content: /*
   * Copyright (C) 2014 AChep@xda <artemchep@gmail.com>
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   * MA  02110-1301, USA.
   */
  package com.achep.base.ui;
  
  import android.app.AlertDialog;
  import android.content.Context;
  import android.content.res.Resources;
  import android.graphics.drawable.Drawable;
  import android.support.annotation.DrawableRes;
  import android.support.annotation.LayoutRes;
  import android.support.annotation.NonNull;
  import android.support.annotation.Nullable;
  import android.support.annotation.StringRes;
  import android.text.TextUtils;
  import android.text.method.LinkMovementMethod;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.ViewStub;
  import android.widget.FrameLayout;
  import android.widget.LinearLayout;
  import android.widget.TextView;
  
  import com.achep.headsup.R;
  import com.achep.base.Device;
  
  import org.apache.commons.lang.builder.EqualsBuilder;
  import org.apache.commons.lang.builder.HashCodeBuilder;
  
  /**
   * Helper class to implement custom dialog's design.
   */
  public class DialogBuilder {
  
      /**
       * Layout where content's layout exists in a {@link android.widget.ScrollView}.
       * This is nice to display simple layout without scrollable elements such as
       * {@link android.widget.ListView} or any similar. Use {@link #LAYOUT_SKELETON}
       * for them.
       *
       * @see #LAYOUT_SKELETON
       * @see #createView()
       * @see #createAlertDialogBuilder(int)
       */
      public static final int LAYOUT_COMMON = 0;
  
      /**
       * The skeleton of dialog's layout. The only thing that is here is the custom
       * view you set and the title / icon. Use it to display scrollable elements such as
       * {@link android.widget.ListView}.
       *
       * @see #LAYOUT_COMMON
       * @see #createSkeletonView()
       * @see #createAlertDialogBuilder(int)
       */
      public static final int LAYOUT_SKELETON = 1;
  
      protected final Context mContext;
  
      private Drawable mIcon;
      private CharSequence mTitleText;
      private CharSequence mMessageText;
      private View mView;
      private int mViewRes;
      private int mContentViewRes;
  
      public DialogBuilder(@NonNull Context context) {
          mContext = context;
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public int hashCode() {
          return new HashCodeBuilder(201, 17)
                  .append(mContext)
                  .append(mIcon)
                  .append(mTitleText)
                  .append(mMessageText)
                  .append(mViewRes)
                  .append(mView)
                  .toHashCode();
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public boolean equals(Object o) {
          if (o == null)
              return false;
          if (o == this)
              return true;
          if (!(o instanceof DialogBuilder))
              return false;
  
          DialogBuilder builder = (DialogBuilder) o;
          return new EqualsBuilder()
                  .append(mContext, builder.mContext)
                  .append(mIcon, builder.mIcon)
                  .append(mTitleText, builder.mTitleText)
                  .append(mMessageText, builder.mMessageText)
                  .append(mViewRes, builder.mViewRes)
                  .append(mView, builder.mView)
                  .isEquals();
      }
  
      /**
       * Sets the icon of the title.
       *
       * @see #setIcon(int)
       */
      @NonNull
      public DialogBuilder setIcon(@Nullable Drawable icon) {
          mIcon = icon;
          return this;
      }
  
      /**
       * Sets the icon of the title.
       *
       * @see #setIcon(android.graphics.drawable.Drawable)
       */
      @NonNull
      public DialogBuilder setIcon(@DrawableRes int drawableResource) {
          Resources res = mContext.getResources();
          return setIcon(drawableResource == 0
                  ? null
                  : res.getDrawable(drawableResource));
      }
  
      /**
       * Sets the title text.
       *
       * @see #setTitle(int)
       * @see #setIcon(int)
       */
      @NonNull
      public DialogBuilder setTitle(@Nullable CharSequence title) {
          mTitleText = title;
          return this;
      }
  
      /**
       * Sets the title text.
       *
       * @see #setTitle(CharSequence)
       * @see #setIcon(android.graphics.drawable.Drawable)
       */
      @NonNull
      public DialogBuilder setTitle(@StringRes int titleRes) {
          return setTitle(titleRes == 0
                  ? null
                  : getString(titleRes));
      }
  
      @NonNull
      public DialogBuilder setMessage(@Nullable CharSequence message) {
          mMessageText = message;
          return this;
      }
  
      @NonNull
      public DialogBuilder setMessage(@StringRes int messageRes) {
          return setMessage(messageRes == 0
                  ? null
                  : getString(messageRes));
      }
  
      private String getString(int stringRes) {
          return mContext.getResources().getString(stringRes);
      }
  
      public DialogBuilder setView(View view) {
          mView = view;
          mViewRes = 0;
          return this;
      }
  
      public DialogBuilder setView(@LayoutRes int layoutRes) {
          mView = null;
          mViewRes = layoutRes;
          return this;
      }
  
      public DialogBuilder setContentView(@LayoutRes int layoutRes) {
          mContentViewRes = layoutRes;
          return this;
      }
  
      //-- CREATING VIEW --------------------------------------------------------
  
      public View createView() {
          return createView(LAYOUT_COMMON);
      }
  
      public View createSkeletonView() {
          return createView(LAYOUT_SKELETON);
      }
  
      /**
       * Builds dialog's view
       *
       * @throws IllegalArgumentException when type is not one of defined.
       * @see #LAYOUT_COMMON
       * @see #LAYOUT_SKELETON
       */
      public View createView(int type) {
          LayoutInflater inflater = (LayoutInflater) mContext
                  .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  
          ViewGroup rootLayout = (ViewGroup) createSkeleton();
          ViewGroup contentLayout = rootLayout;
  
          switch (type) {
              case LAYOUT_COMMON:
                  final boolean hasMessageOnly = mView == null && mViewRes == 0;
                  final int layoutResource = mContentViewRes != 0
                          ? mContentViewRes : hasMessageOnly
                          ? R.layout.dialog_message
                          : R.layout.dialog_content;
  
                  ViewStub viewStub = (ViewStub) inflater
                          .inflate(R.layout.dialog_main_body, rootLayout, true)
                          .findViewById(R.id.placeholder);
                  viewStub.setLayoutResource(layoutResource);
  
                  contentLayout = (ViewGroup) viewStub.inflate().findViewById(R.id.content);
                  if (contentLayout == null) contentLayout = rootLayout;
                  TextView messageView = (TextView) contentLayout.findViewById(R.id.message);
  
                  if (messageView != null) {
                      if (!TextUtils.isEmpty(mMessageText)) {
                          messageView.setMovementMethod(new LinkMovementMethod());
                          messageView.setText(mMessageText);
                      } else {
                          ViewGroup vg = (ViewGroup) messageView.getParent();
                          vg.removeView(messageView);
                      }
                  }
  
                  // Fall down.
              case LAYOUT_SKELETON:
  
                  if (mViewRes != 0) {
                      inflater.inflate(mViewRes, contentLayout, true);
                  } else if (mView != null) {
                      contentLayout.addView(mView);
                  }
  
                  return rootLayout;
              default:
                  throw new IllegalArgumentException();
          }
      }
  
      private View createSkeleton() {
          LayoutInflater inflater = (LayoutInflater) mContext
                  .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          LinearLayout rootLayout = (LinearLayout) inflater.inflate(
                  R.layout.dialog_main_skeleton, new FrameLayout(mContext), false);
          TextView titleView = (TextView) rootLayout.findViewById(R.id.title);
  
          if (Device.hasLollipopApi()) {
              // The dividers are quite ugly with material design.
              rootLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
          }
  
          if (mTitleText == null && mIcon == null) {
              rootLayout.removeView(titleView);
          } else {
              if (mTitleText != null)
                  titleView.setText(mTitleText);
              if (mIcon != null)
                  titleView.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
          }
  
          return rootLayout;
      }
  
      //-- ALERT DIALOG ---------------------------------------------------------
  
      public AlertDialog.Builder createAlertDialogBuilder() {
          return createAlertDialogBuilder(LAYOUT_COMMON);
      }
  
      /**
       * Creates view and {@link android.app.AlertDialog.Builder#setView(android.view.View) sets}
       * to new {@link android.app.AlertDialog.Builder}.
       *
       * @param type type of container layout
       * @return AlertDialog.Builder with set custom view
       */
      public AlertDialog.Builder createAlertDialogBuilder(int type) {
          return new AlertDialog.Builder(mContext).setView(createView(type));
      }
  
  }
  