public final class InnerConstants implements GotyeChatListener, GotyeLoginListener{
	
	
	public static final int START_FROM_MAIN = 0;
	public static final int START_FROM_ROOM = 1;
	
	static String configName = "gotye_config";
	static GotyeAPI api;
	public static GotyeUser curUserInfo;
	public static Bitmap curUserHead;
	
	public static ArrayList<Activity> activitys = new ArrayList<Activity>();
	public static GotyeTargetable miniTarget;
	public static boolean isMin = false;
	public static boolean isFirstEnterRoom = true;
	public static int startFrom = START_FROM_MAIN;
	@SuppressWarnings("rawtypes")
	
	public static String curMessageID = null;
	public static ArrayList<GotyeMessageProxy> targetMessageList = new ArrayList<GotyeMessageProxy>();
	public static InnerConstants instance = new InnerConstants();
	public static Context context;
	
	public static void finishAllActivity(){
		for(Activity activity : activitys){
			if(!activity.isFinishing()){
				activity.finish();
			}
		}
		activitys.clear();
	}
	
	public static void addMessage(GotyeMessageProxy msg, GotyeMessageListAdapter adapter){
		addMessage(msg, adapter, false);
	}
	
	public static void addMessage(GotyeMessageProxy msg, GotyeMessageListAdapter adapter, boolean front){
		if(msg.get().getTarget() instanceof GotyeRoom){
			GotyeRoom room = (GotyeRoom) msg.get().getTarget();
			GotyeRoom cur = (GotyeRoom) miniTarget;
			if(room == null || cur == null || room.getRoomID() != cur.getRoomID()){
				return ;
			}
		}else {
			return;
		}
		
		if(targetMessageList.size() == 0){
			
			msg.setShowTime(new PrettyDateFormat("# a HH:mm", "yyyy-MM-dd HH:mm").format(TimeUtil.secondsToDateFromServer(msg.get().getCreateTime(), "yyyy-MM-dd HH:mm")));
		}else {
			GotyeMessageProxy last = targetMessageList.get(targetMessageList.size() - 1);
			
			long lastTime = last.get().getCreateTime();
			if(msg.get().getCreateTime() - lastTime >= 300){
				msg.setShowTime(new PrettyDateFormat("# a HH:mm", "yyyy-MM-dd HH:mm").format(TimeUtil.secondsToDateFromServer(msg.get().getCreateTime(), "yyyy-MM-dd HH:mm")));
			}
		}
		if(front){
			targetMessageList.add(0, msg);
		}else {
			targetMessageList.add(msg);
		}
		
	}
	
	public static void addAllMessage(List<GotyeMessageProxy>  msgs, GotyeMessageListAdapter adapter){
		if(msgs.size() == 0){
			return;
		}
		
		GotyeMessageProxy newLast = null;
		for(int i = 0;i < msgs.size();i++){
			if(i == 0){
				GotyeMessageProxy firstMessage = newLast = msgs.get(0);
				firstMessage.setShowTime(new PrettyDateFormat("# a HH:mm", "yyyy年MM月dd日 HH:mm").format(TimeUtil.secondsToDateFromServer(firstMessage.get().getCreateTime(), "yyyy年MM年dd日 HH:mm")));
			}else {
				GotyeMessageProxy last = msgs.get(i - 1);
				GotyeMessageProxy msg = newLast = msgs.get(i);
				long lastTime = last.get().getCreateTime();
				if(msg.get().getCreateTime() - lastTime >= 300){
//					msg.setShowTime(TimeUtil.secondsToStringFromServer(msg.get().getCreateTime(), "yyyy-MM-dd HH:mm"));
					msg.setShowTime(new PrettyDateFormat("# a HH:mm", "yyyy年MM月dd日 HH:mm").format(TimeUtil.secondsToDateFromServer(msg.get().getCreateTime(), "yyyy年MM年dd日 HH:mm")));
				}
			}
		}
		if(newLast == null){
			return;
		}
		
		targetMessageList.addAll(0, msgs);
		
	}
	
	public static void clearMessage(){
		targetMessageList.clear();
		curMessageID = null;
	}

	@Override
	public void onSendMessage(String appKey, String username,
			GotyeMessage msg, int errorCode) {
		
		GotyeMessageProxy proxy = GotyeMessageActivity.sendMap.remove(msg.getMessageID());
		if(proxy != null){
			if (errorCode == GotyeStatusCode.STATUS_OK) {
				proxy.setSendState(GotyeMessageProxy.SUCCESS);

			}else if (errorCode == GotyeStatusCode.STATUS_FORBIDDEN_SEND_MSG){
				proxy.setSendState(GotyeMessageProxy.FORBIDDEN);
			}else {
				proxy.setSendState(GotyeMessageProxy.FAILED);
			}
		}
	}

	@Override
	public void onReceiveMessage(String appKey, String username,
			GotyeMessage msg) {
		if(msg instanceof GotyeVoiceMessage){
			addMessage(new GotyeVoiceMessageProxy((GotyeVoiceMessage) msg), null);
		}else if(msg instanceof GotyeTextMessage){
			addMessage(new GotyeTextMessageProxy((GotyeTextMessage) msg), null);
		}else if(msg instanceof GotyeImageMessage){
			byte[] thumb = ((GotyeImageMessage) msg).getThumbnailData();
			if(thumb == null){
				thumb = new byte[0];
			}
			thumb = resizeBitmap(thumb);
			ResourceManager.getInstance(context).getImageCacheService().putImageData(((GotyeImageMessage) msg).getDownloadUrl(), ImageCacheService.TYPE_IMAGE, thumb);
			((GotyeImageMessage) msg).setThumbnailData(null);
			addMessage(new GotyeImageMessageProxy((GotyeImageMessage) msg), null);
		}
	}
	
	public static byte[] resizeBitmap(byte[] data){
		Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
		if(bitmap == null){
			return new byte[0];
		}

		int minWidth = GraphicsUtil.dipToPixel(50);
		int minHeight = GraphicsUtil.dipToPixel(50);
		
        float imageWidth = bitmap.getWidth();
        float imageHeight = bitmap.getHeight();
        
        if (imageWidth < minWidth) {
            imageHeight = imageHeight / imageWidth * minWidth;
            imageWidth = minWidth;
        }
        
        if (imageHeight < minHeight) {
            imageWidth = imageWidth / imageHeight * minHeight;
            imageHeight = minHeight;
        }
        
		// create the new Bitmap object
		Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, (int)imageWidth, (int)imageHeight, true);
		if(resizedBitmap == null){
			return new byte[0];
		}
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		resizedBitmap.compress(CompressFormat.JPEG, 100, bout);

