package com.codeim.youliao.ui.base;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.codeim.youliao.R;
import com.codeim.youliao.TwitterApplication;
import com.codeim.youliao.data.Tweet;
import com.codeim.youliao.data.User;
import com.codeim.youliao.fanfou.Paging;
import com.codeim.youliao.fanfou.Status;
import com.codeim.youliao.http.HttpException;
import com.codeim.youliao.task.GenericTask;
import com.codeim.youliao.task.TaskAdapter;
import com.codeim.youliao.task.TaskListener;
import com.codeim.youliao.task.TaskManager;
import com.codeim.youliao.task.TaskParams;
import com.codeim.youliao.task.TaskResult;
import com.codeim.youliao.ui.module.NearbyUserArrayAdapter;
import com.codeim.youliao.ui.module.SimpleFeedback;
import com.codeim.youliao.ui.module.TweetAdapter;
import com.codeim.youliao.ui.module.UserArrayAdapter;
import com.markupartist.android.widget.PullToRefreshListView;
import com.markupartist.android.widget.PullToRefreshListView.OnRefreshListener;

public abstract class TwitterArrayBaseActivity extends TwitterListBaseActivity {
    static final String TAG = "TwitterArrayBaseActivity";
	
	protected String mNameType = "";
	protected String mMinId = "";
	
	// Views.
    protected PullToRefreshListView mTweetList;
    protected NearbyUserArrayAdapter mTweetAdapter;

    protected View mListHeader;
    protected View mListFooter;

    protected TextView loadMoreBtn;
    protected ProgressBar loadMoreGIF;
    protected TextView loadMoreBtnTop;
    protected ProgressBar loadMoreGIFTop;
	
	// Tasks.
    protected TaskManager taskManager = new TaskManager();
    private GenericTask mRetrieveTask;
    private GenericTask mGetMoreTask;
	
	private static class State {
		State(TwitterArrayBaseActivity activity) {
			allTweetList = activity.allTweetList;
			allUserList = activity.allUserList;
		}

		public ArrayList<com.codeim.youliao.data.Tweet> allTweetList;
		public ArrayList<com.codeim.youliao.data.User> allUserList;
	}
	
	// Refresh data at startup if last refresh was this long ago or greater.
    private static final long REFRESH_THRESHOLD = 5 * 60 * 1000;
	
	public abstract String getUserId();
	
	public abstract List<Status> getCategorySinceId(String maxId, int category) throws HttpException;
	public abstract List<Status> getMoreCategoryFromId(String minId, int category) throws HttpException;
	public abstract int getCategory();
	
	private ArrayList<com.codeim.youliao.data.Tweet> allTweetList;
	private ArrayList<com.codeim.youliao.data.User> allUserList;
	
	private TaskListener mRetrieveTaskListener = new TaskAdapter() {

		@Override
		public String getName() {
			return "RetrieveTask";
		}

		@Override
		public void onPostExecute(GenericTask task, TaskResult result) {
		    // 刷新按钮停止旋转
            loadMoreGIF.setVisibility(View.GONE);
            mTweetList.onRefreshComplete();
			
			if (result == TaskResult.AUTH_ERROR) {
				logout();
			} else if (result == TaskResult.OK) {
				draw();
				if (task == mRetrieveTask) {
                    goTop();
                }
			}
			//mUserList.onRefreshComplete();
			updateProgress("");
		}

		@Override
		public void onPreExecute(GenericTask task) {
			onRetrieveBegin();
		}

		@Override
		public void onProgressUpdate(GenericTask task, Object param) {
			Log.d(TAG, "onProgressUpdate");
			draw();
		}
	};
	
	@Override
	protected boolean _onCreate(Bundle savedInstanceState) {
		Log.d(TAG, "onCreate.");
		if (super._onCreate(savedInstanceState)) {

			State state = (State) getLastNonConfigurationInstance();
			if (state != null){
				allTweetList = state.allTweetList;
				allUserList = state.allUserList;
				draw();
			}else{
				doRetrieve();
			}

			return true;
		} else {
			return false;
		}
	}
	
