content: /*
   * Copyright 2013 Niek Haarman
   *
   * 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.nhaarman.listviewanimations;
  
  import android.database.DataSetObserver;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.AbsListView;
  import android.widget.BaseAdapter;
  import android.widget.SectionIndexer;
  
  import com.nhaarman.listviewanimations.widget.DynamicListView;
  import com.nhaarman.listviewanimations.widget.DynamicListView.Swappable;
  
  /**
   * A decorator class that enables decoration of an instance of the BaseAdapter
   * class.
   *
   * Classes extending this class can override methods and provide extra
   * functionality before or after calling the super method.
   */
  public abstract class BaseAdapterDecorator extends BaseAdapter implements SectionIndexer, DynamicListView.Swappable, ListViewSetter {
  
  	protected final BaseAdapter mDecoratedBaseAdapter;
  
  	private AbsListView mListView;
  
  	private boolean mIsParentHorizontalScrollContainer;
  	private int mResIdTouchChild;
  
  	public BaseAdapterDecorator(final BaseAdapter baseAdapter) {
  		mDecoratedBaseAdapter = baseAdapter;
  	}
  
  	@Override
  	public void setAbsListView(final AbsListView listView) {
  		mListView = listView;
  
  		if (mDecoratedBaseAdapter instanceof ListViewSetter) {
  			((ListViewSetter) mDecoratedBaseAdapter).setAbsListView(listView);
  		}
  
  		if (mListView instanceof DynamicListView) {
  			DynamicListView dynListView = (DynamicListView) mListView;
  			dynListView.setIsParentHorizontalScrollContainer(mIsParentHorizontalScrollContainer);
  			dynListView.setDynamicTouchChild(mResIdTouchChild);
  		}
  	}
  
  	public AbsListView getAbsListView() {
  		return mListView;
  	}
  
  	@Override
  	public int getCount() {
  		return mDecoratedBaseAdapter.getCount();
  	}
  
  	@Override
  	public Object getItem(final int position) {
  		return mDecoratedBaseAdapter.getItem(position);
  	}
  
  	@Override
  	public long getItemId(final int position) {
  		return mDecoratedBaseAdapter.getItemId(position);
  	}
  
  	@Override
  	public View getView(final int position, final View convertView, final ViewGroup parent) {
  		return mDecoratedBaseAdapter.getView(position, convertView, parent);
  	}
  
  	@Override
  	public boolean areAllItemsEnabled() {
  		return mDecoratedBaseAdapter.areAllItemsEnabled();
  	}
  
  	@Override
  	public View getDropDownView(final int position, final View convertView, final ViewGroup parent) {
  		return mDecoratedBaseAdapter.getDropDownView(position, convertView, parent);
  	}
  
  	@Override
  	public int getItemViewType(final int position) {
  		return mDecoratedBaseAdapter.getItemViewType(position);
  	}
  
  	@Override
  	public int getViewTypeCount() {
  		return mDecoratedBaseAdapter.getViewTypeCount();
  	}
  
  	@Override
  	public boolean hasStableIds() {
  		return mDecoratedBaseAdapter.hasStableIds();
  	}
  
  	@Override
  	public boolean isEmpty() {
  		return mDecoratedBaseAdapter.isEmpty();
  	}
  
  	@Override
  	public boolean isEnabled(final int position) {
  		return mDecoratedBaseAdapter.isEnabled(position);
  	}
  
  	@Override
  	public void notifyDataSetChanged() {
  		if (!(mDecoratedBaseAdapter instanceof ArrayAdapter<?>)) {
  			// fix #35 dirty trick !
  			// leads to an infinite loop when trying because ArrayAdapter triggers notifyDataSetChanged itself
  			mDecoratedBaseAdapter.notifyDataSetChanged();
  		}
  	}
  	
  	/**
  	 * Helper function if you want to force notifyDataSetChanged()
  	 */
  	@SuppressWarnings("UnusedDeclaration")
      public void notifyDataSetChanged(final boolean force) {
  		if (force || !(mDecoratedBaseAdapter instanceof ArrayAdapter<?>)) {
  			// leads to an infinite loop when trying because ArrayAdapter triggers notifyDataSetChanged itself
  			mDecoratedBaseAdapter.notifyDataSetChanged();
  		}
  	}
  
  	@Override
  	public void notifyDataSetInvalidated() {
  		mDecoratedBaseAdapter.notifyDataSetInvalidated();
  	}
  
  	@Override
  	public void registerDataSetObserver(final DataSetObserver observer) {
  		mDecoratedBaseAdapter.registerDataSetObserver(observer);
  	}
  
  	@Override
  	public void unregisterDataSetObserver(final DataSetObserver observer) {
  		mDecoratedBaseAdapter.unregisterDataSetObserver(observer);
  	}
  
  	@Override
  	public int getPositionForSection(final int section) {
  		if (mDecoratedBaseAdapter instanceof SectionIndexer) {
  			return ((SectionIndexer) mDecoratedBaseAdapter).getPositionForSection(section);
  		}
  		return 0;
  	}
  
  	@Override
  	public int getSectionForPosition(final int position) {
  		if (mDecoratedBaseAdapter instanceof SectionIndexer) {
  			return ((SectionIndexer) mDecoratedBaseAdapter).getSectionForPosition(position);
  		}
  		return 0;
  	}
  
  	@Override
  	public Object[] getSections() {
  		if (mDecoratedBaseAdapter instanceof SectionIndexer) {
  			return ((SectionIndexer) mDecoratedBaseAdapter).getSections();
  		}
  		return null;
  	}
  
  	public BaseAdapter getDecoratedBaseAdapter() {
  		return mDecoratedBaseAdapter;
  	}
  
  	@Override
  	public void swapItems(final int positionOne, final int positionTwo) {
  		if (mDecoratedBaseAdapter instanceof Swappable) {
  			((Swappable) mDecoratedBaseAdapter).swapItems(positionOne, positionTwo);
  		}
  	}
  
  	/**
  	 * If the adapter's list-view is hosted inside a parent(/grand-parent/etc) that can scroll horizontally, horizontal swipes won't
  	 * work, because the parent will prevent touch-events from reaching the list-view.
  	 *
  	 * Call this method with the value 'true' to fix this behavior.
  	 * Note that this will prevent the parent from scrolling horizontally when the user touches anywhere in a list-item.
  	 */
  	public void setIsParentHorizontalScrollContainer(final boolean isParentHorizontalScrollContainer) {
  		mIsParentHorizontalScrollContainer = isParentHorizontalScrollContainer;
  		if (mListView instanceof DynamicListView) {
  			DynamicListView dynListView = (DynamicListView) mListView;
  			dynListView.setIsParentHorizontalScrollContainer(mIsParentHorizontalScrollContainer);
  		}
  	}
  
  	public boolean isParentHorizontalScrollContainer() {
  		return mIsParentHorizontalScrollContainer;
  	}
  
  	/**
  	 * If the adapter's list-view is hosted inside a parent(/grand-parent/etc) that can scroll horizontally, horizontal swipes won't
  	 * work, because the parent will prevent touch-events from reaching the list-view.
  	 *
  	 * If a list-item view has a child with the given resource-ID, the user can still swipe the list-item by touching that child.
  	 * If the user touches an area outside that child (but inside the list-item view), then the swipe will not happen and the parent
  	 * will do its job instead (scrolling horizontally).
  	 *
  	 * @param childResId The resource-ID of the list-items' child that the user should touch to be able to swipe the list-items.
  	 */
  	public void setTouchChild(final int childResId) {
  		mResIdTouchChild = childResId;
  		if (mListView instanceof DynamicListView) {
  			DynamicListView dynListView = (DynamicListView) mListView;
  			dynListView.setDynamicTouchChild(mResIdTouchChild);
  		}
  	}
  
  	public int getTouchChild() {
  		return mResIdTouchChild;
  	}
  }