/**
 * 
 */
package com.codeim.youliao.ui.module;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
// import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Environment;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
// import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

// import com.codeim.youliao.ProfileActivity;
import com.codeim.youliao.R;
import com.codeim.youliao.TwitterApplication;
import com.codeim.youliao.app.Preferences;
import com.codeim.youliao.app.SimpleImageLoader;
import com.codeim.youliao.data.Tweet;
import com.codeim.youliao.data.User;
import com.codeim.youliao.db.StatusTable;
// import com.codeim.youliao.db.TwitterDatabase;
import com.codeim.youliao.fanfou.Weibo;
import com.codeim.youliao.http.HttpClient;
import com.codeim.youliao.http.Response;
import com.codeim.youliao.http.HttpException;
import com.codeim.youliao.task.TaskParams;
import com.codeim.youliao.task.TaskResult;
import com.codeim.youliao.util.DateTimeHelper;
// import com.codeim.youliao.util.TextHelper;

public class BrowseCursorAdapter extends CursorAdapter implements TweetAdapter, OnCompletionListener, OnErrorListener {
	private static final String TAG = "BrowseCursorAdapter";
	public static final String DOWNLOAD_DEFAULT_DIR = "/youliao/download";
	protected static final int REQUEST_CODE_LAUNCH_ACTIVITY = 0;
	
	public static final int IDLE_STATE = 0;
	public static final int PLAYING_STATE = 1;
	public static final int DOWNLOADING_STATE = 2;
	
	private int mState = IDLE_STATE;

	private Context mContext;
	
	protected List<Integer> mButtonSelections;
	protected List<Integer> mProgressbarPercent;
	
	private File mDownloadDir = null;
	private HttpClient mClient;
	private Integer mPlayingPosition;
	// private ViewHolder mPlayingHolder;
	private MediaPlayer mItemPlayer = null;
	private int curPosition;
	
	private String mPlayLink = null;
	List<Integer> mPositionDownloadingList = new ArrayList<Integer>();
	
	public BrowseCursorAdapter(Context context, Cursor cursor) {
		super(context, cursor);
		mContext = context;

		if (context != null) {
			mInflater = LayoutInflater.from(context);
		}

		if (cursor != null) {
			// TODO: 可使用:
			// Tweet tweet = StatusTable.parseCursor(cursor);

			mUserTextColumn = cursor.getColumnIndexOrThrow(StatusTable.USER_SCREEN_NAME);
			mTextColumn = cursor.getColumnIndexOrThrow(StatusTable.TEXT);
			mProfileImageUrlColumn = cursor.getColumnIndexOrThrow(StatusTable.PROFILE_IMAGE_URL);
			mCreatedAtColumn = cursor.getColumnIndex(StatusTable.CREATED_AT);
			// mSourceColumn = cursor.getColumnIndexOrThrow(StatusTable.SOURCE);
			// mInReplyToScreenName = cursor.getColumnIndexOrThrow(StatusTable.IN_REPLY_TO_SCREEN_NAME);
			// mRepostUserId = cursor.getColumnIndexOrThrow(StatusTable.REPOST_USER_ID);
			// mFavorited = cursor.getColumnIndexOrThrow(StatusTable.FAVORITED);
			// mThumbnailPic = cursor.getColumnIndexOrThrow(StatusTable.PIC_THUMB);
			// mMiddlePic = cursor.getColumnIndexOrThrow(StatusTable.PIC_MID);
			// mOriginalPic = cursor.getColumnIndexOrThrow(StatusTable.PIC_ORIG);
			mAudioDurationColumn = cursor.getColumnIndexOrThrow(StatusTable.AUDIO_DURATION);
			mConversationCountColumn = cursor.getColumnIndexOrThrow(StatusTable.CONVERSATION_COUNT);
			mReplyCountColumn = cursor.getColumnIndexOrThrow(StatusTable.REPLY_COUNT);
		}
		// mMetaBuilder = new StringBuilder();
		mButtonSelections = new ArrayList<Integer>();
		mProgressbarPercent = new ArrayList<Integer>();
		
		File downloadDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + DOWNLOAD_DEFAULT_DIR);
        if (!downloadDir.exists()) {
            downloadDir.mkdirs();
        }
        mDownloadDir = downloadDir;
		mClient = getApi().getHttpClient();
		
