content: /*
   * Copyright 2014 Alex Curran
   *
   * 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.github.amlcurran.showcaseview.targets;
  
  import android.util.Log;
  import android.view.View;
  import android.view.ViewParent;
  
  import java.lang.reflect.Field;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Class which wraps round the many implementations of ActionBarView and allows finding of Action
   * items
   */
  class ActionBarViewWrapper {
  
      private ViewParent mActionBarView;
      private Class mActionBarViewClass;
      private Class mAbsActionBarViewClass;
  
      public ActionBarViewWrapper(ViewParent actionBarView) {
          if (!actionBarView.getClass().getName().contains("ActionBarView")) {
              String previousP = actionBarView.getClass().getName();
              actionBarView = actionBarView.getParent();
              String throwP = actionBarView.getClass().getName();
              if (!actionBarView.getClass().getName().contains("ActionBarView")) {
                  throw new IllegalStateException("Cannot find ActionBarView for " +
                          "Activity, instead found " + previousP + " and " + throwP);
              }
          }
          mActionBarView = actionBarView;
          mActionBarViewClass = actionBarView.getClass();
          mAbsActionBarViewClass = actionBarView.getClass().getSuperclass();
      }
  
      /**
       * Return the view which represents the spinner on the ActionBar, or null if there isn't one
       */
      public View getSpinnerView() {
          try {
              Field spinnerField = mActionBarViewClass.getDeclaredField("mSpinner");
              spinnerField.setAccessible(true);
              return (View) spinnerField.get(mActionBarView);
          } catch (NoSuchFieldException e) {
              Log.e("TAG", "Failed to find actionbar spinner", e);
          } catch (IllegalAccessException e) {
              Log.e("TAG", "Failed to access actionbar spinner", e);
          }
          return null;
      }
  
      /**
       * Return the view which represents the title on the ActionBar, or null if there isn't one
       */
      public View getTitleView() {
          try {
              Field mTitleViewField = mActionBarViewClass.getDeclaredField("mTitleView");
              mTitleViewField.setAccessible(true);
              return (View) mTitleViewField.get(mActionBarView);
          } catch (NoSuchFieldException e) {
              Log.e("TAG", "Failed to find actionbar title", e);
          } catch (IllegalAccessException e) {
              Log.e("TAG", "Failed to access actionbar title", e);
          }
          return null;
      }
  
      /**
       * Return the view which represents the overflow action item on the ActionBar, or null if there isn't one
       */
      public View getOverflowView() {
          try {
              Field actionMenuPresenterField = mAbsActionBarViewClass.getDeclaredField("mActionMenuPresenter");
              actionMenuPresenterField.setAccessible(true);
              Object actionMenuPresenter = actionMenuPresenterField.get(mActionBarView);
              Field overflowButtonField = actionMenuPresenter.getClass().getDeclaredField("mOverflowButton");
              overflowButtonField.setAccessible(true);
              return (View) overflowButtonField.get(actionMenuPresenter);
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          } catch (NoSuchFieldException e) {
              e.printStackTrace();
          }
          return null;
      }
      
      /**
       * Return the view which represents the MediaRouterButton action item on the ActionBar, or null
       * if there isn't one
       */
      public View getMediaRouterButtonView() {
          try {
              Field actionMenuPresenterField =
                      mActionBarViewClass.getDeclaredField("mOptionsMenu");
              actionMenuPresenterField.setAccessible(true);
              Object optionsMenu = actionMenuPresenterField.get(mActionBarView);
  
              Field actionItemsField = optionsMenu.getClass().getDeclaredField("mActionItems");
              actionItemsField.setAccessible(true);
  
              List actionItems = (ArrayList) actionItemsField.get(optionsMenu);
              if (null != actionItems) {
                  for(Object obj : actionItems) {
                      System.out.println(obj);
                      Object view = getMediaRouteButton(obj);
                      if (null != view) {
                          return (View) view;
                      }
                  }
              }
  
              return null;
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          } catch (NoSuchFieldException e) {
              e.printStackTrace();
          }
          return null;
      }
      
      private Object getMediaRouteButton(Object obj) {
          try {
              Field f = obj.getClass().getDeclaredField("mActionView");
              f.setAccessible(true);
              Object view = f.get(obj);
              if("android.support.v7.app.MediaRouteButton".equals(view.getClass().getName())) {
                  return view;
              }
          } catch (NoSuchFieldException e) {
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          }
          return null;
      }
  
      public View getActionItem(int actionItemId) {
          try {
              Field actionMenuPresenterField = mAbsActionBarViewClass.getDeclaredField("mActionMenuPresenter");
              actionMenuPresenterField.setAccessible(true);
              Object actionMenuPresenter = actionMenuPresenterField.get(mActionBarView);
  
              Field menuViewField = actionMenuPresenter.getClass().getSuperclass().getDeclaredField("mMenuView");
              menuViewField.setAccessible(true);
              Object menuView = menuViewField.get(actionMenuPresenter);
  
              Field mChField;
              if (menuView.getClass().toString().contains("com.actionbarsherlock")) {
                  // There are thousands of superclasses to traverse up
                  // Have to get superclasses because mChildren is private
                  mChField = menuView.getClass().getSuperclass().getSuperclass()
                          .getSuperclass().getSuperclass().getDeclaredField("mChildren");
              } else if (menuView.getClass().toString().contains("android.support.v7")) {
                  mChField = menuView.getClass().getSuperclass().getSuperclass()
                          .getSuperclass().getDeclaredField("mChildren");
              } else {
                  mChField = menuView.getClass().getSuperclass().getSuperclass()
                          .getDeclaredField("mChildren");
              }
              mChField.setAccessible(true);
              Object[] mChs = (Object[]) mChField.get(menuView);
              for (Object mCh : mChs) {
                  if (mCh != null) {
                      View v = (View) mCh;
                      if (v.getId() == actionItemId) {
                          return v;
                      }
                  }
              }
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          } catch (NoSuchFieldException e) {
              e.printStackTrace();
          }
          return null;
      }
  
  }
  