<commit_before>package com.rey.material.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.v7.internal.widget.TintManager;
import android.support.v7.internal.widget.TintTypedArray;
import android.support.v7.internal.widget.ViewUtils;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;

import com.rey.material.R;
import com.rey.material.app.ThemeManager;
import com.rey.material.drawable.ArrowDrawable;
import com.rey.material.drawable.DividerDrawable;
import com.rey.material.drawable.RippleDrawable;
import com.rey.material.util.ThemeUtil;

public class Spinner extends FrameLayout implements ThemeManager.OnThemeChangedListener{
		
	private static final int MAX_ITEMS_MEASURED = 15;
	
	private static final int INVALID_POSITION = -1;

    /**
     * Interface definition for a callback to be invoked when a item's view is clicked.
     */
	public interface OnItemClickListener{
        /**
         * Called when a item's view is clicked.
         * @param parent The Spinner view.
         * @param view The item view.
         * @param position The position of item.
         * @param id The id of item.
         * @return false will make the Spinner doesn't select this item.
         */
		boolean onItemClick(Spinner parent, View view, int position, long id);
	}

    /**
     * Interface definition for a callback to be invoked when an item is selected.
     */
	public interface OnItemSelectedListener{
        /**
         * Called when an item is selected.
         * @param parent The Spinner view.
         * @param view The item view.
         * @param position The position of item.
         * @param id The id of item.
         */
		void onItemSelected(Spinner parent, View view, int position, long id);
	}

    private boolean mLabelEnable;
    private android.widget.TextView mLabelView;

	private SpinnerAdapter mAdapter;
	private OnItemClickListener mOnItemClickListener;
	private OnItemSelectedListener mOnItemSelectedListener;

    private int mMinWidth;
    private int mMinHeight;

	private DropdownPopup mPopup;
	private int mDropDownWidth;
	
	private ArrowDrawable mArrowDrawable;
	private int mArrowSize;
	private int mArrowPadding;
	private boolean mArrowAnimSwitchMode;
	
	private DividerDrawable mDividerDrawable;
	private int mDividerHeight;
	private int mDividerPadding;
	
	private int mGravity;
	private boolean mDisableChildrenWhenDisabled;
	
	private int mSelectedPosition;
	
	private RecycleBin mRecycler = new RecycleBin();
	
	private Rect mTempRect = new Rect();
	
	private DropDownAdapter mTempAdapter;
	
	private SpinnerDataSetObserver mDataSetObserver = new SpinnerDataSetObserver();

	private TintManager mTintManager;

    private boolean mIsRtl;
		
	public Spinner(Context context) {
		super(context, null, R.attr.listPopupWindowStyle);
	}
	
	public Spinner(Context context, AttributeSet attrs) {
		super(context, attrs, R.attr.listPopupWindowStyle);
	}
	
	public Spinner(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}

    public Spinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
	protected void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        mLabelEnable = false;
        mDropDownWidth = LayoutParams.WRAP_CONTENT;
        mArrowAnimSwitchMode = false;
        mGravity = Gravity.CENTER;
        mDisableChildrenWhenDisabled = false;
        mSelectedPosition = INVALID_POSITION;
        mIsRtl = false;

        setWillNotDraw(false);

        mPopup = new DropdownPopup(context, attrs, defStyleAttr, defStyleRes);
        mPopup.setModal(true);

		if(isInEditMode())
            applyStyle(R.style.Material_Widget_Spinner);
		
		setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPopup();
            }
        });

        super.init(context, attrs, defStyleAttr, defStyleRes);
	}

    private android.widget.TextView getLabelView(){
        if(mLabelView == null){
            mLabelView = new android.widget.TextView(getContext());
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
                mLabelView.setTextDirection(mIsRtl ? TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR);
            mLabelView.setSingleLine(true);
            mLabelView.setDuplicateParentStateEnabled(true);
        }

        return mLabelView;
    }

    @Override
    protected void applyStyle(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
        super.applyStyle(context, attrs, defStyleAttr, defStyleRes);

        removeAllViews();

        TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,  R.styleable.Spinner, defStyleAttr, defStyleRes);

        int arrowAnimDuration = -1;
        ColorStateList arrowColor = null;
        Interpolator arrowInterpolator = null;
        boolean arrowClockwise = true;
        int dividerAnimDuration = -1;
        ColorStateList dividerColor = null;
        ColorStateList labelTextColor = null;
        int labelTextSize = -1;

        for(int i = 0, count = a.getIndexCount(); i < count; i++){
            int attr = a.getIndex(i);

            if(attr == R.styleable.Spinner_spn_labelEnable)
                mLabelEnable = a.getBoolean(attr, false);
            else if(attr == R.styleable.Spinner_spn_labelPadding)
                getLabelView().setPadding(0, 0, 0, a.getDimensionPixelSize(attr, 0));
            else if (attr == R.styleable.Spinner_spn_labelTextSize)
                labelTextSize = a.getDimensionPixelSize(attr, 0);
            else if(attr == R.styleable.Spinner_spn_labelTextColor)
                labelTextColor = a.getColorStateList(attr);
            else if(attr == R.styleable.Spinner_spn_labelTextAppearance)
                getLabelView().setTextAppearance(context, a.getResourceId(attr, 0));
            else if(attr == R.styleable.Spinner_spn_labelEllipsize){
                int labelEllipsize = a.getInteger(attr, 0);
                switch (labelEllipsize) {
                    case 1:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.START);
                        break;
                    case 2:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.MIDDLE);
                        break;
                    case 3:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.END);
                        break;
                    case 4:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.MARQUEE);
                        break;
                    default:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.END);
                        break;
                }
            }
            else if(attr == R.styleable.Spinner_spn_label)
                getLabelView().setText(a.getString(attr));
            else if(attr == R.styleable.Spinner_android_gravity)
                mGravity = a.getInt(attr, 0);
            else if(attr == R.styleable.Spinner_android_minWidth)
                setMinimumWidth(a.getDimensionPixelOffset(attr, 0));
            else if(attr == R.styleable.Spinner_android_minHeight)
                setMinimumHeight(a.getDimensionPixelOffset(attr, 0));
            else if(attr == R.styleable.Spinner_android_dropDownWidth)
                mDropDownWidth = a.getLayoutDimension(attr, LayoutParams.WRAP_CONTENT);
            else if(attr == R.styleable.Spinner_android_popupBackground)
                mPopup.setBackgroundDrawable(a.getDrawable(attr));
            else if(attr == R.styleable.Spinner_android_prompt)
                mPopup.setPromptText(a.getString(attr));
            else if(attr == R.styleable.Spinner_spn_popupItemAnimation)
                mPopup.setItemAnimation(a.getResourceId(attr, 0));
            else if(attr == R.styleable.Spinner_spn_popupItemAnimOffset)
                mPopup.setItemAnimationOffset(a.getInteger(attr, 0));
            else if(attr == R.styleable.Spinner_spn_disableChildrenWhenDisabled)
                mDisableChildrenWhenDisabled = a.getBoolean(attr, false);
            else if(attr == R.styleable.Spinner_spn_arrowSwitchMode)
                mArrowAnimSwitchMode = a.getBoolean(attr, false);
            else if(attr == R.styleable.Spinner_spn_arrowAnimDuration)
                arrowAnimDuration = a.getInteger(attr, 0);
            else if(attr == R.styleable.Spinner_spn_arrowSize)
                mArrowSize = a.getDimensionPixelSize(attr, 0);
            else if(attr == R.styleable.Spinner_spn_arrowPadding)
                mArrowPadding = a.getDimensionPixelSize(attr, 0);
            else if(attr == R.styleable.Spinner_spn_arrowColor)
                arrowColor = a.getColorStateList(attr);
            else if(attr == R.styleable.Spinner_spn_arrowInterpolator){
                int resId = a.getResourceId(attr, 0);
                arrowInterpolator = AnimationUtils.loadInterpolator(context, resId);
            }
            else if(attr == R.styleable.Spinner_spn_arrowAnimClockwise)
                arrowClockwise = a.getBoolean(attr, true);
            else if(attr == R.styleable.Spinner_spn_dividerHeight)
                mDividerHeight = a.getDimensionPixelOffset(attr, 0);
            else if(attr == R.styleable.Spinner_spn_dividerPadding)
                mDividerPadding = a.getDimensionPixelOffset(attr, 0);
            else if(attr == R.styleable.Spinner_spn_dividerAnimDuration)
                dividerAnimDuration = a.getInteger(attr, 0);
            else if(attr == R.styleable.Spinner_spn_dividerColor)
                dividerColor = a.getColorStateList(attr);
        }

        a.recycle();

        if(labelTextColor != null)
            getLabelView().setTextColor(labelTextColor);

        if(labelTextSize >= 0)
            getLabelView().setTextSize(TypedValue.COMPLEX_UNIT_PX, labelTextSize);

        if(mLabelEnable)
            addView(getLabelView(), 0, new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        if(mArrowSize > 0){
            if(mArrowDrawable == null){
                if(arrowColor == null)
                    arrowColor = ColorStateList.valueOf(ThemeUtil.colorControlNormal(context, 0xFF000000));

                if(arrowAnimDuration < 0)
                    arrowAnimDuration = 0;

                mArrowDrawable = new ArrowDrawable(ArrowDrawable.MODE_DOWN, mArrowSize, arrowColor, arrowAnimDuration, arrowInterpolator, arrowClockwise);
                mArrowDrawable.setCallback(this);
            }
            else{
                mArrowDrawable.setArrowSize(mArrowSize);
                mArrowDrawable.setClockwise(arrowClockwise);

                if(arrowColor != null)
                    mArrowDrawable.setColor(arrowColor);

                if(arrowAnimDuration >= 0)
                    mArrowDrawable.setAnimationDuration(arrowAnimDuration);

                if(arrowInterpolator != null)
                    mArrowDrawable.setInterpolator(arrowInterpolator);
            }
        }
        else if(mArrowDrawable != null){
            mArrowDrawable.setCallback(null);
            mArrowDrawable = null;
        }

        if(mDividerHeight > 0){
            if(mDividerDrawable == null){
                if(dividerAnimDuration < 0)
                    dividerAnimDuration = 0;

                if(dividerColor == null){
                    int[][] states = new int[][]{
                            new int[]{-android.R.attr.state_pressed},
                            new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled},
                    };
                    int[] colors = new int[]{
                            ThemeUtil.colorControlNormal(context, 0xFF000000),
                            ThemeUtil.colorControlActivated(context, 0xFF000000),
                    };

                    dividerColor = new ColorStateList(states, colors);
                }

                mDividerDrawable = new DividerDrawable(mDividerHeight, dividerColor, dividerAnimDuration);
                mDividerDrawable.setCallback(this);
            }
            else{
                mDividerDrawable.setDividerHeight(mDividerHeight);

                if(dividerColor != null)
                    mDividerDrawable.setColor(dividerColor);

                if(dividerAnimDuration >= 0)
                    mDividerDrawable.setAnimationDuration(dividerAnimDuration);
            }
        }
        else if(mDividerDrawable != null){
            mDividerDrawable.setCallback(null);
            mDividerDrawable = null;
        }

        mTintManager = a.getTintManager();

        if (mTempAdapter != null) {
            mPopup.setAdapter(mTempAdapter);
            mTempAdapter = null;
        }

        if(mAdapter != null)
            setAdapter(mAdapter);

        if(isInEditMode()){
            TextView tv = new TextView(context, attrs, defStyleAttr);
            tv.setText("Item 1");
            super.addView(tv);
        }

        requestLayout();
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    @Override
    public void onRtlPropertiesChanged(int layoutDirection) {
        boolean rtl = layoutDirection == LAYOUT_DIRECTION_RTL;
        if(mIsRtl != rtl) {
            mIsRtl = rtl;

            if(mLabelView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
                mLabelView.setTextDirection(mIsRtl ? TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR);

            requestLayout();
        }
    }

    /**
     * @return The selected item's view.
     */
    public View getSelectedView() {
        View v = getChildAt(getChildCount() - 1);
		return v == mLabelView ? null : v;
	}

    /**
     * Set the selected position of this Spinner.
     * @param position The selected position.
     */
	public void setSelection(int position) {
		if(mAdapter != null)
			position = Math.min(position, mAdapter.getCount() - 1);
		
		if(mSelectedPosition != position){
			mSelectedPosition = position;
			
			if(mOnItemSelectedListener != null)
				mOnItemSelectedListener.onItemSelected(this, getSelectedView(), position, mAdapter == null ? -1 : mAdapter.getItemId(position));
			
			onDataInvalidated();
		}
	}

    /**
     * @return The selected posiiton.
     */<commit_msg>Spinner: fix bug negative position when adapter is empty in setSelection(int) method.<commit_after>package com.rey.material.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.v7.internal.widget.TintManager;
import android.support.v7.internal.widget.TintTypedArray;
import android.support.v7.internal.widget.ViewUtils;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;

import com.rey.material.R;
import com.rey.material.app.ThemeManager;
import com.rey.material.drawable.ArrowDrawable;
import com.rey.material.drawable.DividerDrawable;
import com.rey.material.drawable.RippleDrawable;
import com.rey.material.util.ThemeUtil;

public class Spinner extends FrameLayout implements ThemeManager.OnThemeChangedListener{
		
	private static final int MAX_ITEMS_MEASURED = 15;
	
	private static final int INVALID_POSITION = -1;

    /**
     * Interface definition for a callback to be invoked when a item's view is clicked.
     */
	public interface OnItemClickListener{
        /**
         * Called when a item's view is clicked.
         * @param parent The Spinner view.
         * @param view The item view.
         * @param position The position of item.
         * @param id The id of item.
         * @return false will make the Spinner doesn't select this item.
         */
		boolean onItemClick(Spinner parent, View view, int position, long id);
	}

    /**
     * Interface definition for a callback to be invoked when an item is selected.
     */
	public interface OnItemSelectedListener{
        /**
         * Called when an item is selected.
         * @param parent The Spinner view.
         * @param view The item view.
         * @param position The position of item.
         * @param id The id of item.
         */
		void onItemSelected(Spinner parent, View view, int position, long id);
	}

    private boolean mLabelEnable;
    private android.widget.TextView mLabelView;

	private SpinnerAdapter mAdapter;
	private OnItemClickListener mOnItemClickListener;
	private OnItemSelectedListener mOnItemSelectedListener;

    private int mMinWidth;
    private int mMinHeight;

	private DropdownPopup mPopup;
	private int mDropDownWidth;
	
	private ArrowDrawable mArrowDrawable;
	private int mArrowSize;
	private int mArrowPadding;
	private boolean mArrowAnimSwitchMode;
	
	private DividerDrawable mDividerDrawable;
	private int mDividerHeight;
	private int mDividerPadding;
	
	private int mGravity;
	private boolean mDisableChildrenWhenDisabled;
	
	private int mSelectedPosition;
	
	private RecycleBin mRecycler = new RecycleBin();
	
	private Rect mTempRect = new Rect();
	
	private DropDownAdapter mTempAdapter;
	
	private SpinnerDataSetObserver mDataSetObserver = new SpinnerDataSetObserver();

	private TintManager mTintManager;

    private boolean mIsRtl;
		
	public Spinner(Context context) {
		super(context, null, R.attr.listPopupWindowStyle);
	}
	
	public Spinner(Context context, AttributeSet attrs) {
		super(context, attrs, R.attr.listPopupWindowStyle);
	}
	
	public Spinner(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}

    public Spinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
	protected void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        mLabelEnable = false;
        mDropDownWidth = LayoutParams.WRAP_CONTENT;
        mArrowAnimSwitchMode = false;
        mGravity = Gravity.CENTER;
        mDisableChildrenWhenDisabled = false;
        mSelectedPosition = INVALID_POSITION;
        mIsRtl = false;

        setWillNotDraw(false);

        mPopup = new DropdownPopup(context, attrs, defStyleAttr, defStyleRes);
        mPopup.setModal(true);

		if(isInEditMode())
            applyStyle(R.style.Material_Widget_Spinner);
		
		setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPopup();
            }
        });

        super.init(context, attrs, defStyleAttr, defStyleRes);
	}

    private android.widget.TextView getLabelView(){
        if(mLabelView == null){
            mLabelView = new android.widget.TextView(getContext());
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
                mLabelView.setTextDirection(mIsRtl ? TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR);
            mLabelView.setSingleLine(true);
            mLabelView.setDuplicateParentStateEnabled(true);
        }

        return mLabelView;
    }

    @Override
    protected void applyStyle(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
        super.applyStyle(context, attrs, defStyleAttr, defStyleRes);

        removeAllViews();

        TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,  R.styleable.Spinner, defStyleAttr, defStyleRes);

        int arrowAnimDuration = -1;
        ColorStateList arrowColor = null;
        Interpolator arrowInterpolator = null;
        boolean arrowClockwise = true;
        int dividerAnimDuration = -1;
        ColorStateList dividerColor = null;
        ColorStateList labelTextColor = null;
        int labelTextSize = -1;

        for(int i = 0, count = a.getIndexCount(); i < count; i++){
            int attr = a.getIndex(i);

            if(attr == R.styleable.Spinner_spn_labelEnable)
                mLabelEnable = a.getBoolean(attr, false);
            else if(attr == R.styleable.Spinner_spn_labelPadding)
                getLabelView().setPadding(0, 0, 0, a.getDimensionPixelSize(attr, 0));
            else if (attr == R.styleable.Spinner_spn_labelTextSize)
                labelTextSize = a.getDimensionPixelSize(attr, 0);
            else if(attr == R.styleable.Spinner_spn_labelTextColor)
                labelTextColor = a.getColorStateList(attr);
            else if(attr == R.styleable.Spinner_spn_labelTextAppearance)
                getLabelView().setTextAppearance(context, a.getResourceId(attr, 0));
            else if(attr == R.styleable.Spinner_spn_labelEllipsize){
                int labelEllipsize = a.getInteger(attr, 0);
                switch (labelEllipsize) {
                    case 1:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.START);
                        break;
                    case 2:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.MIDDLE);
                        break;
                    case 3:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.END);
                        break;
                    case 4:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.MARQUEE);
                        break;
                    default:
                        getLabelView().setEllipsize(TextUtils.TruncateAt.END);
                        break;
                }
            }
            else if(attr == R.styleable.Spinner_spn_label)
                getLabelView().setText(a.getString(attr));
            else if(attr == R.styleable.Spinner_android_gravity)
                mGravity = a.getInt(attr, 0);
            else if(attr == R.styleable.Spinner_android_minWidth)
                setMinimumWidth(a.getDimensionPixelOffset(attr, 0));
            else if(attr == R.styleable.Spinner_android_minHeight)
                setMinimumHeight(a.getDimensionPixelOffset(attr, 0));
            else if(attr == R.styleable.Spinner_android_dropDownWidth)
                mDropDownWidth = a.getLayoutDimension(attr, LayoutParams.WRAP_CONTENT);
            else if(attr == R.styleable.Spinner_android_popupBackground)
                mPopup.setBackgroundDrawable(a.getDrawable(attr));
            else if(attr == R.styleable.Spinner_android_prompt)
                mPopup.setPromptText(a.getString(attr));
            else if(attr == R.styleable.Spinner_spn_popupItemAnimation)
                mPopup.setItemAnimation(a.getResourceId(attr, 0));
            else if(attr == R.styleable.Spinner_spn_popupItemAnimOffset)
                mPopup.setItemAnimationOffset(a.getInteger(attr, 0));
            else if(attr == R.styleable.Spinner_spn_disableChildrenWhenDisabled)
                mDisableChildrenWhenDisabled = a.getBoolean(attr, false);
            else if(attr == R.styleable.Spinner_spn_arrowSwitchMode)
                mArrowAnimSwitchMode = a.getBoolean(attr, false);
            else if(attr == R.styleable.Spinner_spn_arrowAnimDuration)
                arrowAnimDuration = a.getInteger(attr, 0);
            else if(attr == R.styleable.Spinner_spn_arrowSize)
                mArrowSize = a.getDimensionPixelSize(attr, 0);
            else if(attr == R.styleable.Spinner_spn_arrowPadding)
                mArrowPadding = a.getDimensionPixelSize(attr, 0);
            else if(attr == R.styleable.Spinner_spn_arrowColor)
                arrowColor = a.getColorStateList(attr);
            else if(attr == R.styleable.Spinner_spn_arrowInterpolator){
                int resId = a.getResourceId(attr, 0);
                arrowInterpolator = AnimationUtils.loadInterpolator(context, resId);
            }
            else if(attr == R.styleable.Spinner_spn_arrowAnimClockwise)
                arrowClockwise = a.getBoolean(attr, true);
            else if(attr == R.styleable.Spinner_spn_dividerHeight)
                mDividerHeight = a.getDimensionPixelOffset(attr, 0);
            else if(attr == R.styleable.Spinner_spn_dividerPadding)
                mDividerPadding = a.getDimensionPixelOffset(attr, 0);
            else if(attr == R.styleable.Spinner_spn_dividerAnimDuration)
                dividerAnimDuration = a.getInteger(attr, 0);
            else if(attr == R.styleable.Spinner_spn_dividerColor)
                dividerColor = a.getColorStateList(attr);
        }

        a.recycle();

        if(labelTextColor != null)
            getLabelView().setTextColor(labelTextColor);

        if(labelTextSize >= 0)
            getLabelView().setTextSize(TypedValue.COMPLEX_UNIT_PX, labelTextSize);

        if(mLabelEnable)
            addView(getLabelView(), 0, new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        if(mArrowSize > 0){
            if(mArrowDrawable == null){
                if(arrowColor == null)
                    arrowColor = ColorStateList.valueOf(ThemeUtil.colorControlNormal(context, 0xFF000000));

                if(arrowAnimDuration < 0)
                    arrowAnimDuration = 0;

                mArrowDrawable = new ArrowDrawable(ArrowDrawable.MODE_DOWN, mArrowSize, arrowColor, arrowAnimDuration, arrowInterpolator, arrowClockwise);
                mArrowDrawable.setCallback(this);
            }
            else{
                mArrowDrawable.setArrowSize(mArrowSize);
                mArrowDrawable.setClockwise(arrowClockwise);

                if(arrowColor != null)
                    mArrowDrawable.setColor(arrowColor);

                if(arrowAnimDuration >= 0)
                    mArrowDrawable.setAnimationDuration(arrowAnimDuration);

                if(arrowInterpolator != null)
                    mArrowDrawable.setInterpolator(arrowInterpolator);
            }
        }
        else if(mArrowDrawable != null){
            mArrowDrawable.setCallback(null);
            mArrowDrawable = null;
        }

        if(mDividerHeight > 0){
            if(mDividerDrawable == null){
                if(dividerAnimDuration < 0)
                    dividerAnimDuration = 0;

                if(dividerColor == null){
                    int[][] states = new int[][]{
                            new int[]{-android.R.attr.state_pressed},
                            new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled},
                    };
                    int[] colors = new int[]{
                            ThemeUtil.colorControlNormal(context, 0xFF000000),
                            ThemeUtil.colorControlActivated(context, 0xFF000000),
                    };

                    dividerColor = new ColorStateList(states, colors);
                }

                mDividerDrawable = new DividerDrawable(mDividerHeight, dividerColor, dividerAnimDuration);
                mDividerDrawable.setCallback(this);
            }
            else{
                mDividerDrawable.setDividerHeight(mDividerHeight);

                if(dividerColor != null)
                    mDividerDrawable.setColor(dividerColor);

                if(dividerAnimDuration >= 0)
                    mDividerDrawable.setAnimationDuration(dividerAnimDuration);
            }
        }
        else if(mDividerDrawable != null){
            mDividerDrawable.setCallback(null);
            mDividerDrawable = null;
        }

        mTintManager = a.getTintManager();

        if (mTempAdapter != null) {
            mPopup.setAdapter(mTempAdapter);
            mTempAdapter = null;
        }

        if(mAdapter != null)
            setAdapter(mAdapter);

        if(isInEditMode()){
            TextView tv = new TextView(context, attrs, defStyleAttr);
            tv.setText("Item 1");
            super.addView(tv);
        }

        requestLayout();
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    @Override
    public void onRtlPropertiesChanged(int layoutDirection) {
        boolean rtl = layoutDirection == LAYOUT_DIRECTION_RTL;
        if(mIsRtl != rtl) {
            mIsRtl = rtl;

            if(mLabelView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
                mLabelView.setTextDirection(mIsRtl ? TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR);

            requestLayout();
        }
    }

    /**
     * @return The selected item's view.
     */
    public View getSelectedView() {
        View v = getChildAt(getChildCount() - 1);
		return v == mLabelView ? null : v;
	}

    /**
     * Set the selected position of this Spinner.
     * @param position The selected position.
     */
	public void setSelection(int position) {
		if(mAdapter != null)
			position = Math.max(0, Math.min(position, mAdapter.getCount() - 1));
		
		if(mSelectedPosition != position){
			mSelectedPosition = position;
			
			if(mOnItemSelectedListener != null)
				mOnItemSelectedListener.onItemSelected(this, getSelectedView(), position, mAdapter == null ? -1 : mAdapter.getItemId(position));
			
			onDataInvalidated();
		}
	}

    /**
     * @return The selected posiiton.
     */
{'fraction_non_alphanumeric': 0.08726963239385904, 'fraction_numerical': 0.0046810042881927395, 'mean_word_length': 2.3993546233448315, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3310598', 'n_tokens_mistral': 8800, 'n_tokens_neox': 8453, 'n_words': 1678}