		return bout.toByteArray();
		  
	}
	
	static HashMap<String, Object> lastUser(){
		
		HashMap<String, Object> map = new HashMap<String, Object>();
		SharedPreferences sp = context.getSharedPreferences(InnerConstants.configName, 0);
		
		map.put(GotyeSDK.PRO_USERNAME, sp.getString(GotyeSDK.PRO_USERNAME, null));
		map.put("nickname", sp.getString("nickname", null));
		map.put("sex", sp.getInt("sex", GotyeSex.MAN.ordinal()));
		map.put("avatar", sp.getString("avatar", null));
		return map;
	}
	
	static void saveUser(String appKey, String username, String nickName, GotyeSex sex, Bitmap head){
		SharedPreferences sp = context.getSharedPreferences(InnerConstants.configName, 0);
		Editor ed = sp.edit();
		ed.putString(GotyeSDK.PRO_APP_KEY, appKey);
		ed.putString(GotyeSDK.PRO_USERNAME, username);
		ed.putString("nickname", nickName);
		ed.putInt("sex", sex.ordinal());
		
		if(head != null){
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			head.compress(CompressFormat.JPEG, 100, bout);
			byte[] imageData = bout.toByteArray();
			String key = StringUtil.getString(DataUtil.getMD5Str(imageData));
			GotyeFileCache.getFileCacheByUser().put(context, GotyeFileCache.CACHE_IMAGE, key, imageData);
			ed.putString("avatar", key);
		}else {
			ed.putString("avatar", null);
		}
		ed.commit();
	}
	
	public static Bitmap getChatBackground(){
		SharedPreferences sp = context.getSharedPreferences(InnerConstants.configName, 0);
		String key = sp.getString("chatbackground", null);
		if(key == null){
			return null;
		}
		CachedData data = GotyeFileCache.getFileCacheByUser().get(context, GotyeFileCache.CACHE_IMAGE, key);
		if(data == null){
			return null;
		}
		return BitmapFactory.decodeByteArray(data.mData, data.mOffset, data.mData.length - data.mOffset);
	}
	
	public static void resetAccount(){
		SharedPreferences sp = context.getSharedPreferences(InnerConstants.configName, 0);
		sp.edit().clear().commit();
		api = null;
		GotyeSDK.getInstance().api = null;
		GotyeSDK.getInstance().curUsername = null;
	}
	
	public static GotyeAPI getAPI(Context context){
		return api;
	}

	@Override
	public void onLogin(String appKey, String username, int errorCode) {
		try{
			if(username.equals(api.getUsername()) && errorCode == GotyeStatusCode.STATUS_OK){
				api.modifyUserInfo(InnerConstants.curUserInfo, InnerConstants.curUserHead);
				
				GotyeTargetable target = (GotyeTargetable) miniTarget;
				if(target != null && target instanceof GotyeRoom){
					api.enterRoom((GotyeRoom) target);
				}
			}
		}catch(Exception e){
		}
	}

	@Override
	public void onLogout(String appKey, String username, int errorCode) {
	}

	@Override
	public void onGetHistoryMessages(String appKey, String username,
			GotyeTargetable target, String msgID, List<GotyeMessage> msgs, boolean contain,
			int code) {
	}

	@Override
	public void onStartTalkTo(String appKey, String username,
			GotyeTargetable target, WhineMode mode, boolean isRealTime) {
	}

	@Override
	public void onStopTalkTo(String appKey, String username,
			GotyeTargetable target, WhineMode mode, boolean isRealTime,
			GotyeVoiceMessage voiceMessage, long duration, int code) {
	}

	@Override
	public void onReceiveVoiceMessage(String appKey, String username,
			GotyeTargetable sender, GotyeTargetable target) {
	}

	@Override
	public void onVoiceMessageEnd(String appKey, String username,
			GotyeTargetable sender, GotyeTargetable target) {
	}

} public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView> {

	private LoadingLayout mHeaderLoadingView;
	private LoadingLayout mFooterLoadingView;

	private FrameLayout mLvFooterLoadingFrame;

	private boolean mListViewExtrasEnabled;

	public PullToRefreshListView(Context context) {
		super(context);
	}

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

	public PullToRefreshListView(Context context, Mode mode) {
		super(context, mode);
	}

	public PullToRefreshListView(Context context, Mode mode, AnimationStyle style) {
		super(context, mode, style);
	}

	@Override
	public final Orientation getPullToRefreshScrollDirection() {
		return Orientation.VERTICAL;
	}

	@Override
	protected void onRefreshing(final boolean doScroll) {
		/**
		 * If we're not showing the Refreshing view, or the list is empty, the
		 * the header/footer views won't show so we use the normal method.
		 */
		ListAdapter adapter = mRefreshableView.getAdapter();
		if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
			super.onRefreshing(doScroll);
			return;
		}

		super.onRefreshing(false);

		final LoadingLayout origLoadingView, listViewLoadingView, oppositeListViewLoadingView;
		final int selection, scrollToY;

		switch (getCurrentMode()) {
			case MANUAL_REFRESH_ONLY:
			case PULL_FROM_END:
				origLoadingView = getFooterLayout();
				listViewLoadingView = mFooterLoadingView;
				oppositeListViewLoadingView = mHeaderLoadingView;
				selection = mRefreshableView.getCount() - 1;
				scrollToY = getScrollY() - getFooterSize();
				break;
			case PULL_FROM_START:
			default:
				origLoadingView = getHeaderLayout();
				listViewLoadingView = mHeaderLoadingView;
				oppositeListViewLoadingView = mFooterLoadingView;
				selection = mRefreshableView.getSelectedItemPosition() - 1;
				scrollToY = getScrollY() + getHeaderSize();
				break;
		}

		// Hide our original Loading View
		origLoadingView.reset();
		origLoadingView.hideAllViews();

		// Make sure the opposite end is hidden too
		oppositeListViewLoadingView.setVisibility(View.GONE);

		// Show the ListView Loading View and set it to refresh.
		listViewLoadingView.setVisibility(View.VISIBLE);
		listViewLoadingView.refreshing();

		if (doScroll) {
			// We need to disable the automatic visibility changes for now
			disableLoadingLayoutVisibilityChanges();

			// We scroll slightly so that the ListView's header/footer is at the
			// same Y position as our normal header/footer
			setHeaderScroll(scrollToY);

			// Make sure the ListView is scrolled to show the loading
			// header/footer
			mRefreshableView.setSelection(selection);

			// Smooth scroll as normal
			smoothScrollTo(0);
		}
	}

	@Override
	protected void onReset() {
		/**
		 * If the extras are not enabled, just call up to super and return.
		 */
		if (!mListViewExtrasEnabled) {
			super.onReset();
			return;
		}

		final LoadingLayout originalLoadingLayout, listViewLoadingLayout;
		final int scrollToHeight, selection;
		final boolean scrollLvToEdge;

		switch (getCurrentMode()) {
			case MANUAL_REFRESH_ONLY:
			case PULL_FROM_END:
				originalLoadingLayout = getFooterLayout();
				listViewLoadingLayout = mFooterLoadingView;
				selection = mRefreshableView.getCount() - 1;
				scrollToHeight = getFooterSize();
				scrollLvToEdge = Math.abs(mRefreshableView.getLastVisiblePosition() - selection) <= 1;
				break;
			case PULL_FROM_START:
			default:
				originalLoadingLayout = getHeaderLayout();
				listViewLoadingLayout = mHeaderLoadingView;
				scrollToHeight = -getHeaderSize();
				selection = mRefreshableView.getSelectedItemPosition() - 1;
				scrollLvToEdge = false;
				break;
		}

		// If the ListView header loading layout is showing, then we need to
		// flip so that the original one is showing instead
		if (listViewLoadingLayout.getVisibility() == View.VISIBLE) {

			// Set our Original View to Visible
			originalLoadingLayout.showInvisibleViews();

			// Hide the ListView Header/Footer
			listViewLoadingLayout.setVisibility(View.GONE);

			/**
			 * Scroll so the View is at the same Y as the ListView
			 * header/footer, but only scroll if: we've pulled to refresh, it's
			 * positioned correctly
			 */
			if (scrollLvToEdge && getState() != State.MANUAL_REFRESHING) {
				mRefreshableView.setSelection(selection);
				setHeaderScroll(scrollToHeight);
			}
		}

		// Finally, call up to super
		super.onReset();
	}

	@Override
	protected LoadingLayoutProxy createLoadingLayoutProxy(final boolean includeStart, final boolean includeEnd) {
		LoadingLayoutProxy proxy = super.createLoadingLayoutProxy(includeStart, includeEnd);

		if (mListViewExtrasEnabled) {
			final Mode mode = getMode();

			if (includeStart && mode.showHeaderLoadingLayout()) {
				proxy.addLayout(mHeaderLoadingView);
			}
			if (includeEnd && mode.showFooterLoadingLayout()) {
				proxy.addLayout(mFooterLoadingView);
			}
		}

		return proxy;
	}

	protected ListView createListView(Context context, AttributeSet attrs) {
		final ListView lv;
		if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
			lv = new InternalListViewSDK9(context, attrs);
		} else {
			lv = new InternalListView(context, attrs);
		}
		return lv;
	}

	@Override
	protected ListView createRefreshableView(Context context, AttributeSet attrs) {
		ListView lv = createListView(context, attrs);
		// Set it to this so it can be used in ListActivity/ListFragment
		lv.setId(android.R.id.list);
		return lv;
	}

	@Override
	protected void handleStyledAttributes(TypedArray a) {
		super.handleStyledAttributes(a);

		mListViewExtrasEnabled = true;

		if (mListViewExtrasEnabled) {
			final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
					FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL);

			// Create Loading Views ready for use later
			FrameLayout frame = new FrameLayout(getContext());
			mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a);
			mHeaderLoadingView.setVisibility(View.GONE);
			frame.addView(mHeaderLoadingView, lp);
			mRefreshableView.addHeaderView(frame, null, false);

			mLvFooterLoadingFrame = new FrameLayout(getContext());
			mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a);
			mFooterLoadingView.setVisibility(View.GONE);
			mLvFooterLoadingFrame.addView(mFooterLoadingView, lp);

			/**
			 * If the value for Scrolling While Refreshing hasn't been
			 * explicitly set via XML, enable Scrolling While Refreshing.
			 */
			if (!a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {
				setScrollingWhileRefreshingEnabled(true);
			}
		}
	}

	@TargetApi(9)
	final class InternalListViewSDK9 extends InternalListView {

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

		@Override
		protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
				int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

			final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
					scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);

			// Does all of the hard work...