	@Override
    protected void onPause() {
	    super.onPause();
	    mTweetAdapter.stopPlay();  // 停止语音播放
	}
	
	@Override
	protected int getLayoutId() {
		return R.layout.main;
	}
	
	@Override
    protected ListView getTweetList() {
        return mTweetList;
    }
	
	@Override
    protected TweetAdapter getTweetAdapter() {
        return mTweetAdapter;
    }

    @Override
    protected boolean useBasicMenu() {
        return true;
    }
	
	@Override
    protected void updateTweet(Tweet tweet) {
        // TODO: updateTweet() 在哪里调用的? 目前尚只支持:
        // updateTweet(String tweetId, ContentValues values)
        // setFavorited(String tweetId, String isFavorited)
        // 看是否还需要增加updateTweet(Tweet tweet)方法

        // 对所有相关表的对应消息都进行刷新（如果存在的话）
        // getDb().updateTweet(TwitterDbAdapter.TABLE_FAVORITE, tweet);
        // getDb().updateTweet(TwitterDbAdapter.TABLE_MENTION, tweet);
        // getDb().updateTweet(TwitterDbAdapter.TABLE_TWEET, tweet);
    }
	
	@Override
	protected void setupState() {
		setTitle(getActivityTitle());

		mTweetList = (PullToRefreshListView) findViewById(R.id.tweet_list);

		setupListHeader(true);

		mTweetAdapter = new NearbyUserArrayAdapter(this);
		mTweetList.setAdapter(mTweetAdapter);
		allTweetList = new ArrayList<com.codeim.youliao.data.Tweet>();
		allUserList = new ArrayList<com.codeim.youliao.data.User>();
	}
	
	@Override
	protected String getActivityTitle() {
		// TODO Auto-generated method stub
		return null;
	}
	
	/**
     * 绑定listView底部 - 载入更多 NOTE: 必须在listView#setAdapter之前调用
     */
    protected void setupListHeader(boolean addFooter) {
        // Add Header to ListView
        // mListHeader = View.inflate(this, R.layout.listview_header, null);
        // mTweetList.addHeaderView(mListHeader, null, true);
    	mTweetList.setOnRefreshListener(new OnRefreshListener(){
    		@Override
    		public void onRefresh(){
    			doRetrieve();
    		}
    	});

        // Add Footer to ListView
        mListFooter = View.inflate(this, R.layout.listview_footer, null);
        mTweetList.addFooterView(mListFooter, null, true);
        
        // Find View
        loadMoreBtn = (TextView) findViewById(R.id.ask_for_more);
        loadMoreGIF = (ProgressBar) findViewById(R.id.rectangleProgressBar);
        loadMoreBtnTop = (TextView) findViewById(R.id.ask_for_more_header);
        loadMoreGIFTop = (ProgressBar) findViewById(R.id.rectangleProgressBar_header);
    }
	
	@Override
    protected void specialItemClicked(int position) {
        // 注意 mTweetAdapter.getCount 和 mTweetList.getCount的区别
        // 前者仅包含数据的数量（不包括foot和head），后者包含foot和head
        // 因此在同时存在foot和head的情况下，list.count = adapter.count + 2
        if (position == 0) {
            // 第一个Item(header)
            loadMoreGIFTop.setVisibility(View.VISIBLE);
            doRetrieve();
        } else if (position == mTweetList.getCount() - 1) {
            // 最后一个Item(footer)
            loadMoreGIF.setVisibility(View.VISIBLE);
            doGetMore();
        }
    }
	
	public void draw() {
        // mTweetAdapter.refresh();
		// mTweetAdapter.refresh(allTweetList);
		mTweetAdapter.refresh(allUserList);
    }
	
	public void goTop() {
        Log.d(TAG, "goTop.");
        mTweetList.setSelection(1);
    }
	