		Log.d(TAG, "TweetCursorAdapter " + getCursor().getCount());
		for (int i=0; i<getCursor().getCount(); i++) {
			mButtonSelections.add(1);
			mProgressbarPercent.add(0);
		}
	}

	private LayoutInflater mInflater;

	private int mUserTextColumn;
	private int mTextColumn;
	private int mProfileImageUrlColumn;
	private int mCreatedAtColumn;
	// private int mSourceColumn;
	// private int mInReplyToScreenName;
	// private int mRepostUserId;
	// private int mFavorited;
	// private int mThumbnailPic;
	// private int mMiddlePic;
	// private int mOriginalPic;
	private int mAudioDurationColumn;
	private int mConversationCountColumn;
	private int mReplyCountColumn;

	// private StringBuilder mMetaBuilder;

	/*
	 * private ProfileImageCacheCallback callback = new
	 * ProfileImageCacheCallback(){
	 * 
	 * @Override public void refresh(String url, Bitmap bitmap) {
	 * TweetCursorAdapter.this.refresh(); }
	 * 
	 * };
	 */
	 
	private static class ViewHolder {
		public ImageView profileImage;  //头像
		public TextView screenName;  //第一行：用户名
		public TextView distanceAndCreatedAt;  //第一行：距离与时间
		public TextView lastStatus;  //第二行：标题
		public FrameLayout playBtn;  //第三行：播放按钮
		public FrameLayout downloadingBtn;  //第三行：正在下载按钮
		public FrameLayout stopBtn;  //第三行：停止按钮
		public ProgressBar playProgressBar;  //第三行：播放进度
		public TextView totalTimeText;  //第三行：语音时间长度
		public TextView commentCountText;  //第三行：评论个数
	}

	@Override
	public View newView(Context context, Cursor cursor, ViewGroup parent) {
		View view = mInflater.inflate(R.layout.tweet_item, parent, false);
		BrowseCursorAdapter.ViewHolder holder = new ViewHolder();
		holder = new ViewHolder();
		holder.profileImage = (ImageView) view.findViewById(R.id.profile_image);
		holder.screenName = (TextView) view.findViewById(R.id.screen_name);
		holder.distanceAndCreatedAt = (TextView) view.findViewById(R.id.tweet_meta_text);
		holder.lastStatus = (TextView) view.findViewById(R.id.tweet_text);
		holder.playBtn = (FrameLayout) view.findViewById(R.id.play_btn_layout);
		holder.downloadingBtn = (FrameLayout) view.findViewById(R.id.downloading_btn_layout);
		holder.stopBtn = (FrameLayout) view.findViewById(R.id.stop_btn_layout);
		holder.playProgressBar = (ProgressBar) view.findViewById(R.id.play_progressbar);
		holder.totalTimeText = (TextView) view.findViewById(R.id.play_total_time_text);
		holder.commentCountText = (TextView) view.findViewById(R.id.comment_count_text);
		view.setTag(holder);
		return view;
	}

	@Override
	public void bindView(View view, Context context, final Cursor cursor) {
		
		final int position;
		position = cursor.getPosition();
		// Log.d(TAG, "position: " + position);
		
		final BrowseCursorAdapter.ViewHolder holder = (BrowseCursorAdapter.ViewHolder) view.getTag();

		SharedPreferences pref = TwitterApplication.mPref;  // PreferenceManager.getDefaultSharedPreferences(mContext);;
		boolean useProfileImage = pref.getBoolean(Preferences.USE_PROFILE_IMAGE, true);
		// boolean useHighlightBackground = pref.getBoolean(Preferences.HIGHLIGHT_BACKGROUND, true);
		
		holder.lastStatus.setText(cursor.getString(mTextColumn));
		String profileImageUrl = cursor.getString(mProfileImageUrlColumn);
		if (useProfileImage && !TextUtils.isEmpty(profileImageUrl)) {
			SimpleImageLoader.display(holder.profileImage, profileImageUrl);
			// holder.profileImage.setImageBitmap(TwitterApplication.mImageLoader.get(profileImageUrl, callback));
		} else {
			holder.profileImage.setVisibility(View.GONE);
		}
		
		holder.screenName.setText(cursor.getString(mUserTextColumn));
		holder.totalTimeText.setText(cursor.getString(mAudioDurationColumn) + "''");
		holder.commentCountText.setText("评:" + cursor.getString(mConversationCountColumn));
		// holder.commentCountText.setText("评:" + cursor.getString(mReplyCountColumn));
		Date createAt = DateTimeHelper.parseDateTimeFromSqlite(cursor.getString(mCreatedAtColumn));
		if (createAt != null) {
		    holder.distanceAndCreatedAt.setText(DateTimeHelper.getRelativeDate(createAt));
		}
		
		if (mButtonSelections.get(position) == 1) {
			holder.playBtn.setVisibility(View.VISIBLE);
			holder.downloadingBtn.setVisibility(View.GONE);
			holder.stopBtn.setVisibility(View.GONE);
		} else if (mButtonSelections.get(position) == 2) {
			holder.downloadingBtn.setVisibility(View.VISIBLE);
			holder.playBtn.setVisibility(View.GONE);
			holder.stopBtn.setVisibility(View.GONE);
		} else if (mButtonSelections.get(position) == 3) {
			holder.stopBtn.setVisibility(View.VISIBLE);
			holder.playBtn.setVisibility(View.GONE);
			holder.downloadingBtn.setVisibility(View.GONE);
		}
		
		holder.playProgressBar.setMax(10000);
		
		/*
		holder.profileImage.setOnClickListener(new OnClickListener() {
		    @Override
			public void onClick(View v) {
		    	Log.d(TAG, "position is " + position);
		    	if(cursor.moveToPosition(position)) {
		    	    Tweet tweet = StatusTable.parseCursor(cursor);
		    	    User user = Tweet.tweetSwitchToUser(tweet);
				    launchActivity(ProfileActivity.createIntent(user));
		    	}
			}
		});
		*/
		
		//播放按钮
		holder.playBtn.setOnClickListener(new OnClickListener() {
		    @Override
			public void onClick(View v) {
		    	cursor.moveToPosition(position);
		    	Tweet tweet = StatusTable.parseCursor(cursor);
		    	User user = Tweet.tweetSwitchToUser(tweet);
			    mPlayLink = user.attachmentUrl;
				String fileName = mPlayLink.substring(mPlayLink.lastIndexOf("/") + 1);

			    //Log.d(TAG, "position " + position);
				//lastPosition = curPosition;
				curPosition = position;
				
				//lastView = curView;
				//curView = v;
				
				// ViewHolder itemHolder = holder;
				
				if (mState == PLAYING_STATE) {  //其中一个item正在播放，需要先停止这个item
				    stopPlay();
				}
				
				//if (mPositionViewHolder.containsKey(position)) {  //正在下载相同position的语音
			    if (mPositionDownloadingList.contains(position)) {
					//因为已经在下载所以仅仅切换按钮就可以
					mButtonSelections.set(position, 2);
			        notifyDataSetChanged();	
				} else {
					File downloadFile = new File(mDownloadDir.getAbsolutePath() + "/" + fileName);
					if (downloadFile.exists()) {  //语音已经存在，直接播放
					    // mPlayingHolder = itemHolder;
						startPlay(position, downloadFile.getAbsolutePath());
					} else {  //语音不存在，需要下载
						downloadAudio(position, fileName, mPlayLink);
					}
				}
			}
		});
		
		//正在下载
		holder.downloadingBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
			    //Log.d(TAG, "position " + position);
				curPosition = position;
		
				mButtonSelections.set(position, 1);
			    notifyDataSetChanged();	
			}
		});
		
		//停止按钮
		holder.stopBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
			    //Log.d(TAG, "position " + position);
				curPosition = position;
				//curView = v;
				stopPlay();
			}
		});
	}
	
	public void startPlay(int position, String downloadFilePath) {
		//Log.d(TAG, "downloadFile: " + downloadFilePath);
		
        //stopPlay();

        mItemPlayer = new MediaPlayer();
        try {
            mItemPlayer.setDataSource(downloadFilePath);
            mItemPlayer.setOnCompletionListener(this);
            mItemPlayer.setOnErrorListener(this);
            mItemPlayer.prepare();
            mItemPlayer.seekTo(0);
            mItemPlayer.start();
        } catch (IllegalArgumentException e) {
            mItemPlayer = null;
            return;
        } catch (IOException e) {
            mItemPlayer = null;
            return;
        }
        
		mPlayingPosition = position;
        
        mButtonSelections.set(position, 3);
        mProgressbarPercent.set(position, 0);
        notifyDataSetChanged();
        
		mState = PLAYING_STATE;
		//updateProgressBar(position);
    }
	
	public void stopPlay() {
        if (mItemPlayer == null) // we were not in playback
            return;
        //Log.d(TAG, "stopPlay");
        mItemPlayer.stop();
        mItemPlayer.release();
        mItemPlayer = null;
        
        mButtonSelections.set(mPlayingPosition, 1);
        notifyDataSetChanged();

		mPlayingPosition = null;
		// mPlayingHolder = null;

        mState = IDLE_STATE;
    }
	
	private void downloadAudio(Integer position, String fileName, String audioURL) {
		//if (mDownloadAudioTask != null && mDownloadAudioTask.getStatus() == AsyncTask.Status.RUNNING) {
		//	return;
		//} else {
			DownloadAudioTask downloadAudioTask = new DownloadAudioTask(position, fileName);

			TaskParams params = new TaskParams();
			
			params.put("filename_str", fileName);
			params.put("audio_url", audioURL);
			downloadAudioTask.execute(params);
		//}
	}
	
	protected void launchActivity(Intent intent) {
		mContext.startActivity(intent);
	}
	
	public Weibo getApi() {
		return TwitterApplication.mApi;
	}
	
	private InputStream getInputStream(String url) throws HttpException, IOException {
	    Response res = mClient.get(url);
		InputStream is = res.asStream();
		
		return is;
	}

	// @Override
	public void refresh() {
	    Log.d(TAG, "refresh: " + getCursor().getCount());
		getCursor().requery();
		for (int i=0; i<getCursor().getCount(); i++) {
			mButtonSelections.add(1);
			mProgressbarPercent.add(0);
		}
	}
	
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
        stopPlay();
        return true;
    }

	@Override
    public void onCompletion(MediaPlayer mp) {
        stopPlay();
    }
	
	private class DownloadAudioTask extends AsyncTask<TaskParams, Object, TaskResult> {
		
		private Integer position;
		private String downloadFilePath;
		
		public DownloadAudioTask(Integer position, String fileName) {
			super();
			this.position = position;
			this.downloadFilePath = mDownloadDir.getAbsolutePath() + "/" + fileName;
		}
	    
		@Override
		protected TaskResult doInBackground(TaskParams... params) {
		    TaskParams param = params[0];
			try {
				String fileName = param.getString("filename_str");
			    String audioURL = param.getString("audio_url");
				if (!TextUtils.isEmpty(audioURL)) {
				    InputStream is = getInputStream(audioURL);
				    File downloadFile = new File(mDownloadDir.getAbsolutePath() + "/" + fileName);
				    downloadFile.createNewFile();
					OutputStream out = null;
					out = new FileOutputStream(downloadFile);
					int temp = 0;
			        byte[] data = new byte[1024];
			        while((temp = is.read(data))!=-1){
				        out.write(data, 0, temp);
			        }
			        out.flush();
			        is.close();
			        out.close();
				}
			} catch (HttpException e) {
				Log.e(TAG, e.getMessage(), e);
				return TaskResult.IO_ERROR;
			} catch (IOException e) {
				Log.e(TAG, e.getMessage(), e);
				return TaskResult.IO_ERROR;
			} 
			return TaskResult.OK;
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			//mPositionViewHolder.put(position, holder);
			//holder.playBtn.setVisibility(View.GONE);
			//holder.downloadingBtn.setVisibility(View.VISIBLE);
			mPositionDownloadingList.add(position);
			mButtonSelections.set(position, 2);
			notifyDataSetChanged();
		}
		
		@Override
		protected void onPostExecute(TaskResult result) {
			super.onPostExecute(result);
			
			//mPositionViewHolder.remove(position);
			mPositionDownloadingList.remove(position);
			
			if (result == TaskResult.AUTH_ERROR) {
				
            } else if (result == TaskResult.OK) {
            	if ((position == curPosition) && (mButtonSelections.get(position) == 2)) { 
            		//holder.downloadingBtn.setVisibility(View.GONE);
            		//holder.playBtn.setVisibility(View.VISIBLE);
            		mButtonSelections.set(position, 3);
            		notifyDataSetChanged();
            		startPlay(position, downloadFilePath);
            	} else {
            		//holder.downloadingBtn.setVisibility(View.GONE);
            		//holder.playBtn.setVisibility(View.VISIBLE);
            		mButtonSelections.set(position, 1);
            		notifyDataSetChanged();
            	}
            } else if (result == TaskResult.IO_ERROR) {
                
            } else {
                // do nothing
            }
		}
		
		@Override
		protected void onProgressUpdate(Object... values) {
			super.onProgressUpdate(values);
		}
	}
}