package xdroid.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.database.DataSetObserver;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

public class HorizontalSpinner extends FrameLayout {
    private HorizontalScrollView mScrollView;
    private LinearLayout mLinearLayout;

    private Adapter mAdapter;
    private View mCurrentView;
    private int mCurrentIndex;
    private boolean mOpened;

    private Listener mListener;

    private final DataSetObserver mObserver;
    private final OnClickListener mOnClickListener;
    private final OnClickListener mOnSwitchListener;

    public HorizontalScrollView getScrollView() {
        return mScrollView;
    }

    public LinearLayout getLinearLayout() {
        return mLinearLayout;
    }

    public Adapter getAdapter() {
        return mAdapter;
    }

    public View getCurrentView() {
        return mCurrentView;
    }

    public void setCurrentView(View currentView) {
        mCurrentView = currentView;
    }

    public int getCurrentIndex() {
        return mCurrentIndex;
    }

    public void setCurrentIndex(int currentIndex) {
        mCurrentIndex = currentIndex;
    }

    public boolean isOpened() {
        return mOpened;
    }

    public void setOpened(boolean opened) {
        mOpened = opened;
    }

    public Listener getListener() {
        return mListener;
    }

    public void setListener(Listener listener) {
        mListener = listener;
    }

    public HorizontalSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public HorizontalSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    {
        mObserver = new DataSetObserver() {
            @Override
            public void onChanged() {
                onDataSetChanged();
            }
        };

        mOnClickListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                onItemClicked(v);
            }
        };

        mOnSwitchListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                onSwitchClicked();
            }
        };
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        mLinearLayout = new LinearLayout(getContext());
        mLinearLayout.setOrientation(LinearLayout.HORIZONTAL);

        mScrollView = new HorizontalScrollView(getContext());
        mScrollView.addView(mLinearLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mScrollView.setHorizontalScrollBarEnabled(isHorizontalScrollBarEnabled());

        addView(mScrollView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        updateState();
    }

    @Override
    public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
        super.setHorizontalScrollBarEnabled(horizontalScrollBarEnabled);

        if (mScrollView != null) {
            mScrollView.setHorizontalScrollBarEnabled(horizontalScrollBarEnabled);
        }
    }

    public void setAdapter(Adapter adapter) {
        if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mObserver);
        }

        mAdapter = adapter;

        if (mAdapter != null) {
            mAdapter.registerDataSetObserver(mObserver);
        }

        onDataSetChanged();
    }

    protected void onDataSetChanged() {
        int oldCount = mLinearLayout.getChildCount();
        int newCount = mAdapter.getCount();

        for (int i = 0, n = Math.max(oldCount, newCount); i < n; ++i) {
            View oldChild = mLinearLayout.getChildAt(i);
            if (oldChild != null) {
                oldChild.setOnClickListener(null);
            }

            View newChild = mAdapter.getView(i, oldChild, mLinearLayout);
            if (newChild != null) {
                newChild.setOnClickListener(mOnClickListener);

                if (oldChild != newChild) {
                    if (i < oldCount) {
                        mLinearLayout.removeViewAt(i);
                        mLinearLayout.addView(newChild, i);
                    } else {
                        mLinearLayout.addView(newChild);
                    }
                }
            }
        }

        updateCurrentView();
        updateState();
    }

    protected void onItemClicked(View view) {
        setCurrentItem(mLinearLayout.indexOfChild(view));

        // NOTE this may be customized by attributes
        switchState();
    }

    protected void onSwitchClicked() {
        switchState();
    }

    public void switchState() {
        mOpened = !mOpened;

        if (mListener != null) {
            mListener.onSwitched(this, mOpened);
        }

        updateState();
    }

    private void updateState() {
        if (mOpened) {
            if (mCurrentView != null) {
                mCurrentView.setVisibility(GONE);
            }

            mScrollView.setVisibility(VISIBLE);
        } else {
            if (mCurrentView != null) {
                mCurrentView.setVisibility(VISIBLE);
            }

            mScrollView.setVisibility(GONE);
        }
    }

    public void setCurrentItem(int position) {
        boolean changed = mCurrentIndex != position;

        mCurrentIndex = position;

        if (changed) {
            if (mListener != null) {
                mListener.onCurrentItemChanged(this, mCurrentIndex);
            }

            updateCurrentView();
        }
    }

    private void updateCurrentView() {
        if (mCurrentView != null) {
            mCurrentView.setOnClickListener(null);
        }

        mCurrentView = mAdapter.getView(mCurrentIndex, mCurrentView, this);

        if (mCurrentView != null) {
            if (mCurrentView.getParent() == null) {
                addView(mCurrentView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            }

            mCurrentView.setOnClickListener(mOnSwitchListener);
        }
    }

    public interface Listener {
        void onCurrentItemChanged(HorizontalSpinner parent, int position);

        void onSwitched(HorizontalSpinner parent, boolean opened);
    }
}

@@ -5790,24 +5790,21 @@
 tem(int 
-position
+index
 ) %7B%0A    
@@ -5811,23 +5811,29 @@
     
-boolean changed
+final int oldPosition
  = m
@@ -5848,22 +5848,9 @@
 ndex
- != position;%0A
+;
 %0A   
@@ -5870,24 +5870,21 @@
 Index = 
-position
+index
 ;%0A%0A     
@@ -5894,15 +5894,28 @@
 if (
-changed
+oldPosition != index
 ) %7B%0A
@@ -6004,25 +6004,17 @@
 d(this, 
-mCurrentI
+i
 ndex);%0A 
@@ -6052,32 +6052,82 @@
 eCurrentView();%0A
+            updateCurrentChildViews(oldPosition);%0A
         %7D%0A    %7D%0A
@@ -6658,32 +6658,627 @@
        %7D%0A    %7D%0A%0A
+    private void updateCurrentChildViews(int oldIndex) %7B%0A        refreshChildItem(oldIndex);%0A        refreshChildItem(mCurrentIndex);%0A    %7D%0A%0A    private void refreshChildItem(int index) %7B%0A        View convertView = mLinearLayout.getChildAt(index);%0A        View view = mAdapter.getView(index, convertView, mLinearLayout);%0A%0A        if (convertView != null) %7B%0A            if (convertView != view) %7B%0A                mLinearLayout.removeViewAt(index);%0A                mLinearLayout.addView(view, index);%0A            %7D%0A        %7D else %7B%0A            mLinearLayout.addView(view, index);%0A        %7D%0A    %7D%0A%0A
     public inter
@@ -7361,16 +7361,13 @@
 int 
-position
+index
 );%0A%0A

update expanded views in HorizontalSpinner.