//			OverscrollHelper.overScrollBy(PullToRefreshListView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent);

			return returnValue;
		}
	}

	protected class InternalListView extends ListView implements EmptyViewMethodAccessor {

		private boolean mAddedLvFooter = false;

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

		@Override
		protected void dispatchDraw(Canvas canvas) {
			/**
			 * This is a bit hacky, but Samsung's ListView has got a bug in it
			 * when using Header/Footer Views and the list is empty. This masks
			 * the issue so that it doesn't cause an FC. See Issue #66.
			 */
			try {
				super.dispatchDraw(canvas);
			} catch (IndexOutOfBoundsException e) {
				e.printStackTrace();
			}
		}

		@Override
		public boolean dispatchTouchEvent(MotionEvent ev) {
			/**
			 * This is a bit hacky, but Samsung's ListView has got a bug in it
			 * when using Header/Footer Views and the list is empty. This masks
			 * the issue so that it doesn't cause an FC. See Issue #66.
			 */
			try {
				return super.dispatchTouchEvent(ev);
			} catch (IndexOutOfBoundsException e) {
				e.printStackTrace();
				return false;
			}
		}

		@Override
		public void setAdapter(ListAdapter adapter) {
			// Add the Footer View at the last possible moment
			if (null != mLvFooterLoadingFrame && !mAddedLvFooter) {
				addFooterView(mLvFooterLoadingFrame, null, false);
				mAddedLvFooter = true;
			}

			super.setAdapter(adapter);
		}

		@Override
		public void setEmptyView(View emptyView) {
			PullToRefreshListView.this.setEmptyView(emptyView);
		}

		@Override
		public void setEmptyViewInternal(View emptyView) {
			super.setEmptyView(emptyView);
		}

	}

} public class GotyeImageMessageProxy extends GotyeMessageProxy<GotyeImageMessage> {

	public GotyeImageMessageProxy(GotyeImageMessage message) {
		super(message);
	}

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	private String savePath;
} public class GotyeMessageProxy<T extends GotyeMessage> {

	public static final int SUCCESS = 200;
	public static final int FAILED = 201;
	public static final int FORBIDDEN = 202;
	
	private T message;
	private String showTime;
	private int sendState;

	public GotyeMessageProxy(T message) {
		super();
		this.message = message;
	}
	
	public T get(){
		return message;
	}
	
	public boolean isSendBySelf() {
		return isSendBySelf;
	}

	public void setSendBySelf(boolean isSendBySelf) {
		this.isSendBySelf = isSendBySelf;
	}

	public String getShowTime() {
		return showTime;
	}

	public void setShowTime(String showTime) {
		this.showTime = showTime;
	}


	public int getSendState() {
		return sendState;
	}

	public void setSendState(int sendState) {
		this.sendState = sendState;
	}


	private boolean isSendBySelf = false;
} public class GotyeVoiceMessageProxy extends GotyeMessageProxy<GotyeVoiceMessage>{
	
	public GotyeVoiceMessageProxy(GotyeVoiceMessage message) {
		super(message);
	}

	private String savePath;
	private boolean isNewRecoder = false;
	private boolean isDownloading = false;
	private boolean downloadFailed = false;

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	public boolean isNewRecoder() {
		return isNewRecoder;
	}

	public void setNewRecoder(boolean isNewRecoder) {
		this.isNewRecoder = isNewRecoder;
	}

	public boolean isDownloading() {
		return isDownloading;
	}

	public void setDownloading(boolean isDownloading) {
		this.isDownloading = isDownloading;
	}

	public boolean isDownloadFailed() {
		return downloadFailed;
	}

	public void setDownloadFailed(boolean downloadFailed) {
		this.downloadFailed = downloadFailed;
	}
	
} public class EmotiAdapter extends BaseAdapter {
	private Context mContext;
	private Resources mResources;
	private List<Integer> data;
	private HashMap<String, Integer> faceMap;
	String[] icons;
	ImageCache cache;

	
	public EmotiAdapter(Context context, Resources resources) {
		this.mContext = context;
		this.mResources = resources;
		
		cache = new ImageCache();
		data = new ArrayList<Integer>();
		faceMap = new HashMap<String, Integer>();
		Resources rs = resources;
		TypedArray ty = rs.obtainTypedArray(R.array.gotye_smiley_resid_array);
		icons = rs.getStringArray(R.array.gotye_smiley_resid_array);
		for(int i = 0;i < icons.length;i++){
			data.add(ty.getResourceId(i, R.drawable.gotye_smiley_1));
			faceMap.put(icons[i], ty.getResourceId(i, R.drawable.gotye_smiley_1));
		}
		ty.recycle();
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		ImageView i;

		if (convertView == null) {
			i = new ImageView(mContext);
			i.setAdjustViewBounds(true);
			i.setLayoutParams(new GridView.LayoutParams(
						LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
		} else {
			i = (ImageView) convertView;
		}
		
		Bitmap d = cache.getImage(String.valueOf(position));
		if(d == null){
		d = GraphicsUtil.drawableToBitmap(mResources.getDrawable(data.get(position)));
			cache.putImage(String.valueOf(position), d);
		}
		i.setImageBitmap(d);
		return i;
	}

	public int getCount() {
		return data.size();
	}

	public Drawable getItem(int position) {
		return /*mContext.getResources()*/mResources.getDrawable(data.get(position));
	}

	public long getItemId(int position) {
		return position;
	}
	
	public int getDrawableID(int id){
		return data.get(id - 1);
	}
}
 public class GotyeMessageListAdapter extends BaseAdapter implements GotyeStreamPlayListener{

	public static final int TYPE_TEXT = 0;
	public static final int TYPE_IMAGE = 1;
	public static final int TYPE_VOICE = 2;
	
	public static final int TYPE_TEXT_RIGHT = 3;
	public static final int TYPE_IMAGE_RIGHT = 4;
	public static final int TYPE_VOICE_RIGHT = 5;
	
	private GotyeDialog dialog = null;
	private Context context;
	@SuppressWarnings("rawtypes")
	private List<GotyeMessageProxy> messageList;
	private GotyeAPI api;
	private GotyeMessageActivity activity;
	private WindowManager wm;
	private int width;
	private Bitmap defaultHead;
	private NinePatchDrawable bgImageMessage;
	
	private Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			notifyDataSetChanged();
		};
	};
	
	private GotyeVoiceMessageProxy curPreparedPlayMessage;
	
	private ImageCache imageSoftCache = new ImageCache();
	
	@SuppressWarnings("deprecation")
	public GotyeMessageListAdapter(GotyeMessageActivity activity, GotyeAPI api, Context context,
			@SuppressWarnings("rawtypes") List<GotyeMessageProxy> messageList) {
		super();
		this.activity = activity;
		this.api = api;
		this.context = context;
		this.messageList = messageList;
		wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE);
		width = wm.getDefaultDisplay().getWidth();
		defaultHead = BitmapFactory.decodeResource(context.getResources(), R.drawable.gotye_bg_icon_nn);
		bgImageMessage = (NinePatchDrawable) context.getResources().getDrawable(R.drawable.gotye_bg_image_nn);
	}

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

	@SuppressWarnings("rawtypes")
	@Override
	public GotyeMessageProxy getItem(int position) {
		return position >= 0 ? messageList.get(position) : null;
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		int type = getItemViewType(position);
		@SuppressWarnings("rawtypes")
		final GotyeMessageProxy message = getItem(position);
		SenderHolder holder = null;
		if(type == TYPE_TEXT){
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.gotye_message_mode_text, null);
				holder = new TextHolder(convertView);
				
				convertView.setTag(holder);
			}else {
				holder = (TextHolder) convertView.getTag();
			}
			bindText(context, position, (TextHolder) holder, convertView, (GotyeTextMessageProxy) message);
		}else if(type == TYPE_IMAGE){
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.gotye_message_mode_image, null);
				holder = new ImageHolder(convertView);
				
				convertView.setTag(holder);
			}else {
				holder = (ImageHolder) convertView.getTag();
			}
			bindImage(context, position, (ImageHolder) holder, convertView, (GotyeImageMessageProxy) message);
		}else if(type == TYPE_VOICE){
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.gotye_message_mode_voice, null);
				holder = new VoiceHolder(convertView);
				
				convertView.setTag(holder);
			}else {
				holder = (VoiceHolder) convertView.getTag();
			}
			bindVoice(context, position, (VoiceHolder) holder, convertView, (GotyeVoiceMessageProxy) message);
		}else if(type == TYPE_TEXT_RIGHT){
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.gotye_message_mode_text_right, null);
				holder = new TextHolder(convertView);
				
				convertView.setTag(holder);
			}else {
				holder = (TextHolder) convertView.getTag();
			}
			bindText(context, position, (TextHolder) holder, convertView, ((GotyeTextMessageProxy) message));
		}else if(type == TYPE_IMAGE_RIGHT){
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.gotye_message_mode_image_right, null);
				holder = new ImageHolder(convertView);
				
				convertView.setTag(holder);
			}else {
				holder = (ImageHolder) convertView.getTag();
			}
			bindImage(context, position, (ImageHolder) holder, convertView, (GotyeImageMessageProxy) message);
		}else if(type == TYPE_VOICE_RIGHT){
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.gotye_message_mode_voice_right, null);
				holder = new VoiceHolder(convertView);
				
				convertView.setTag(holder);
			}else {
				holder = (VoiceHolder) convertView.getTag();
			}
			bindVoice(context, position, (VoiceHolder) holder, convertView, ((GotyeVoiceMessageProxy) message));
		}

		if(holder != null){
			if(holder.tip != null && message.isSendBySelf() && message.getSendState() == GotyeMessageProxy.FORBIDDEN){
				holder.tip.setVisibility(View.VISIBLE);
			}else if(holder.tip != null && message.isSendBySelf()){
				holder.tip.setVisibility(View.GONE);
			}else if(holder.tip != null){
				holder.tip.setVisibility(View.GONE);
			}
			
			if(message.getShowTime() != null){
				holder.timeTip.setVisibility(View.VISIBLE);
			}else {
				holder.timeTip.setVisibility(View.GONE);
			}
			
			holder.timeTip.setText(message.getShowTime());
			
			
			final SenderHolder fholder = holder;
			final GotyeUser user = message.get().getSender();
			
			holder.userIcon.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					if(dialog != null){
						dialog.dismiss();
					}
					dialog = GotyeDialog.createUserinfoDialog(api, context, message.get().getSender());
					dialog.show();
				}
			});
			fholder.usernameView.setText(" ");
			
			holder.usernameView.setTag(user);
			fholder.userIcon.setDefaultImage(R.drawable.gotye_default_icon);
			fholder.userIcon.setImageBitmap("", R.drawable.gotye_bg_icon_nn);
			if(api.getUsername().equals(user.getUsername())){
				fholder.usernameView.setText("" + InnerConstants.curUserInfo.getNickName());
				
				Bitmap icon = InnerConstants.curUserHead;
				icon = ImageUtils.toRoundCorner(context, icon, defaultHead);
				fholder.userIcon.setImageBitmap(icon, R.drawable.gotye_bg_icon_nn);
			}else {
				
				ItemLoadedFuture userFu = UserInfoManager.getInstance(context).getThumbnail(user, new ItemLoadedCallback<UserLoaded>() {
					
					@Override
					public void onItemLoaded(final UserLoaded resultr, Throwable exception) {
						
						Object tag = resultr.tag;
						if(!(tag instanceof TextView)){
							return;
						}
						TextView tv = (TextView) tag;
						final GotyeUser user = (GotyeUser) tv.getTag();
						
						boolean eq = user.getUsername().equals(resultr.user.getUsername());
						if(eq){
							if(!(resultr.fu instanceof NullItemLoadedFuture)){
								refresh();
							}else {
								if(StringUtil.isEmpty(resultr.user.getNickName())){
									fholder.usernameView.setText(" ");
								}else {
									fholder.usernameView.setText(resultr.user.getNickName());
								}
								fholder.userIcon.setImageBitmap(resultr.user.getUserIcon(), R.drawable.gotye_bg_icon_nn);
							}
						}
					}
				}, holder.usernameView);
			}
			
		}
		return convertView;
	}
	
	private void refresh(){
		notifyDataSetChanged();
//		handler.postDelayed(new Runnable() {
//			
//			@Override
//			public void run() {
//			}
//		}, 1000);
	}
	
	@Override
	public int getViewTypeCount() {
		return 6;
	}
	
	@Override
	public int getItemViewType(int position) {
		
		@SuppressWarnings("rawtypes")
		GotyeMessageProxy item = getItem(position);
		
		if(item instanceof GotyeTextMessageProxy){
			if(api.getUsername().equals(item.get().getSender().getUsername())){
				return TYPE_TEXT_RIGHT; 
			}
			return TYPE_TEXT;
		}else if(item instanceof GotyeImageMessageProxy){
			if(api.getUsername().equals(item.get().getSender().getUsername())){
				return TYPE_IMAGE_RIGHT; 
			}
			return TYPE_IMAGE;
		}else if(item instanceof GotyeVoiceMessageProxy){
			if(api.getUsername().equals(item.get().getSender().getUsername())){
				return TYPE_VOICE_RIGHT; 
			}
			return TYPE_VOICE;
		}
		return 0;
	}
	
	static class SenderHolder {
		TextView usernameView;
		AsycImageView userIcon;
		TextView timeTip;
		TextView tip;
		
		public SenderHolder(View parent){
			userIcon = (AsycImageView) parent.findViewById(R.id.gotye_item_icon);
			usernameView = (TextView) parent.findViewById(R.id.gotye_item_name);
			usernameView.setClickable(true);
			timeTip = (TextView) parent.findViewById(R.id.gotye_time_tip);
			tip = (TextView) parent.findViewById(R.id.gotye_msg_tip);
		}
	}
	
	static class TextHolder extends SenderHolder{
		public TextHolder(View parent) {
			super(parent);
			contentView = (TextView) parent.findViewById(R.id.gotye_item_msg_text);
		}

		TextView contentView;
	}
	
	static class ImageHolder extends SenderHolder{

		public ImageHolder(View parent) {
			super(parent);
			contentView = (ImageView) parent.findViewById(R.id.gotye_item_msg_image);
		}
		
		ImageView contentView;
	}
	
	static class VoiceHolder extends SenderHolder{

		public VoiceHolder(View parent) {
			super(parent);
			contentView = (TextView) parent.findViewById(R.id.gotye_item_msg_voice);
			downloadProgress = (ProgressBar) parent.findViewById(R.id.gotye_item_msg_voice_progress);
		}
		
		private TextView contentView;
		private ProgressBar downloadProgress;
	}
	
	private void bindText(Context context, int position, TextHolder holder, View convertView, final GotyeTextMessageProxy msg){
		if(msg.get().getText().length() < 5){
			holder.contentView.setGravity(Gravity.CENTER);
		}else {
			holder.contentView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
		}
		
		CharSequence sqe = msg.getTextCharSeq();
		if(sqe == null){
			msg.setTextCharSeq(SmileyUtil.replace(context, context.getResources(), msg.get().getText()));
		}
		
		holder.contentView.setText(msg.getTextCharSeq());
		holder.contentView.setOnLongClickListener(new OnLongClickListener() {
			
			@Override
			public boolean onLongClick(View v) {
				activity.showMessagePannel(v, msg);
				return true;
			}
		});
	}
	
	private void bindImage(Context context, int position, ImageHolder holder, View convertView, final GotyeImageMessageProxy msg){
		Bitmap image = null;
		if(msg.isSendBySelf()){
			image = imageSoftCache.getImage(msg.getSavePath());
		}else {
			image = imageSoftCache.getImage(msg.get().getDownloadUrl());
		}
		
		if (image == null) {
			ImageData data = null;
			
			if(msg.isSendBySelf()){
				data = ResourceManager.getInstance(context).getImageCacheService().getImageData(
						msg.getSavePath(), ImageCacheService.TYPE_IMAGE);
			}else {
				data = ResourceManager.getInstance(context).getImageCacheService().getImageData(
						msg.get().getDownloadUrl(), ImageCacheService.TYPE_IMAGE);
			}
			
			
			if (data != null) {
				image = BitmapFactory.decodeByteArray(data.mData, data.mOffset,
						data.mData.length - data.mOffset);
				imageSoftCache.putImage(msg.get().getDownloadUrl(), image);
			}
		}
		if(image != null){
			final Bitmap bit = image;
//			holder.contentView.setScaleType(ScaleType.FIT_XY);
			holder.contentView.setImageBitmap(ImageUtils.toRoundCornerScaleDst(context, image, bgImageMessage));
			holder.contentView.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					
					if(msg.isSendBySelf()){
						activity.showImagePrev(bit, false, msg.getSavePath() + "big", ImageCacheService.TYPE_IMAGE);
						 
					}else {
						activity.showImagePrev(bit, false, msg.get().getDownloadUrl(), ImageCacheService.TYPE_RES);
					}
				}
			});
		}else {
			holder.contentView.setImageBitmap(null);
			holder.contentView.setOnClickListener(null);
		}
		holder.contentView.setOnLongClickListener(new OnLongClickListener() {
			
			@Override
			public boolean onLongClick(View v) {
				activity.showMessagePannel(v, msg);
				return true;
			}
		});
	}
	
	private void bindVoice(final Context context, int position, final VoiceHolder holder, View convertView, final GotyeVoiceMessageProxy msg){
		
		Drawable[] leftRight = holder.contentView.getCompoundDrawables();
		AnimationDrawable left = (AnimationDrawable) leftRight[0];
		AnimationDrawable right = (AnimationDrawable) leftRight[2];
		
		int time = (int) (msg.get().getDuration() / 1000f);
		
		if(curPreparedPlayMessage == msg){
//			time = (int) (curPlayTime / 1000f);
			if(left != null){
				left.start();
			}else if(right != null){
				right.start();
			}
		}else {
			if(left != null){
				left.stop();
				left.selectDrawable(0);
			}else if(right != null){
				right.stop();
				right.selectDrawable(0);
			}
		}
		if(time == 0){
			time = 1;
		}
		
		holder.contentView.setText((int)time + "''");
		int voiceWidth = context.getResources().getDimensionPixelSize(R.dimen.gotye_message_voice_len) + (int) (width / 3f * (time / 60f));
		holder.contentView.setWidth(voiceWidth);
		
		holder.contentView.setOnClickListener(null);
		
		final String savePath = msg.getSavePath();
		if(msg.isDownloading()){
			holder.downloadProgress.setVisibility(View.VISIBLE);
			holder.contentView.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					activity.hideKeyboard();
					if(curPreparedPlayMessage != msg){
						api.stopPlayStream();
					}else {
						notifyDataSetChanged();
//						curPreparedPlayMessage = null;
						return;
					}
					curPreparedPlayMessage = msg;
					notifyDataSetChanged();
				}
			});
		}else if(savePath == null && !msg.isNewRecoder()){
			if(left != null){
				left.stop();
				left.selectDrawable(0);
			}else if(right != null){
				right.stop();
				right.selectDrawable(0);
			}
			holder.downloadProgress.setVisibility(View.INVISIBLE);
			holder.contentView.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(final View v) {
					if(curPreparedPlayMessage != msg){
						api.stopPlayStream();
					}else {
						notifyDataSetChanged();
//						curPreparedPlayMessage = null;
						return;
					}
					curPreparedPlayMessage = msg;
					
					msg.setDownloading(true);
					String url = msg.get().getDownloadUrl();
					v.setTag(url);
					ResourceManager.getInstance(context).getThumbnail(msg.get().getDownloadUrl(), Uri.parse(url), new ItemLoadedCallback<ResourceManager.ResLoaded>() {
						
						@Override
						public void onItemLoaded(ResLoaded result, Throwable exception) {
							if(v != result.tag){
								return;
							}
							if(result.downloadUrl.equals(((View) result.tag).getTag())){
								if(exception == null && (result.data != null && result.data.mData.length != 0)){
									msg.setSavePath(msg.get().getDownloadUrl());
									msg.setDownloading(false);
									if(curPreparedPlayMessage == msg){
										play(msg);
									}
								}else {
									msg.setSavePath(null);
									msg.setDownloading(false);
									curPreparedPlayMessage = null;//TODO 下载失败
								}
								msg.setDownloadFailed(false);
								handler.post(new Runnable() {
									
									@Override
									public void run() {
										notifyDataSetChanged();
									}
								});
							}
						}
					}, v);
					notifyDataSetChanged();
				}
			});
			
		}else {
			holder.downloadProgress.setVisibility(View.INVISIBLE);
			holder.contentView.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					activity.hideKeyboard();
					if(curPreparedPlayMessage != msg){
						api.stopPlayStream();
					}else {
						api.stopPlayStream();
						curPreparedPlayMessage = null;
						notifyDataSetChanged();
						return;
					}
					curPreparedPlayMessage = msg;
					play(msg);
				}
			});
		}
		holder.contentView.setOnLongClickListener(new OnLongClickListener() {
			
			@Override
			public boolean onLongClick(View v) {
				activity.showMessagePannel(v, msg);
				return true;
			}
		});
	}

	@Override
	public void onPlayStart() {
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				notifyDataSetChanged();
			}
		});
		
	}

	@Override
	public void onPlaying(final float time) {
//		curPlayTime = time;
//		if(!handler.hasMessages(0)){
//			handler.sendEmptyMessageDelayed(0, 400);
//		}
	}

	@Override
	public void onPlayStop() {
		curPreparedPlayMessage = null;
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				notifyDataSetChanged();
			}
		});
	}
	
	public void play(GotyeVoiceMessageProxy msg){
		ImageData data = ResourceManager.getInstance(context).getImageCacheService().getImageData(msg.getSavePath(), ImageCacheService.TYPE_RES);

		if(data == null){
			curPreparedPlayMessage = null;
			notifyDataSetChanged();
			return;
		}
		
		api.startPlayStream(new ByteArrayInputStream(data.mData, data.mOffset, data.mData.length - data.mOffset), GotyeMessageListAdapter.this);
		notifyDataSetChanged();
	}
	
	public void stopPlay(){
		api.stopPlayStream();
		curPreparedPlayMessage = null;
		notifyDataSetChanged();
	}
	
	@Override  
    public boolean areAllItemsEnabled() {  
        return false;  
    }  
      
    @Override  
    public boolean isEnabled(int position) {  
        return false;  
    }

	public GotyeVoiceMessageProxy getCurPreparedPlayMessage() {
		return curPreparedPlayMessage;
	}

	public void setCurPreparedPlayMessage(GotyeVoiceMessageProxy curPreparedPlayMessage) {
		this.curPreparedPlayMessage = curPreparedPlayMessage;
	} 
	
	public void onConfigurationChanged(Configuration newConfig) {
		if(dialog != null){
			dialog.onConfigurationChanged(newConfig);
		}
	}
} public class GotyeUserListAdapter extends BaseAdapter {

	private RoomUserListListener roomListener;
	private GotyeDialog userinfoDialog;
	private Context context;
	private List<GotyeUser> userList;
	private GotyeAPI api;

	private Handler handler = new Handler();
	
	private int itemCount = 0;
	private int itemWidth = 0;

	private View footView;

	public GotyeUserListAdapter(GotyeAPI api, Context context, List<GotyeUser> messageList) {
		super();
		this.api = api;
		this.context = context;
		this.userList = messageList;
		
		calSize();
	}
	
	private void calSize(){
		WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE);
		int width = wm.getDefaultDisplay().getWidth();
		width -= GraphicsUtil.dipToPixel(10);
		
		int spacing = context.getResources().getDimensionPixelSize(R.dimen.gotye_user_list_spacing);
		itemWidth = GraphicsUtil.dipToPixel(60) + (2 * spacing);
		
		itemCount = width / itemWidth;
	}
	
	private int calcCount(){
		if(userList.size() == 0){
			return 0;
		}else {
			return (userList.size() - 1) / itemCount + 1;
		}
	}

	@Override
	public int getCount() {
		return calcCount();
	}

	@Override
	public GotyeUser getItem(int position) {
		return null;
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {
			convertView = new LinearLayout(context);
			LinearLayout c = (LinearLayout) convertView;
//			c.setBackgroundColor(Color.BLACK);
			c.setGravity(Gravity.CENTER_HORIZONTAL);
			
			holder = new ViewHolder();
			holder.items = new View[itemCount];
			for(int i = 0 ;i < itemCount;i++){
				View item = LayoutInflater.from(context).inflate(R.layout.gotye_adapter_icon, null);
				c.addView(item, itemWidth, -2);
				holder.items[i] = item;
			}
			holder.init();
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		
		int lastCount;
		
		if(getCount() - 1 == position){
			lastCount = userList.size() % itemCount;
			if(lastCount == 0){
				lastCount = itemCount;
			}
			if(roomListener != null){
				roomListener.loadNextPage();
			}
			
		}else {
			lastCount = itemCount;
		}
	
		for(int i = 0; i < holder.items.length;i++){
			if(i >= lastCount){
				holder.items[i].setVisibility(View.INVISIBLE);
			}else {
				holder.items[i].setVisibility(View.VISIBLE);
				final GotyeUser user = userList.get(position * itemCount + i);
				holder.items[i].setOnClickListener(new OnClickListener() {
					
					@Override
					public void onClick(View v) {
						if(userinfoDialog != null){
							return;
						}
						userinfoDialog = GotyeDialog.createUserinfoDialog(api, context, user);
						userinfoDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
							
							@Override
							public void onDismiss(DialogInterface dialog) {
								userinfoDialog = null;
							}
						});
						userinfoDialog.show();	
					}
				});
				final ViewHolder fholder = holder;
				holder.holders[i].usernameView.setTag(user);
				
				holder.holders[i].usernameView.setText("");
				fholder.holders[i].userIcon.setDefaultImage(R.drawable.gotye_default_icon);
				if(api.getUsername().equals(user.getUsername())){
					fholder.holders[i].usernameView.setText("" + InnerConstants.curUserInfo.getNickName());
					
					Bitmap icon = InnerConstants.curUserHead;
					icon = ImageUtils.toRoundCorner(context, icon, BitmapFactory.decodeResource(context.getResources(), R.drawable.gotye_bg_icon_nn));
					fholder.holders[i].userIcon.setImageBitmap(icon, R.drawable.gotye_bg_icon_nn_dialog);
				}else {
					final int ii = i;
					UserInfoManager.getInstance(context).getThumbnail(user, new ItemLoadedCallback<UserLoaded>() {

						@Override
						public void onItemLoaded(final UserLoaded resultr, Throwable exception) {
							
							Object tag = resultr.tag;
							if(!(tag instanceof TextView)){
								return;
							}
							TextView tv = (TextView) tag;
							final GotyeUser user = (GotyeUser) tv.getTag();
							
							boolean eq = user.getUsername().equals(resultr.user.getUsername());
							if(eq){
								if(!(resultr.fu instanceof NullItemLoadedFuture)){
									refresh();
								}else {
									fholder.holders[ii].usernameView.setText("" + resultr.user.getNickName());
									
									final String icon = resultr.user.getUserIcon();
									fholder.holders[ii].userIcon.setImageBitmap(icon, R.drawable.gotye_bg_icon_nn_dialog);
								}
							}
						}
					}, holder.holders[i].usernameView);
				}
				
				
			}
		}
		
		return convertView;
	}

	public List<GotyeUser> getUserList() {
		return userList;
	}

	public void setUserList(List<GotyeUser> userList) {
		this.userList = userList;
	}

	static class ViewHolder {
		
		private View[] items;
		private SubHolder[] holders;
		
		public void init(){
			int i = 0;
			holders = new SubHolder[items.length];
			for(View parent : items){
				holders[i] = new SubHolder();
				holders[i].usernameView = (TextView) parent.findViewById(R.id.gotye_item_name);
				holders[i].userIcon = (AsycImageView) parent.findViewById(R.id.gotye_item_icon);
				
				i++;
			}
		}

		
	}
	
	static class SubHolder {
		
		private TextView usernameView;
		private AsycImageView userIcon;
	}
	
	private void refresh(){
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				notifyDataSetChanged();
			}
		});
	}
	
	public void addFoot() {
		if (footView == null) {
//			footView = LayoutInflater.from(context).inflate(
//					R.layout.gotye_load_more, null);
//			AbsListView.LayoutParams p = new AbsListView.LayoutParams(-1, 100);
//			p.height = 100;
//			footView.setLayoutParams(p);
//			listView.addFooterView(footView, null, false);
		}
	}

	public void removeFoot() {
//		if (footView != null) {
//			listView.removeFooterView(footView);
//			footView = null;
//		}
	}

	public RoomUserListListener getRoomListener() {
		return roomListener;
	}

	public void setRoomListener(RoomUserListListener roomListener) {
		this.roomListener = roomListener;
	}
	
	public void configChanged(int o){
		switch (o) {
		case Configuration.ORIENTATION_LANDSCAPE:
			calSize();
			break;

		case Configuration.ORIENTATION_PORTRAIT:
			calSize();
			break;
		default:
			break;
		}
		notifyDataSetChanged();
	}
} public class GotyeDialog extends Dialog {
	
	private Object tag;
	private View contentView;

	public GotyeDialog(Context context) {
		super(context, R.style.GotyeDialogStyle);
	}

	@Override
	public void setContentView(View view, ViewGroup.LayoutParams params) {
		this.contentView = view;
		super.setContentView(view, params);
	}

	@Override
	public void setContentView(View view) {
		
		this.contentView = view;
		
		onConfigurationChanged(getContext().getResources().getConfiguration());
	}
	
	public void onConfigurationChanged(Configuration newConfig){
		if(this.contentView == null){
			return;
		}
		WindowManager wm = (WindowManager) getContext().getSystemService(
				Context.WINDOW_SERVICE);
		int orientation = newConfig.orientation;
		switch (orientation) {
			case Configuration.ORIENTATION_LANDSCAPE:
			
				int height = wm.getDefaultDisplay().getHeight();// 屏幕宽度
				super.setContentView(contentView, new ViewGroup.LayoutParams(
						(int) (3.0 / 5 * height), ViewGroup.LayoutParams.WRAP_CONTENT));
				break;

			case Configuration.ORIENTATION_PORTRAIT:

				int width = wm.getDefaultDisplay().getWidth();// 屏幕宽度
				super.setContentView(contentView, new ViewGroup.LayoutParams(
						(int) (3.0 / 5 * width), ViewGroup.LayoutParams.WRAP_CONTENT));
				
				break;
		default:
			break;
		}
	}

	@Override
	public void setContentView(int layoutResID) {

		this.setContentView(this.contentView = LayoutInflater.from(getContext()).inflate(
				layoutResID, null));
	}
	
	public static GotyeDialog createReportDialog(final Activity context, final GotyeUser user, final GotyeMessage message){
		final GotyeDialog dialog = new GotyeDialog(context);
		View dialogView = LayoutInflater.from(context).inflate(
				R.layout.gotye_dialog_report, null);
		dialog.setContentView(dialogView);
		dialog.setCancelable(true);
		dialog.setCanceledOnTouchOutside(true);
		
		final TextView titleView = (TextView) dialogView.findViewById(R.id.gotye_report_title);
		
		final EditText contentView = (EditText) dialogView.findViewById(R.id.gotye_report_edit);
		dialogView.findViewById(R.id.gotye_btn_dialog_close).setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		
		final TextView typeView1 = (TextView) dialogView.findViewById(R.id.gotye_user_type_1);
		final TextView typeView2 = (TextView) dialogView.findViewById(R.id.gotye_user_type_2);
		final TextView typeView3 = (TextView) dialogView.findViewById(R.id.gotye_user_type_3);
		final Button sureBtn = (Button) dialogView.findViewById(R.id.gotye_report_cancel);
		
		typeView1.setText("恶意刷屏");
		typeView1.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				report(dialog, context, 0, user, "", message);
				dialog.dismiss();
			}
		});
		typeView2.setText("谩骂");
		typeView2.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				report(dialog, context, 1, user, "", message);
				dialog.dismiss();
			}
		});
		typeView3.setText("其他理由");
		typeView3.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
