content: /*
   * Copyright (C) 2015 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.acdisplay.ui.components;
  
  import android.app.Activity;
  import android.appwidget.AppWidgetManager;
  import android.appwidget.AppWidgetProviderInfo;
  import android.content.Context;
  import android.content.res.Resources;
  import android.graphics.Bitmap;
  import androidx.annotation.NonNull;
  import androidx.annotation.Nullable;
  import android.view.Gravity;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.LinearLayout;
  
  import com.achep.acdisplay.Config;
  import com.achep.acdisplay.R;
  import com.achep.acdisplay.appwidget.MyAppWidgetHost;
  import com.achep.acdisplay.appwidget.MyAppWidgetHostView;
  import com.achep.acdisplay.ui.fragments.AcDisplayFragment;
  import com.achep.base.content.ConfigBase;
  import com.achep.base.utils.AppWidgetUtils;
  import com.achep.base.utils.MathUtils;
  import com.achep.base.utils.ViewUtils;
  
  /**
   * A widget the hosts {@link android.appwidget.AppWidgetHost}.
   *
   * @author Artem Chepurnoy
   */
  public class HostWidget extends Widget implements ConfigBase.OnConfigChangedListener {
  
      private static final String TAG = "HostWidget";
  
      public static final int HOST_ID = 1;
  
      private final AppWidgetManager mAppWidgetManager;
      private final MyAppWidgetHost mAppWidgetHost;
      private MyAppWidgetHostView mHostView;
      private ViewGroup mHostContainer;
      private View mEmptyView;
  
      private boolean mHostViewNeedsReInflate;
  
      public HostWidget(@NonNull Callback callback, @NonNull AcDisplayFragment fragment) {
          super(callback, fragment);
          Activity activity = fragment.getActivity();
          mAppWidgetManager = AppWidgetManager.getInstance(activity);
          mAppWidgetHost = new MyAppWidgetHost(activity, HOST_ID);
      }
  
      @Override
      public void onStart() {
          super.onStart();
          mAppWidgetHost.startListening();
          getConfig().registerListener(this);
          updateAppWidgetViewIfNeeded();
      }
  
      @Override
      public void onViewAttached() {
          super.onViewAttached();
          updateAppWidgetViewIfNeeded();
      }
  
      @Override
      public void onStop() {
          getConfig().unregisterListener(this);
          mAppWidgetHost.stopListening();
          mHostViewNeedsReInflate = true;
          // Stopping listening removes all active views from it,
          // so we will have to re-inflate them.
          super.onStop();
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public boolean isHomeWidget() {
          return true;
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public boolean hasClock() {
          return true;
      }
  
      @Override
      protected ViewGroup onCreateView(
              @NonNull LayoutInflater inflater,
              @NonNull ViewGroup container,
              @Nullable ViewGroup sceneView) {
          boolean initialize = sceneView == null;
          if (initialize) {
              sceneView = (ViewGroup) inflater.inflate(R.layout.acdisplay_scene_host, container, false);
              assert sceneView != null;
          }
  
          mHostContainer = (ViewGroup) sceneView.findViewById(R.id.scene);
          mEmptyView = sceneView.findViewById(R.id.empty);
          return sceneView;
      }
  
      @Nullable
      @Override
      public Bitmap getBackground() {
          return null;
      }
  
      @Override
      public int getBackgroundMask() {
          return 0;
      }
  
      //-- APP WIDGET HOST ------------------------------------------------------
  
      private void updateAppWidgetViewIfNeeded() {
          if (!isStarted() || !isViewAttached()) return;
  
          int id = getConfig().getCustomWidgetId();
          if (!AppWidgetUtils.isValidId(id)) {
              if (mHostView != null) {
                  ViewUtils.removeViewParent(mHostView);
                  mEmptyView.setVisibility(View.VISIBLE);
  
                  mHostViewNeedsReInflate = false;
                  mHostView = null;
              }
              return;
          }
  
          Context context = getFragment().getActivity();
          if (mHostView == null) {
              mHostView = new MyAppWidgetHostView(context);
              updateAppWidgetTouchable();
  
              LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                      ViewGroup.LayoutParams.WRAP_CONTENT,
                      ViewGroup.LayoutParams.WRAP_CONTENT,
                      Gravity.CENTER_HORIZONTAL);
              mHostContainer.addView(mHostView, lp);
              mEmptyView.setVisibility(View.GONE);
          } else if (!mHostViewNeedsReInflate && mHostView.getAppWidgetId() == id) return;
          AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(id);
          mAppWidgetHost.updateView(context, id, appWidget, mHostView);
          mHostViewNeedsReInflate = false;
          updateAppWidgetFrameSize();
      }
  
      private void updateAppWidgetFrameSize() {
          Resources res = getFragment().getActivity().getResources();
          int h = getConfig().getCustomWidgetHeightDp();
          int hMin = res.getDimensionPixelSize(R.dimen.scene_min_height);
          int hMax = res.getDimensionPixelSize(R.dimen.scene_max_height);
          int w = getConfig().getCustomWidgetWidthDp();
          int wMin = res.getDimensionPixelSize(R.dimen.scene_min_width);
          int wMax = res.getDimensionPixelSize(R.dimen.scene_max_width);
          float density = res.getDisplayMetrics().density;
          w = Math.round(MathUtils.range(w * density, wMin, wMax));
          h = Math.round(MathUtils.range(h * density, hMin, hMax));
          // Update size
          ViewUtils.setSize(mHostView, w, h);
          mHostView.updateAppWidgetSize(null, w, h, w, h);
      }
  
      private void updateAppWidgetTouchable() {
          mHostView.setTouchable(getConfig().isCustomWidgetTouchable());
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public void onConfigChanged(@NonNull ConfigBase config,
                                  @NonNull String key,
                                  @NonNull Object value) {
          switch (key) {
              case Config.KEY_UI_CUSTOM_WIDGET_ID:
                  mHostViewNeedsReInflate = true;
                  updateAppWidgetViewIfNeeded();
                  break;
              case Config.KEY_UI_CUSTOM_WIDGET_WIDTH_DP:
              case Config.KEY_UI_CUSTOM_WIDGET_HEIGHT_DP:
                  if (mHostView != null) updateAppWidgetFrameSize();
                  break;
              case Config.KEY_UI_CUSTOM_WIDGET_TOUCHABLE:
                  if (mHostView != null) updateAppWidgetTouchable();
                  break;
          }
      }
  }
  