package com.codeim.youliao.ui.module;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
//import java.util.HashMap;
import java.util.List;
import java.io.InputStream;

//import android.app.AlertDialog;
//import android.app.AlertDialog.Builder;
//import android.app.Dialog;
import android.content.Context;
//import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
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.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
//import android.widget.Toast;

import com.codeim.youliao.R;
import com.codeim.youliao.TwitterApplication;
import com.codeim.youliao.StatusWithCommentActivity;
import com.codeim.youliao.app.LazyImageLoader.ImageLoaderCallback;
import com.codeim.youliao.app.Preferences;
import com.codeim.youliao.data.Tweet;
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.NearbyActivity;

/*
 * 用于用户的Adapter
 */
public class CommentArrayAdapter extends BaseAdapter implements TweetAdapter, OnCompletionListener, OnErrorListener {
	private static final String TAG = "CommentArrayAdapter";
	
	public static final String DOWNLOAD_DEFAULT_DIR = "/youliao/download";
	
	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;

	protected ArrayList<Tweet> mTweets;
	private Context mContext;
	protected LayoutInflater mInflater;
	
	// private ListView listView;
	
	//protected List<HashMap<String, Boolean>> mButtonStatuses;
	protected List<Integer> mButtonSelections;
	protected List<Integer> mProgressbarPercent;
	
	private MediaPlayer mItemPlayer = null;
	private String mPlayLink = null;
	
	//private int lastPosition;
	private int curPosition;
	//private View lastView = null;
	//private View curView = null;
	
	//private File mDownloadFile = null;
	private File mDownloadDir = null;
	
	//private View mPlayingView;
	private Integer mPlayingPosition;
	
	private ViewHolder mPlayingHolder;
	
	// ArrayList<HashMap<Integer, View>> mlistPositionView = new ArrayList<HashMap<Integer, View>>();
	// HashMap<Integer, ViewHolder> mPositionViewHolder = new HashMap<Integer, ViewHolder>();
	List<Integer> mPositionDownloadingList = new ArrayList<Integer>();
	
	private HttpClient mClient;
	
	//private DownloadAudioTask mDownloadAudioTask;
	
	private final Handler mHandler = new Handler();
	
	private Runnable mUpdateSeekBar = new Runnable() {
        @Override
        public void run() {
		    if (mPlayingPosition != null) {
                //updateProgressBar(mPlayingPosition);
		    }
        }
    };
	
	private ImageLoaderCallback callback = new ImageLoaderCallback() {
		@Override
		public void refresh(String url, Bitmap bitmap) {
			CommentArrayAdapter.this.refresh();
		} 
	};

	public CommentArrayAdapter(Context context) {
		mTweets = new ArrayList<Tweet>();
		mContext = context;
		mInflater = LayoutInflater.from(mContext);
		//mButtonStatuses = new ArrayList<HashMap<String, Boolean>>();
		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();
	}

	@Override
	public int getCount() {
		return mTweets.size();
	}

	@Override
	public Object getItem(int position) {
		return mTweets.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	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;  //第三行：语音时间长度
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
	    // Log.d(TAG, "getView position: " + position);
		View view;

		SharedPreferences pref = TwitterApplication.mPref; // PreferenceManager.getDefaultSharedPreferences(mContext);
		boolean useProfileImage = pref.getBoolean(Preferences.USE_PROFILE_IMAGE, true);
		
		view = convertView;
		final ViewHolder holder;

		if (view == null) {
			view = mInflater.inflate(R.layout.comment_item, parent, false);

			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);
			view.setTag(holder);
		} else {
			holder = (ViewHolder) view.getTag();
		}

		final Tweet tweet = mTweets.get(position);
		String profileImageUrl = tweet.profileImageUrl;
		mPlayLink = tweet.attachmentUrl;
		// Log.d(TAG, "mPlayLink = " + mPlayLink);
		if (useProfileImage) {
			if (!TextUtils.isEmpty(profileImageUrl)) {
				holder.profileImage.setImageBitmap(TwitterApplication.mImageLoader.get(profileImageUrl, callback));
			}
		} else {
			holder.profileImage.setVisibility(View.GONE);
		}
		// holder.profileImage.setImageBitmap(ImageManager.mDefaultBitmap);
		holder.screenName.setText(tweet.screenName);
		if (tweet.createdAt != null) {
			holder.distanceAndCreatedAt.setText(DateTimeHelper.getRelativeDate(tweet.createdAt));
		}
		// holder.lastStatus.setText(tweet.text);
		holder.totalTimeText.setText(String.valueOf(tweet.audioDuration) + "''");
		
		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.playProgressBar.setProgress(mProgressbarPercent.get(position));
		
		//播放按钮
		holder.playBtn.setOnClickListener(new OnClickListener() {
		    @Override
			public void onClick(View v) {
		    	((StatusWithCommentActivity) mContext).stopPlay();
			    // Log.d(TAG, "playBtn position " + position);
			    mPlayLink = tweet.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();
			}
		});

		return view;
	}
	
	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);
    }
	
	/*
	private void updateProgressBar(int position) {
        if (mState == PLAYING_STATE) {
        	//playProgressBar.setProgress(mItemPlayer.getCurrentPosition());
        	float percent = (float) mItemPlayer.getCurrentPosition()/mItemPlayer.getDuration();
        	//Log.d(TAG, "Play percent is " + percent + "  " + (int)(10000*percent) + "  " + mItemPlayer.getCurrentPosition() + "  " + mItemPlayer.getDuration());
        	mProgressbarPercent.set(position, (int)(10000*percent));
        	//notifyDataSetChanged();
        	updateProgressBarView(position, (int)(10000*percent));
            mHandler.postDelayed(mUpdateSeekBar, 500);
        }
    }
	
	private void updateProgressBarView(int position, int progress) {
		//int visiblePosition = listView.getFirstVisiblePosition();
		//Log.d(TAG, "visiblePosition = " + visiblePosition + "   positon = " + position);
		//View itemView = listView.getChildAt(position);
		//ProgressBar itemProgressBar = (ProgressBar) itemView.findViewById(R.id.play_progressbar);
		ProgressBar itemProgressBar = mPlayingHolder.playProgressBar;
		itemProgressBar.setProgress(progress);
	}
	*/
	
	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;
    }

	public void refresh(ArrayList<Tweet> tweets) {
		mTweets = (ArrayList<Tweet>) tweets.clone();
		
		for (int i=0; i<mTweets.size(); i++) {
			//Log.d(TAG, "i = " + i);
			//mButtonStatuses.get(i).put(key, value);
			mButtonSelections.add(1);
			mProgressbarPercent.add(0);
		}
		
		notifyDataSetChanged();
	}

	@Override
	public void refresh() {
		notifyDataSetChanged();
	}
	
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
        stopPlay();
        return true;
    }

	@Override
    public void onCompletion(MediaPlayer mp) {
        stopPlay();
    }
	
	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;
	}
	
	/*
	public void setListView(ListView listView) {
		this.listView = listView;
	}
	*/
	
	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);
		//}
	}
	
	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);
		}
	}
}