//				report(dialog, context, 2, user, contentView.getText().toString(), message);
				typeView1.setVisibility(View.INVISIBLE);
				typeView2.setVisibility(View.INVISIBLE);
				typeView3.setVisibility(View.INVISIBLE);
				
				titleView.setText("其他理由");
				
				contentView.setVisibility(View.VISIBLE);
				sureBtn.setText(R.string.gotye_sure);
				
				sureBtn.setTag(true);
			}
		});
		sureBtn.setTag(false);
		sureBtn.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				boolean tag = (Boolean) sureBtn.getTag();
				if(tag){
					report(dialog, context, 2, user, contentView.getText().toString(), message);
				}else {
					
				}
				dialog.dismiss();
			}
		});
		
		typeView1.setClickable(true);
		typeView2.setClickable(true);
		typeView3.setClickable(true);
		
		return dialog;
	}
	
	private static void report(final GotyeDialog dialog, final Activity context, int type, final GotyeUser user, final String reason, final GotyeMessage message){
		final int t = type;
		AsyncDialog asycnDialog = new AsyncDialog(context);
		asycnDialog.runAsync(new Runnable() {
			
			@Override
			public void run() {
				final GotyeRequestFuture fu = InnerConstants.getAPI(context).report(user, t, reason, message);
				try {
					fu.get();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}, new Runnable() {
			
			@Override
			public void run() {
				dialog.dismiss();
			}
		}, R.string.gotye_modify_loading);
	}

	public static GotyeDialog createUserinfoDialog(GotyeAPI api, final Context context, final GotyeUser user) {

		final GotyeDialog dialog = new GotyeDialog(context);
		View dialogView = LayoutInflater.from(context).inflate(
				R.layout.gotye_dialog_userinfo, null);
		dialog.setContentView(dialogView);
		dialog.setCancelable(true);
		dialog.setCanceledOnTouchOutside(true);
		
		dialogView.findViewById(R.id.gotye_btn_dialog_close).setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		
		final TextView nameView = (TextView) dialogView.findViewById(R.id.gotye_username);
//		nameView.setText(user.getUsername());
		final TextView userIDView = (TextView) dialogView.findViewById(R.id.gotye_userid);
		final TextView sexView = (TextView) dialogView.findViewById(R.id.gotye_usersex);
		final AsycImageView head = (AsycImageView) dialogView.findViewById(R.id.gotye_icon);
		nameView.setTag(user);
		if(api.getUsername().equals(user.getUsername())){
			nameView.setText("" + InnerConstants.curUserInfo.getNickName());
			
			Bitmap icon = InnerConstants.curUserHead;
//			fholder.holders[i].userIcon.setTag(icon);
			icon = ImageUtils.toRoundCorner(context, icon, BitmapFactory.decodeResource(context.getResources(), R.drawable.gotye_bg_icon_nn));
			head.setImageBitmap(icon, R.drawable.gotye_bg_icon_nn_dialog);
			
			userIDView.setText("ID：" + String.valueOf(api.getUserState(GotyeAPI.STATE_USER_ID)));
			nameView.setText(InnerConstants.curUserInfo.getNickName());
			if(InnerConstants.curUserInfo.getSex() != null){
				switch (InnerConstants.curUserInfo.getSex()) {
				case MAN:
					sexView.setText("性别：" + context.getString(R.string.gotye_male));
					break;
				case NOT_SET:
					sexView.setText("性别：" + context.getString(R.string.gotye_notset));
					break;
				case WOMEN:
					sexView.setText("性别：" + context.getString(R.string.gotye_female));
					break;
					
				default:
					sexView.setText("性别：你猜");
					break;
				}
			}else {
				sexView.setText("性别：你猜");
			}
			
		}else {
			
			UserInfoManager.getInstance(context).getThumbnail(user, new ItemLoadedCallback<UserInfoManager.UserLoaded>() {
				
				@Override
				public void onItemLoaded(UserLoaded result, Throwable exception) {
					if(result.user == null){
						return;
					}
					if(nameView != result.tag){
						return;
					}
					if(!result.user.getUsername().equals(((GotyeUser) ((View) result.tag).getTag()).getUsername())){
						return;
					}
					userIDView.setText("ID：" + String.valueOf(result.user.getUserID()));
					nameView.setText(result.user.getNickName());
					if(result.user.getSex() != null){
						switch (result.user.getSex()) {
						case MAN:
							sexView.setText("性别：" + context.getString(R.string.gotye_male));
							break;
						case NOT_SET:
							sexView.setText("性别：" + context.getString(R.string.gotye_notset));
							break;
						case WOMEN:
							sexView.setText("性别：" + context.getString(R.string.gotye_female));
							break;
							
						default:
							sexView.setText("性别：你猜");
							break;
						}
					}else {
						sexView.setText("性别：你猜");
					}
					
					head.setImageBitmap(result.user.getUserIcon(), R.drawable.gotye_bg_icon_nn_dialog);
				}
			}, nameView);
		}
		
		return dialog;
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		
		TextView tv = (TextView) getTag();
		tv.setText(item.getTitle());
		return super.onContextItemSelected(item);
	}

	public Object getTag() {
		return tag;
	}

	public void setTag(Object tag) {
		this.tag = tag;
	}
	
	 /**
     * @see Activity#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)
     */
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    	
    }
    
} public class AnimUtil {

	public static AnimationDrawable getSpeakBgAnim(Resources resources) {
		AnimationDrawable speakBg = new AnimationDrawable();
		BitmapDrawable item = new BitmapDrawable(BitmapFactory.decodeResource(
				resources, R.drawable.gotye_talk_ring));
		speakBg.addFrame(item, 400);
		item = new BitmapDrawable(BitmapFactory.decodeResource(resources,
				R.drawable.gotye_talk_ring1));
		speakBg.addFrame(item, 400);
		item = new BitmapDrawable(BitmapFactory.decodeResource(resources,
				R.drawable.gotye_talk_ring2));
		speakBg.addFrame(item, 400);
		speakBg.setOneShot(false);
		return speakBg;
	}

	public static Animation createAnimationFromXml(Context c,
			Resources resources, int resid) {
		XmlResourceParser parser = null;
		try {
			parser = resources.getAnimation(resid);
		} catch (Exception e) {
			// TODO: handle exception
			return null;
		}

		return createAnimationFromXml(c, parser, null,
				Xml.asAttributeSet(parser));
	}

	public static Animation createAnimationFromXml(Context c,
			XmlPullParser parser, AnimationSet parent, AttributeSet attrs) {
		Animation anim = null;

		// Make sure we are on a start tag.
		int type;
		int depth = parser.getDepth();

		try {
			while (((type = parser.next()) != XmlPullParser.END_TAG || parser
					.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {

				if (type != XmlPullParser.START_TAG) {
					continue;
				}

				String name = parser.getName();

				if (name.equals("set")) {
					anim = new AnimationSet(c, attrs);
					createAnimationFromXml(c, parser, (AnimationSet) anim,
							attrs);
				} else if (name.equals("alpha")) {
					anim = new AlphaAnimation(c, attrs);
				} else if (name.equals("scale")) {
					anim = new ScaleAnimation(c, attrs);
				} else if (name.equals("rotate")) {
					anim = new RotateAnimation(c, attrs);
				} else if (name.equals("translate")) {
					anim = new TranslateAnimation(c, attrs);
				} else {
					throw new RuntimeException("Unknown animation name: "
							+ parser.getName());
				}

				if (parent != null) {
					parent.addAnimation(anim);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return anim;

	}
}
 public class GraphicsUtil {
	final static float scale = Resources.getSystem().getDisplayMetrics().density;

	/**
	 * Converts DIP to pixels.
	 * 
	 * @param dip
	 *            the value of the dip.
	 * @return the value of the pixels.
	 */
	public static int dipToPixel(int dip) {
		return (int) (dip * scale + 0.5f);
	}

	public static int pixelToDip(int px) {
		return (int) ((px - 0.5f) / scale);
	}

	public static Bitmap drawableToBitmap(Drawable drawable) {
		BitmapDrawable bd = (BitmapDrawable) drawable;
		Bitmap bitmap = bd.getBitmap();
		return bitmap;
	}

	public static Drawable BitmapToDrawable(final Bitmap bitmap) {
		BitmapDrawable bd = new BitmapDrawable(bitmap);
		return bd;
	}

	/**
	 * 通过图片url返回图片Bitmap
	 * 
	 * @param url
	 * @return
	 * @throws IOException 
	 */
	public static Bitmap returnBitMap(String path) throws IOException {
		URL url = null;
		Bitmap bitmap = null;
		url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 利用HttpURLConnection对象,我们可以从网络中获取网页数据.
		conn.setDoInput(true);
		conn.connect();
		InputStream is = conn.getInputStream(); // 得到网络返回的输入流
		bitmap = BitmapFactory.decodeStream(is);
		is.close();
		return bitmap;
	}
} public class ResourceManager extends BackgroundLoaderManager {
    private static final String TAG = "ResManager";


    private final Context mContext;
    private ImageCacheService mImageCacheService;
    private static ResourceManager instance;
    
    public static synchronized ResourceManager getInstance(Context context){
    	if(instance == null){
    		instance = new ResourceManager(context.getApplicationContext());
    	}
    	return instance;
    }

    public ResourceManager(final Context context) {
        super(context);
        mContext = context;
        mImageCacheService = new ImageCacheService(context.getApplicationContext());
    }

    /**
     * getThumbnail must be called on the same thread that created ThumbnailManager. This is
     * normally the UI thread.
     * @param uri the uri of the image
     * @param width the original full width of the image
     * @param height the original full height of the image
     * @param callback the callback to call when the thumbnail is fully loaded
     * @return
     */
    public ItemLoadedFuture getThumbnail(String resid, Uri uri,
            final ItemLoadedCallback<ResLoaded> callback, Object tag) {
        return getThumbnail(ImageCacheService.TYPE_RES, resid, uri, false, callback, tag);
    }
    
    public ItemLoadedFuture getThumbnail(String resid, int type, Uri uri,
            final ItemLoadedCallback<ResLoaded> callback, Object tag) {
        return getThumbnail(type, resid, uri, false, callback, tag);
    }

    private ItemLoadedFuture getThumbnail(int type, String resid, Uri uri, boolean isVideo,
            final ItemLoadedCallback<ResLoaded> callback, Object tag) {
        if (uri == null) {
            throw new NullPointerException();
        }
        NullItemLoadedFuture fu = new NullItemLoadedFuture();
        if(StringUtil.isEmpty(resid)){
            ResLoaded imageLoaded = new ResLoaded(fu, tag, resid, null);
            callback.onItemLoaded(imageLoaded, null);
            return fu;
        }

        final ImageData thumbnail = mImageCacheService.getImageData(resid, type);
        
        boolean thumbnailExists = (thumbnail != null);
        
        if(thumbnailExists && (thumbnail.mData == null || 0 == (thumbnail.mData.length - thumbnail.mOffset))){
        	thumbnailExists = false;
        }
        
        final boolean taskExists = mPendingTaskUris.contains(uri);
        final boolean newTaskRequired = !thumbnailExists && !taskExists;
        final boolean callbackRequired = (callback != null);

        if (thumbnailExists) {
        	
            if (callbackRequired) {
                if (callbackRequired) {
                    addCallback(uri, callback);
                }
                final Set<ItemLoadedCallback> callbacks = mCallbacks.get(uri);
                ResLoaded imageLoaded = new ResLoaded(fu, tag, resid, thumbnail);
                if (callbacks != null) {

                    // Make a copy so that the callback can unregister itself
                    for (final ItemLoadedCallback<ResLoaded> c : asList(callbacks)) {
                        c.onItemLoaded(imageLoaded, null);
                    }
                } 
//                callback.onItemLoaded(imageLoaded, null);
            }
            return fu;
        }

        if (callbackRequired) {
            addCallback(uri, callback);
        }

        ItemLoadedFuture f= new ItemLoadedFuture() {
            private boolean mIsDone;

            @Override
            public void cancel(Uri uri) {
                cancelCallback(callback);
//                removeThumbnail(uri);   // if the thumbnail is half loaded, force a reload next time
            }

            @Override
            public void setIsDone(boolean done) {
                mIsDone = done;
            }

            @Override
            public boolean isDone() {
                return mIsDone;
            }
        };
        
        if (newTaskRequired) {
            mPendingTaskUris.add(uri);
            Runnable task = new LoadResTask(f, tag, type, resid, uri, isVideo);
            mExecutor.execute(task);
        }
        return f;
    }

    @Override
    public synchronized void clear() {
        super.clear();

        clearBackingStore();        // clear on-disk cache
    }

    // Delete the on-disk cache, but leave the in-memory cache intact
    public synchronized void clearBackingStore() {
        if (mImageCacheService == null) {
            // No need to call getImageCacheService() to renew the instance if it's null.
            // It's enough to only delete the image cache files for the sake of safety.
            CacheManager.clear(mContext);
        } else {
            getImageCacheService().clear();

            // force a re-init the next time getImageCacheService requested
            mImageCacheService = null;
        }
    }

    @Override
    public String getTag() {
        return TAG;
    }

    public synchronized ImageCacheService getImageCacheService() {
        return mImageCacheService;
    }

    public class LoadResTask implements Runnable {
        private final Uri mUri;
        private final boolean mIsVideo;
        private final String downloadUrl;
        private int type;
        private Object tag;
        public ItemLoadedFuture fu;

        public LoadResTask(ItemLoadedFuture fu, Object tag, int type, String downloadUrl, Uri uri, boolean isVideo) {
            if (uri == null) {
                throw new NullPointerException();
            }
            this.type = type;
            this.downloadUrl = downloadUrl;
            mUri = uri;
            mIsVideo = isVideo;
            this.tag = tag;
            this.fu = fu;
        }

        /** {@inheritDoc} */
        @Override
        public void run() {

        	Exception exception = null;
        	
           //download res
        	final ByteArrayOutputStream bout = new ByteArrayOutputStream();
        	FileInputStream fin = null;
			try {
				GotyeRequestFuture fu = InnerConstants.getAPI(mContext).downloadRes(downloadUrl, null, new GotyeProgressListener() {
					
					@Override
					public void onProgressUpdate(String appKey, String username, String resID,
							String path, long totalByte, long downloadByte, byte[] data,
							int offset, int len) {
						bout.write(data, offset, len);
					}
					
					@Override
					public void onDownloadRes(String appKey, String username, String resID,
							String path, int code) {
						
					}
				});
				boolean success = (Boolean) fu.get();
				if(success){
					mImageCacheService.putImageData(downloadUrl, type, bout.toByteArray());
				}
			} catch (Exception e) {
				e.printStackTrace();
				exception = e;
			} finally {
				if(fin != null){
					try {
						fin.close();
					} catch (IOException e) {
					}
				}
			}
        	
        	byte[] bytes = bout.toByteArray();
        	final ImageData result = new ImageData(bytes, 0);

        	final Exception e = exception;
            mCallbackHandler.post(new Runnable() {
                @Override
                public void run() {
                    final Set<ItemLoadedCallback> callbacks = mCallbacks.get(mUri);
                    if (callbacks != null) {

                        // Make a copy so that the callback can unregister itself
                        for (final ItemLoadedCallback<ResLoaded> callback : asList(callbacks)) {
                        	ResLoaded imageLoaded = new ResLoaded(fu, tag, downloadUrl, result);
                             callback.onItemLoaded(imageLoaded, e);
                        }
                    } 

                    // Add the bitmap to the soft cache if the load succeeded. Don't cache the
                    // stand-ins for empty bitmaps.

                    mCallbacks.remove(mUri);
                    mPendingTaskUris.remove(mUri);

                }
            });
        }

 

    }

    public static class ResLoaded {
        public final String downloadUrl;
        public final ImageData data;
        public final Object tag;
        public final ItemLoadedFuture fu;

        public ResLoaded(ItemLoadedFuture fu, Object tag, String downloadUrl, ImageData data) {
            this.downloadUrl = downloadUrl;
            this.data = data;
            this.tag = tag;
            this.fu = fu;
        }
    }
}
 public static class ResLoaded {
    public final String downloadUrl;
    public final ImageData data;
    public final Object tag;
    public final ItemLoadedFuture fu;

    public ResLoaded(ItemLoadedFuture fu, Object tag, String downloadUrl, ImageData data) {
        this.downloadUrl = downloadUrl;
        this.data = data;
        this.tag = tag;
        this.fu = fu;
    }
}
 public class SmileyUtil {
	private static final String PREFIX="gotye_smiley_";
	   private static  Pattern mPattern=buildPattern();
	   private static int getIdByResourceName(String ResName) {
				int resourceId = 0;
				try {
					Field field = R.drawable.class.getField(ResName);
					field.setAccessible(true);

					try {
						resourceId = field.getInt(null);
					} catch (IllegalArgumentException e) {
					} catch (IllegalAccessException e) {
					}
				} catch (NoSuchFieldException e) {
				}
				return resourceId;
			}
	    //构建正则表达式
	    private static Pattern buildPattern() {
	    	return Pattern.compile("\\[+[s](\\d*)\\]+");
	    }
	    //根据文本替换成图片
	    public static CharSequence replace(Context c, Resources resources, CharSequence text) {
	        SpannableStringBuilder builder = new SpannableStringBuilder(text);
	        Matcher matcher = mPattern.matcher(text);
	        while (matcher.find()) {
	            int id = getIdByResourceName(PREFIX + matcher.group(1));
	            if(id<=0){
	            	continue;
	            }
	            builder.setSpan(new GPlusImageSpan(c, resources, id),matcher.start(), matcher.end(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
	        }
	        return builder;
	    }
}
 public class ViewHelper {
	 /* 
     * 获取控件宽 
     */  
    public static int getWidth(View view)  
    {  
        int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
        int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
        view.measure(w, h);  
        return (view.getMeasuredWidth());         
    }  
    /* 
     * 获取控件高 
     */  
    public static int getHeight(View view)  
    {  
        int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
        int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
        view.measure(w, h);  
        return (view.getMeasuredHeight());         
    }  
}
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.gotye.api.GotyeAPI;
import com.gotye.api.GotyeChatListener;
import com.gotye.api.GotyeLoginListener;
import com.gotye.api.GotyeRoomListener;
import com.gotye.api.GotyeStatusCode;
import com.gotye.api.GotyeUserListener;
import com.gotye.api.bean.GotyeImageMessage;
import com.gotye.api.bean.GotyeMessage;
import com.gotye.api.bean.GotyeRoom;
import com.gotye.api.bean.GotyeTargetable;
import com.gotye.api.bean.GotyeTextMessage;
import com.gotye.api.bean.GotyeUser;
import com.gotye.api.bean.GotyeVoiceMessage;
import com.gotye.api.media.WhineMode;
import com.gotye.api.net.GotyeRequestFuture;
import com.gotye.api.utils.ImageUtils;
import com.gotye.api.utils.StringUtil;
import com.gotye.api.utils.UriImage;
import com.gotye.sdk.InnerConstants;
import com.gotye.sdk.R;
import com.gotye.sdk.handmark.pulltorefresh.library.GotyePullToRefreshScrollView;
import com.gotye.sdk.handmark.pulltorefresh.library.GotyePullToRefreshScrollView.OnTouchBottomListener;
import com.gotye.sdk.handmark.pulltorefresh.library.PullToRefreshBase;
import com.gotye.sdk.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.gotye.sdk.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.gotye.sdk.handmark.pulltorefresh.library.PullToRefreshListView;
import com.gotye.sdk.logic.beans.GotyeImageMessageProxy;
import com.gotye.sdk.logic.beans.GotyeMessageProxy;
import com.gotye.sdk.logic.beans.GotyeTextMessageProxy;
import com.gotye.sdk.logic.beans.GotyeVoiceMessageProxy;
import com.gotye.sdk.ui.adapter.EmotiAdapter;
import com.gotye.sdk.ui.adapter.GotyeMessageListAdapter;
import com.gotye.sdk.ui.adapter.GotyeUserListAdapter;
import com.gotye.sdk.ui.dialog.GotyeDialog;
import com.gotye.sdk.uk.co.senab.photoview.PhotoViewAttacher;
import com.gotye.sdk.uk.co.senab.photoview.PhotoViewAttacher.OnPhotoTapListener;
import com.gotye.sdk.uk.co.senab.photoview.PhotoViewAttacher.OnViewTapListener;
import com.gotye.sdk.utils.AnimUtil;
import com.gotye.sdk.utils.GraphicsUtil;
import com.gotye.sdk.utils.ImageCacheService;
import com.gotye.sdk.utils.ItemLoadedCallback;
import com.gotye.sdk.utils.ResourceManager;
import com.gotye.sdk.utils.ResourceManager.ResLoaded;
import com.gotye.sdk.utils.SmileyUtil;
import com.gotye.sdk.utils.TimeUtil;
import com.gotye.sdk.utils.ViewHelper;
						window.dismiss();
					}
				});
		    
		        
		        left1Btn.setVisibility(View.VISIBLE);

		        TextView title = (TextView) view.findViewById(R.id.gotye_text_top_text);
		        setTitle(title, null);
		        
		        final GotyePullToRefreshScrollView userListGrid = (GotyePullToRefreshScrollView) view.findViewById(R.id.gotye_grid_userlist);
		        
//		        
		        final RoomUserListListener userListener = new RoomUserListListener(userListGrid);
		        InnerConstants.getAPI(getApplicationContext()).addRoomListener(userListener);
				window.setOnDismissListener(new PopupWindow.OnDismissListener() {
					
					@Override
					public void onDismiss() {
						InnerConstants.getAPI(getApplicationContext()).removeRoomListener(userListener);
					}
				});
				
				userListGrid.setListstener(userListener);
				
				userListGrid.setMode(Mode.PULL_FROM_START);
				userListGrid.setScrollingWhileRefreshingEnabled(true);
				
				userListGrid.setOnRefreshListener(new OnRefreshListener<ScrollView>() {

					@Override
					public void onRefresh(PullToRefreshBase refreshView) {
						handler.post(new Runnable() {
							
							@Override
							public void run() {
								userListener.reloadPage();
							}
						});
					}

				});

				window.update();
				window.showAsDropDown(getWindow().getDecorView(), 0, -statusBarHeight);
				userListWindow = window;
				
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						userListGrid.setRefreshing();
						userListener.loadNextPage();
					}
				});
			}
		});
	}
	
	private void setTitle(TextView titleView, TextView titleViewLand){
		if(target instanceof GotyeRoom){
			GotyeRoom room = (GotyeRoom) target;
			if(titleView != null){
				titleView.setText(StringUtil.escapeNull(room.getRoomName()));
			}
			if(titleViewLand != null){
				titleViewLand.setText(StringUtil.escapeNull(room.getRoomName()));
			}
			
		}
	}
	
	public void hideKeyboard(){
		// 隐藏输入法 
		InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
		// 显示或者隐藏输入法 
		imm.hideSoftInputFromWindow(textEdit.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
	}
	
	public class RoomUserListListener implements GotyeRoomListener, OnTouchBottomListener {

		private boolean isLoad = false;
		private GotyePullToRefreshScrollView gridView;
		private int curPage;
		private List<GotyeUser> users = new ArrayList<GotyeUser>();
		private ListView listView;
		
		public RoomUserListListener(GotyePullToRefreshScrollView gridView) {
			super();
			this.gridView = gridView;
		}

		@Override
		public void onEnterRoom(String appKey, String username, GotyeRoom room, String recordID,
				int errorCode) {
		}

		@Override
		public void onLeaveRoom(String appKey, String username, GotyeRoom room,
				int errorCode) {
		}

		@Override
		public void onGetRoomList(String appKey, String username, int pageNum,
				List<GotyeRoom> roomList, int errorCode) {
		}

		@Override
		public void onGetRoomUserList(String appKey, String username,
				GotyeRoom room, int pageNum, List<GotyeUser> userList,
				int errorCode) {
			Log.d("", "get user list : " + errorCode + "" + room + ", " + userList.size());
			if(curPage == pageNum && errorCode == GotyeStatusCode.STATUS_OK && room.equals(target)){
				isLoad = false;
				
				if(pageNum == 0){
					
					gridView.removeListView();
					users.clear();
					listView = new ListView(GotyeMessageActivity.this);
			        final GotyeUserListAdapter adapter = new GotyeUserListAdapter(InnerConstants.getAPI(getApplicationContext()), GotyeMessageActivity.this, users);