	@Override
    protected Tweet getContextItemTweet(int position) {
        position = position - 1;
        // 因为List加了Header和footer，所以要跳过第一个以及忽略最后一个
        if (position >= 0 && position < mTweetAdapter.getCount()) {
            User user = (User) mTweetAdapter.getItem(position);
            if (user == null) {
                return null;
            } else {
            	Tweet tweet = User.userSwitchToTweet(user);
                return tweet;
            }
        } else {
            return null;
        }
    }
	
	@Override
	public void doRetrieve() {
		Log.d(TAG, "Attempting retrieve.");
		if (mRetrieveTask != null && mRetrieveTask.getStatus() == GenericTask.Status.RUNNING) {
			return;
		} else {
			mRetrieveTask = new RetrieveTask();
			mRetrieveTask.setFeedback(mFeedback);
			mRetrieveTask.setListener(mRetrieveTaskListener);
			mRetrieveTask.execute();
			// Add Task to manager
			taskManager.addTask(mRetrieveTask);
		}
	}
	
	public void doGetMore() {
	    Log.d(TAG, "Attempting getMore.");

        if (mGetMoreTask != null && mGetMoreTask.getStatus() == GenericTask.Status.RUNNING) {
            return;
        } else {
            mGetMoreTask = new GetMoreTask();
            mGetMoreTask.setFeedback(mFeedback);
            mGetMoreTask.setListener(mRetrieveTaskListener);
            mGetMoreTask.execute();
            // Add Task to manager
            taskManager.addTask(mGetMoreTask);
        }
	}
	
	public void updateProgress(String progress) {
		mProgressText.setText(progress);
	}

	public void onRetrieveBegin() {
		updateProgress(getString(R.string.page_status_refreshing));
	}
	
	private class RetrieveTask extends GenericTask {

		@Override
		protected TaskResult _doInBackground(TaskParams... params) {
			Log.d(TAG, "load RetrieveTask");

			List<com.codeim.youliao.fanfou.Status> statusList = null;
			try {
				statusList = getCategorySinceId(null, getCategory());
			} catch (HttpException e) {
				e.printStackTrace();
				return TaskResult.IO_ERROR;
			}
			publishProgress(SimpleFeedback.calProgressBySize(40, 20, statusList));
			allTweetList.clear();
			allUserList.clear();
			for (com.codeim.youliao.fanfou.Status status : statusList) {
				if (isCancelled()) {
					return TaskResult.CANCELLED;
				}
				Tweet tweet = Tweet.create(status);

				allTweetList.add(tweet);
				allUserList.add(Tweet.tweetSwitchToUser(tweet));
				
				mMinId = tweet.id;

				if (isCancelled()) {
					return TaskResult.CANCELLED;
				}
			}

			return TaskResult.OK;
		}
	}
	
	private class GetMoreTask extends GenericTask {
        private String _errorMsg;

        public String getErrorMsg() {
            return _errorMsg;
        }

        @Override
        protected TaskResult _doInBackground(TaskParams... params) {
            List<com.codeim.youliao.fanfou.Status> statusList;

            if (mMinId == null || mMinId == "") {
                return TaskResult.FAILED;
            }
			
			if (mMinId == "1") {
				return TaskResult.OK;
			}

            try {
            	String minId = String.valueOf(Integer.parseInt(mMinId)-1);
                statusList = getMoreCategoryFromId(minId, getCategory());
            } catch (HttpException e) {
                e.printStackTrace();
                return TaskResult.IO_ERROR;
            }

            if (statusList == null) {
                return TaskResult.FAILED;
            }

            ArrayList<Tweet> tweets = new ArrayList<Tweet>();
            publishProgress(SimpleFeedback.calProgressBySize(40, 20, tweets));

            for (com.codeim.youliao.fanfou.Status status : statusList) {
				if (isCancelled()) {
					return TaskResult.CANCELLED;
				}
				Tweet tweet = Tweet.create(status);

				allTweetList.add(tweet);
				allUserList.add(Tweet.tweetSwitchToUser(tweet));
				
				mMinId = tweet.id;

				if (isCancelled()) {
					return TaskResult.CANCELLED;
				}
			}

            return TaskResult.OK;
        }
    }
}