/*
 * Copyright (C) 2010 Moduad Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.cgt.weixin.view.manager;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import net.cgt.weixin.Constants;
import net.cgt.weixin.GlobalParams;
import net.cgt.weixin.R;
import net.cgt.weixin.domain.FriendRooms;
import net.cgt.weixin.domain.MucHistory;
import net.cgt.weixin.domain.User;
import net.cgt.weixin.utils.FormatTools;
import net.cgt.weixin.utils.L;
import net.cgt.weixin.utils.LogUtil;
import net.cgt.weixin.utils.SpUtil;
import net.cgt.weixin.view.listener.TaxiChatManagerListener;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Registration;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
import org.jivesoftware.smackx.ReportedData;
import org.jivesoftware.smackx.ReportedData.Row;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.muc.DiscussionHistory;
import org.jivesoftware.smackx.muc.HostedRoom;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.ParticipantStatusListener;
import org.jivesoftware.smackx.muc.RoomInfo;
import org.jivesoftware.smackx.packet.VCard;
import org.jivesoftware.smackx.search.UserSearchManager;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;

/**
 * XMPP管理
 * 
 * @author lijian
 * @date 2014-11-22
 */
public class XmppManager {

	private static final String LOGTAG = LogUtil.makeLogTag(XmppManager.class);

	private Context context;

	/** 加载配置文件 **/
	private Properties props;

	private String version = "0.0.1";

	private String apiKey;

	private String xmppHost;

	private String xmppPort;

	/** 回调Activity的包名 **/
	private String callbackActivityPackageName;

	/** 回调Activity的全类名 **/
	private String callbackActivityClassName;

	private XMPPConnection connection;

	private static XmppManager xmppManager;

	/** 聊天监听器 **/
	private TaxiChatManagerListener chatManagerListener;

	public static XmppManager getInstance() {
		if (xmppManager == null) {
			xmppManager = new XmppManager(GlobalParams.activity);
			return xmppManager;
		}
		return xmppManager;
	}

	private XmppManager(Context context) {
		this.context = context;
		init(context);
	}

	private void init(Context context) {
		if (context instanceof Activity) {
			L.i(LOGTAG, "Callback Activity...");
			Activity callbackActivity = (Activity) context;
			callbackActivityPackageName = callbackActivity.getPackageName();
			callbackActivityClassName = callbackActivity.getClass().getName();
		}

		props = loadProperties();
		apiKey = props.getProperty("apiKey", "");
		xmppHost = props.getProperty("xmppHost", "127.0.0.1");
		xmppPort = props.getProperty("xmppPort", "5222");
		L.i(LOGTAG, "apiKey=" + apiKey);
		L.i(LOGTAG, "xmppHost=" + xmppHost);
		L.i(LOGTAG, "xmppPort=" + xmppPort);

		SpUtil sp = new SpUtil(context);
		sp.saveString(Constants.API_KEY, apiKey);
		sp.saveString(Constants.VERSION, version);
		sp.saveString(Constants.XMPP_HOST, xmppHost);
		sp.saveInt(Constants.XMPP_PORT, Integer.parseInt(xmppPort));
		sp.saveString(Constants.CALLBACK_ACTIVITY_PACKAGE_NAME, callbackActivityPackageName);
		sp.saveString(Constants.CALLBACK_ACTIVITY_CLASS_NAME, callbackActivityClassName);

		connectServer();
	}

	/**
	 * 加载Properties配置文件
	 * 
	 * @return
	 */
	private Properties loadProperties() {
		Properties props = new Properties();
		try {
			int id = context.getResources().getIdentifier("weixin", "raw", context.getPackageName());
			props.load(context.getResources().openRawResource(id));
		} catch (Exception e) {
			L.e(LOGTAG, "Could not find the properties file.", e);
		}
		return props;
	}

	/**
	 * 得到xmpp连接
	 * 
	 * @return
	 */
	public XMPPConnection getConnection() {
		return connection;
	}

	/**
	 * 设置连接
	 * 
	 * @param connection 一个xmpp连接
	 */
	public void setConnection(XMPPConnection connection) {
		this.connection = connection;
	}

	/**
	 * xmpp连接是否建立并连接成功
	 * 
	 * @return
	 */
	private boolean isConnected() {
		return connection != null && connection.isConnected();
	}

	/**
	 * 与服务器建立连接
	 * 
	 * @return
	 */
	public boolean connectServer() {
		ConnectionConfiguration connConfig = new ConnectionConfiguration(xmppHost, Integer.parseInt(xmppPort));
		//设置安全模式
		connConfig.setSecurityMode(SecurityMode.required);
		//设置SASL认证是否启用
		connConfig.setSASLAuthenticationEnabled(false);
		//设置数据压缩是否启用
		connConfig.setCompressionEnabled(false);
		//是否启用调试模式
		connConfig.setDebuggerEnabled(true);

		/** 创建connection连接 */
		XMPPConnection connection = new XMPPConnection(connConfig);
		this.setConnection(connection);

		try {
			// 连接到服务器
			connection.connect();
			L.i(LOGTAG, "XMPP connected successfully");
			return true;
		} catch (XMPPException e) {
			L.e(LOGTAG, "XMPP connection failed", e);
		}
		return false;
	}

	/**
	 * 注册
	 * 
	 * @param account 注册帐号
	 * @param password 注册密码
	 * @return 0、 服务器没有返回结果<br>
	 *         1、注册成功 <br>
	 *         2、这个帐号已经存在 <br>
	 *         3、注册失败
	 */
	public String regist(String account, String password) {
		if (!isConnected()) {
			return "0";
		}
		Registration reg = new Registration();
		reg.setType(IQ.Type.SET);
		reg.setTo(getConnection().getServiceName());
		reg.setUsername(account);
		reg.setPassword(password);
		reg.addAttribute("android", "geolo_createUser_android");

		//数据包过滤器
		PacketFilter filter = new AndFilter(new PacketIDFilter(reg.getPacketID()), new PacketTypeFilter(IQ.class));
		PacketCollector collector = getConnection().createPacketCollector(filter);
		getConnection().sendPacket(reg);

		IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
		//停止请求result(是否成功的结果)
		collector.cancel();
		if (result == null) {
			L.e(LOGTAG, "No response from server.");
			return "0";
		} else if (result.getType() == IQ.Type.RESULT) {
			return "1";
		} else {
			if (result.getError().toString().equalsIgnoreCase("conflict(409)")) {
				L.e(LOGTAG, "IQ.Type.ERROR: " + result.getError().toString());
				return "2";
			} else {
				L.e(LOGTAG, "IQ.Type.ERROR: " + result.getError().toString());
				return "3";
			}
		}
	}

	/**
	 * 获取一个聊天监听器
	 * 
	 * @return
	 */
	public TaxiChatManagerListener getChatManagerListener() {
		return this.chatManagerListener;
	}

	/**
	 * 登陆
	 * 
	 * @param account 账户名
	 * @param password 密码
	 * @return
	 */
	public boolean login(String account, String password) {
		try {
			//登陆
			getConnection().login(account, password);

			/** 开启读写线程,并加入到管理类中 */
			//ClientSendThread cst = new ClientSendThread(connection);
			//cst.start();
			//ManageClientThread.addClientSendThread(account,cst);

			// 添加监听,最好是放在登录方法中,在关闭连接方法中,移除监听,原因是为了避免重复添加监听,接受重复消息
			// 退出程序应该关闭连接,移除监听,该监听可以接受所有好友的消息,很方便吧~
			chatManagerListener = new TaxiChatManagerListener();
			getConnection().getChatManager().addChatListener(chatManagerListener);

			return true;
		} catch (XMPPException e) {
			L.e(LOGTAG, "XMPP connection failed", e);
		}
		return false;
	}

	/**
	 * 登出
	 * 
	 * @return
	 */
	public boolean logout() {
		// 添加监听,最好是放在登录方法中,在关闭连接方法中,移除监听,原因是为了避免重复添加监听,接受重复消息
		// 退出程序应该关闭连接,移除监听,该监听可以接受所有好友的消息,很方便吧~
		getConnection().getChatManager().removeChatListener(chatManagerListener);

		//退出登录
		getConnection().disconnect();

		if (isConnected()) {
			return true;
		}
		return false;
	}

	/**
	 * 修改密码
	 * 
	 * @param password
	 * @return
	 */
	public boolean changePassword(String password) {
		try {
			getConnection().getAccountManager().changePassword(password);
			return true;
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 更改用户状态
	 * 
	 * @param code--><br>
	 *            0、在线<br>
	 *            1、Q我吧<br>
	 *            2、忙碌<br>
	 *            3、离开<br>
	 *            4、隐身<br>
	 *            5、离线
	 */
	public void setPresence(int code) {
		if (!isConnected()) {
			return;
		}
		Presence presence;
		switch (code) {
		case 0:
			presence = new Presence(Presence.Type.available);
			getConnection().sendPacket(presence);
			L.v(LOGTAG, "设置在线");
			break;
		case 1:
			presence = new Presence(Presence.Type.available);
			presence.setMode(Presence.Mode.chat);
			getConnection().sendPacket(presence);
			L.v(LOGTAG, "设置Q我吧");
			L.d(LOGTAG, "Q我吧--->" + presence.toXML());
			break;
		case 2:
			presence = new Presence(Presence.Type.available);
			presence.setMode(Presence.Mode.dnd);
			getConnection().sendPacket(presence);
			L.v(LOGTAG, "设置忙碌");
			L.d(LOGTAG, "忙碌--->" + presence.toXML());
			break;
		case 3:
			presence = new Presence(Presence.Type.available);
			presence.setMode(Presence.Mode.away);
			getConnection().sendPacket(presence);
			L.v(LOGTAG, "设置离开");
			L.d(LOGTAG, "离开--->" + presence.toXML());
			break;
		case 4:
			Roster roster = getConnection().getRoster();
			Collection<RosterEntry> entries = roster.getEntries();
			for (RosterEntry entry : entries) {
				presence = new Presence(Presence.Type.unavailable);
				presence.setPacketID(Packet.ID_NOT_AVAILABLE);
				presence.setFrom(getConnection().getUser());
				presence.setTo(entry.getUser());
				getConnection().sendPacket(presence);
				L.d(LOGTAG, entry.getUser() + "--->" + presence.toXML());
			}
			//向同一用户的其他客户端发送隐身状态
			presence = new Presence(Presence.Type.unavailable);
			presence.setPacketID(Packet.ID_NOT_AVAILABLE);
			presence.setFrom(getConnection().getUser());
			presence.setTo(StringUtils.parseBareAddress(getConnection().getUser()));
			getConnection().sendPacket(presence);
			L.v(LOGTAG, "设置隐身");
			break;
		case 5:
			presence = new Presence(Presence.Type.unavailable);
			getConnection().sendPacket(presence);
			L.v(LOGTAG, "设置离线");
			break;
		default:
			break;
		}
	}

	/**
	 * 删除当前账户
	 * 
	 * @return
	 */
	public boolean deleteAccount() {
		try {
			getConnection().getAccountManager().deleteAccount();
			return true;
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 获得所有组
	 * 
	 * @param roster
	 * @return 所有组集合
	 */
	public List<RosterGroup> getGroups(Roster roster) {
		List<RosterGroup> groupList = new ArrayList<RosterGroup>();
		Collection<RosterGroup> rosterGroups = roster.getGroups();
		Iterator<RosterGroup> i = rosterGroups.iterator();
		while (i.hasNext()) {
			groupList.add(i.next());
		}
		return groupList;
	}

	/**
	 * 添加分组
	 * 
	 * @param roster
	 * @param groupName 分组名
	 * @return
	 */
	public boolean addGroup(Roster roster, String groupName) {
		try {
			roster.createGroup(groupName);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 获得某个组里面的所有好友
	 * 
	 * @param roster
	 * @param groupName 组名
	 * @return
	 */
	public List<RosterEntry> getEntriesByGroup(Roster roster, String groupName) {
		List<RosterEntry> entriesList = new ArrayList<RosterEntry>();
		RosterGroup rosterGroup = roster.getGroup(groupName);
		Collection<RosterEntry> rosterEntries = rosterGroup.getEntries();
		Iterator<RosterEntry> i = rosterEntries.iterator();
		while (i.hasNext()) {
			entriesList.add(i.next());
		}
		return entriesList;
	}

	/**
	 * 获取所有好友信息
	 * 
	 * @param roster
	 * @return
	 */
	public List<RosterEntry> getAllEntries(Roster roster) {
		List<RosterEntry> entriesList = new ArrayList<RosterEntry>();
		Collection<RosterEntry> rosterEntries = roster.getEntries();
		Iterator<RosterEntry> i = rosterEntries.iterator();
		while (i.hasNext()) {
			entriesList.add(i.next());
		}
		return entriesList;
	}

	/**
	 * 获取所有好友信息
	 * 
	 * @param roster
	 * @return
	 */
	public List<User> getAllUser(Roster roster) {
		List<User> mList_user = new ArrayList<User>();
		Collection<RosterEntry> entries = roster.getEntries();
		Iterator<RosterEntry> iterator = entries.iterator();
		while (iterator.hasNext()) {
			RosterEntry entry = iterator.next();
			User user = new User();
			user.setUserAccount(entry.getName());
			user.setUserPhote(String.valueOf(R.drawable.user_picture));
//			user.setUserImage(getUserImage(entry.getName()));
			mList_user.add(user);
			L.i(LOGTAG, "------获取好友-getAllUser----------------------");
			L.i(LOGTAG, "getAllUser-getName-->" + entry.getName());
			L.i(LOGTAG, "getAllUser-getUser-->" + entry.getUser());
			L.i(LOGTAG, "getAllUser-getStatus-->" + entry.getStatus());
		}
		return mList_user;
	}

	/**
	 * 获取用户VCard信息
	 * 
	 * @param user
	 * @return
	 * @throws XMPPException
	 */
	public VCard getUserVCard(String user) throws XMPPException {
		VCard vCard = new VCard();
		vCard.load(getConnection(), user);
		return vCard;
	}

	/**
	 * 获取用户头像信息
	 * 
	 * @param user
	 * @return
	 */
	public Drawable getUserImage(String user) {
		ByteArrayInputStream bais = null;
		try {
			VCard vCard = new VCard();
			//加入这句,解决没有No VCard
			ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new org.jivesoftware.smackx.provider.VCardProvider());
			vCard.load(getConnection(), user + "@" + getConnection().getServiceName());
			if (vCard == null || vCard.getAvatar() == null) {
				return null;
			}
			bais = new ByteArrayInputStream(vCard.getAvatar());
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (bais == null) {
			return null;
		}
		return FormatTools.getInstance().InputStream2Drawable(bais);
	}

	/**
	 * 添加好友--无分组
	 * 
	 * @param roster
	 * @param userName
	 * @param name
	 * @return
	 */
	public boolean addUser(Roster roster, String userName, String name) {
		try {
			roster.createEntry(userName, name, null);
			return true;
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 添加好友--有分组
	 * 
	 * @param roster
	 * @param userName
	 * @param name
	 * @param groupName
	 * @return
	 */
	public boolean addUser(Roster roster, String userName, String name, String groupName) {
		try {
			roster.createEntry(userName, name, new String[] { groupName });
			return true;
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 删除好友
	 * 
	 * @param roster
	 * @param userName
	 * @return
	 */
	public boolean removeUser(Roster roster, String userName) {
		try {
			if (userName.contains("@")) {
				userName = userName.split("@")[0];
			}
			RosterEntry entry = roster.getEntry(userName);
			L.i(LOGTAG, "删除好友--->" + userName);
			L.d(LOGTAG, "User." + (roster.getEntry(userName) == null));
			roster.removeEntry(entry);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 查询用户
	 * 
	 * @param serverDomain
	 * @param userName
	 * @return
	 * @throws XMPPException
	 */
	public List<User> searchUsers(String serverDomain, String userName) throws XMPPException {
		List<User> results = new ArrayList<User>();
		L.i(LOGTAG, "查询开始--->Host=" + getConnection().getHost() + "  ServiceName=" + getConnection().getServiceName());

		UserSearchManager usm = new UserSearchManager(getConnection());
		Form searchForm = usm.getSearchForm(serverDomain);
		Form answerForm = searchForm.createAnswerForm();
		answerForm.setAnswer("userAccount", true);
		answerForm.setAnswer("userPhote", userName);
		ReportedData data = usm.getSearchResults(answerForm, serverDomain);

		Iterator<Row> i = data.getRows();
		Row row = null;
		User user = null;
		while (i.hasNext()) {
			user = new User();
			row = i.next();
			user.setUserAccount(row.getValues("userAccount").next().toString());
			user.setUserPhote(row.getValues("userPhote").next().toString());
			results.add(user);
			//若存在,则有返回,userName一定非空,其他两个若是有设,一定非空
		}
		return results;
	}

	/**
	 * 修改用户头像
	 * 
	 * @param f
	 * @throws XMPPException
	 * @throws IOException
	 */
	public void changeUserImage(File f) throws XMPPException, IOException {
		VCard vCard = new VCard();
		vCard.load(getConnection());
		byte[] bytes = getFileBytes(f);

		String encodeImage = StringUtils.encodeBase64(bytes);
		vCard.setAvatar(bytes, encodeImage);
		vCard.setEncodedImage(encodeImage);
		vCard.setField("PHOTO", "<TYPE>image/jpg</TYPE><BINVAL>" + encodeImage + "</BINVAL>", true);

		ByteArrayInputStream bais = new ByteArrayInputStream(vCard.getAvatar());
		FormatTools.getInstance().InputStream2Bitmap(bais);
		vCard.save(getConnection());
	}

	/**
	 * 获取一个文件的字符流
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	private byte[] getFileBytes(File file) throws IOException {
		BufferedInputStream bis = null;
		try {
			bis = new BufferedInputStream(new FileInputStream(file));
			int bytes = (int) file.length();
			byte[] buffer = new byte[bytes];
			int readBytes = bis.read(buffer);
			if (readBytes != buffer.length) {
				throw new IOException("Entire file not read");
			}
			return buffer;
		} finally {
			if (bis != null) {
				bis.close();
			}
		}
	}

	/**
	 * 创建房间
	 * 
	 * @param roomName 房间名称
	 */
	public void createRoom(String roomName) {
		if (!isConnected()) {
			return;
		}
		try {
			// 创建一个MultiUserChat  
			MultiUserChat muc = new MultiUserChat(getConnection(), roomName + "@conference." + getConnection().getServiceName());
			// 创建聊天室  
			muc.create(roomName); // roomName房间的名字  
			// 获得聊天室的配置表单  
			Form form = muc.getConfigurationForm();
			// 根据原始表单创建一个要提交的新表单。  
			Form submitForm = form.createAnswerForm();
			// 向要提交的表单添加默认答复  
			for (Iterator<FormField> fields = form.getFields(); fields.hasNext();) {
				FormField field = (FormField) fields.next();
				if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
					// 设置默认值作为答复  
					submitForm.setDefaultAnswer(field.getVariable());
				}
			}
			// 设置聊天室的新拥有者  
			List<String> owners = new ArrayList<String>();
			owners.add(getConnection().getUser());// 用户JID  
			submitForm.setAnswer("muc#roomconfig_roomowners", owners);
			// 设置聊天室是持久聊天室,即将要被保存下来  
			submitForm.setAnswer("muc#roomconfig_persistentroom", false);
			// 房间仅对成员开放  
			submitForm.setAnswer("muc#roomconfig_membersonly", false);
			// 允许占有者邀请其他人  
			submitForm.setAnswer("muc#roomconfig_allowinvites", true);
			// 进入是否需要密码  
			//submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);  
			// 设置进入密码  
			//submitForm.setAnswer("muc#roomconfig_roomsecret", "password");  
			// 能够发现占有者真实 JID 的角色  
			// submitForm.setAnswer("muc#roomconfig_whois", "anyone");  
			// 登录房间对话  
			submitForm.setAnswer("muc#roomconfig_enablelogging", true);
			// 仅允许注册的昵称登录  
			submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
			// 允许使用者修改昵称  
			submitForm.setAnswer("x-muc#roomconfig_canchangenick", false);
			// 允许用户注册房间  
			submitForm.setAnswer("x-muc#roomconfig_registration", false);
			// 发送已完成的表单(有默认值)到服务器来配置聊天室  
			submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);
			// 发送已完成的表单(有默认值)到服务器来配置聊天室  
			muc.sendConfigurationForm(submitForm);
		} catch (XMPPException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 加入会议室
	 * 
	 * @param user 昵称
	 * @param password 会议室密码
	 * @param roomsName 会议室名
	 */
	public MultiUserChat joinMultiUserChat(String user, String password, String roomsName) {
		try {
			// 使用XMPPConnection创建一个MultiUserChat窗口  
			MultiUserChat muc = new MultiUserChat(getConnection(), roomsName + "@conference." + getConnection().getServiceName());
			// 聊天室服务将会决定要接受的历史记录数量  
			DiscussionHistory history = new DiscussionHistory();
			history.setMaxStanzas(0);
			//history.setSince(new Date());  
			// 用户加入聊天室  
			muc.join(user, password, history, SmackConfiguration.getPacketReplyTimeout());
			L.i(LOGTAG, "会议室加入成功........");
			return muc;
		} catch (XMPPException e) {
			e.printStackTrace();
			L.i(LOGTAG, "会议室加入失败........");
			return null;
		}
	}

	/**
	 * 查询会议室成员名字
	 * 
	 * @param muc
	 */
	public List<String> findMulitUser(MultiUserChat muc) {
		List<String> listUser = new ArrayList<String>();
		Iterator<String> it = muc.getOccupants();
		//遍历出聊天室人员名称  
		while (it.hasNext()) {
			// 聊天室成员名字  
			String name = StringUtils.parseResource(it.next());
			listUser.add(name);
		}
		return listUser;
	}

	/**
	 * 获取服务器上所有会议室
	 * 
	 * @return
	 * @throws XMPPException
	 */
	public List<FriendRooms> getConferenceRoom() throws XMPPException {
		List<FriendRooms> list = new ArrayList<FriendRooms>();
		new ServiceDiscoveryManager(getConnection());
		if (!MultiUserChat.getHostedRooms(getConnection(), getConnection().getServiceName()).isEmpty()) {

			for (HostedRoom k : MultiUserChat.getHostedRooms(getConnection(), getConnection().getServiceName())) {

				for (HostedRoom j : MultiUserChat.getHostedRooms(getConnection(), k.getJid())) {
					RoomInfo info2 = MultiUserChat.getRoomInfo(getConnection(), j.getJid());
					if (j.getJid().indexOf("@") > 0) {

						FriendRooms friendrooms = new FriendRooms();
						friendrooms.setName(j.getName());//聊天室的名称  
						friendrooms.setJid(j.getJid());//聊天室JID  
						friendrooms.setOccupants(info2.getOccupantsCount());//聊天室中占有者数量  
						friendrooms.setDescription(info2.getDescription());//聊天室的描述  
						friendrooms.setSubject(info2.getSubject());//聊天室的主题  
						list.add(friendrooms);
					}
				}
			}
		}
		return list;
	}

	//	五、监听会议室的消息
	//	添加会议室消息监听 :
	//multiChat.addMessageListener(new multiListener());
	/**
	 * 会议室信息监听事件
	 * 
	 * @author Administrator
	 * 
	 */
	public class multiListener implements PacketListener {
		@Override
		public void processPacket(Packet packet) {
			Message message = (Message) packet;
			// 接收来自聊天室的聊天信息  
			String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
			MucHistory mh = new MucHistory();
			//			mh.setUserAccount(account);
			String from = StringUtils.parseResource(message.getFrom());
			String fromRoomName = StringUtils.parseName(message.getFrom());
			mh.setMhRoomName(fromRoomName);
			mh.setFriendAccount(from);
			mh.setMhInfo(message.getBody());
			mh.setMhTime(time);
			mh.setMhType("left");
		}
	}

	//六、发送会议室消息
	//    multiChat.sendMessage(str);//multiChat 为聊天室对象

	//	七、监听会议室状态(成员的进入、离开等)
	//	添加监听事件:
	//    multiChat.addParticipantStatusListener(new ParticipantStatus());

	/**
	 * 会议室状态监听事件
	 * 
	 * @author Administrator
	 * 
	 */
	class ParticipantStatus implements ParticipantStatusListener {

		@Override
		public void adminGranted(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void adminRevoked(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void banned(String arg0, String arg1, String arg2) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void joined(String participant) {
			System.out.println(StringUtils.parseResource(participant) + " has joined the room.");
		}

		@Override
		public void kicked(String arg0, String arg1, String arg2) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void left(String participant) {
			// TODO Auto-generated method stub  
			System.out.println(StringUtils.parseResource(participant) + " has left the room.");

		}

		@Override
		public void membershipGranted(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void membershipRevoked(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void moderatorGranted(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void moderatorRevoked(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void nicknameChanged(String participant, String newNickname) {
			System.out.println(StringUtils.parseResource(participant) + " is now known as " + newNickname + ".");
		}

		@Override
		public void ownershipGranted(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void ownershipRevoked(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void voiceGranted(String arg0) {
			// TODO Auto-generated method stub  

		}

		@Override
		public void voiceRevoked(String arg0) {
			// TODO Auto-generated method stub  

		}
	}

	//	一、单人聊天
	//	1)发送消息:
	//	首先要获取一个聊天窗口,getConnection()为获取连接connection的方法,调用getFriendChat()获取

	private Map<String, Chat> chatManage = new HashMap<String, Chat>();// 聊天窗口管理map集合

	/**
	 * 获取或创建聊天窗口
	 * 
	 * @param friend 好友名
	 * @param listenter 聊天監聽器
	 * @return
	 */
	public Chat getFriendChat(String friend, MessageListener listenter) {
		if (getConnection() == null)
			return null;
		/** 判断是否创建聊天窗口 */
		for (String fristr : chatManage.keySet()) {
			if (fristr.equals(friend)) {
				// 存在聊天窗口,则返回对应聊天窗口
				return chatManage.get(fristr);
			}
		}
		/** 创建聊天窗口 */
		Chat chat = getConnection().getChatManager().createChat(friend + "@" + getConnection().getServiceName(), listenter);
		/** 添加聊天窗口到chatManage */
		chatManage.put(friend, chat);
		return chat;
	}

	//	friend为好友名,不是JID;listener 监听器可以传null,利用聊天窗口对象调用sendMessage发送消息
	//	这里sendMessage我传的是一个JSON字符串,以便更灵活的控制,发送消息完成~
	//	Chat chat = getFriendChat(friend,null);
	//	try {
	//	 	String msgjson = "{\"messageType\":\""+messageType+"\",\"chanId\":\""+chanId+"\",\"chanName\":\""+chanName+"\"}";
	//		chat.sendMessage(msgjson);
	//	} catch (XMPPException e) {
	//		e.printStackTrace();
	//	}

	//	添加监听,最好是放在登录方法中,在关闭连接方法中,移除监听,原因是为了避免重复添加监听,接受重复消息
	//	退出程序应该关闭连接,移除监听,该监听可以接受所有好友的消息,很方便吧~
	//	TaxiChatManagerListener chatManagerListener = new TaxiChatManagerListener();  
	//	getConnection().getChatManager().addChatListener(chatManagerListener); 

	//	connection.getChatManager().removeChatListener(chatManagerListener);

	//	二、多人聊天(会议室)
	//	1)、发送消息
	//	首先要获取会议室对象(MultiUserChat),有两种方法获取
	//	两个方法前面都有讲到,这里再回顾一下
	//	1、创建会议室
	/**
	 * 创建房间
	 * 
	 * @param user
	 * @param roomName 房间名称
	 * @param password
	 * @return
	 */
	public MultiUserChat createRoom(String user, String roomName, String password) {
		if (getConnection() == null)
			return null;

		MultiUserChat muc = null;
		try {
			// 创建一个MultiUserChat
			muc = new MultiUserChat(getConnection(), roomName + "@conference." + getConnection().getServiceName());
			// 创建聊天室
			muc.create(roomName);
			// 获得聊天室的配置表单
			Form form = muc.getConfigurationForm();
			// 根据原始表单创建一个要提交的新表单。
			Form submitForm = form.createAnswerForm();
			// 向要提交的表单添加默认答复
			for (Iterator<FormField> fields = form.getFields(); fields.hasNext();) {
				FormField field = (FormField) fields.next();
				if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
					// 设置默认值作为答复
					submitForm.setDefaultAnswer(field.getVariable());
				}
			}
			// 设置聊天室的新拥有者
			List<String> owners = new ArrayList<String>();
			owners.add(getConnection().getUser());// 用户JID
			submitForm.setAnswer("muc#roomconfig_roomowners", owners);
			// 设置聊天室是持久聊天室,即将要被保存下来
			submitForm.setAnswer("muc#roomconfig_persistentroom", true);
			// 房间仅对成员开放
			submitForm.setAnswer("muc#roomconfig_membersonly", false);
			// 允许占有者邀请其他人
			submitForm.setAnswer("muc#roomconfig_allowinvites", true);
			if (!password.equals("")) {
				// 进入是否需要密码
				submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", true);
				// 设置进入密码
				submitForm.setAnswer("muc#roomconfig_roomsecret", password);
			}
			// 能够发现占有者真实 JID 的角色
			// submitForm.setAnswer("muc#roomconfig_whois", "anyone");
			// 登录房间对话
			submitForm.setAnswer("muc#roomconfig_enablelogging", true);
			// 仅允许注册的昵称登录
			submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
			// 允许使用者修改昵称
			submitForm.setAnswer("x-muc#roomconfig_canchangenick", false);
			// 允许用户注册房间
			submitForm.setAnswer("x-muc#roomconfig_registration", false);
			// 发送已完成的表单(有默认值)到服务器来配置聊天室
			muc.sendConfigurationForm(submitForm);
		} catch (XMPPException e) {
			e.printStackTrace();
			return null;
		}
		return muc;
	}

	//	/**
	//	 * 加入会议室
	//	 * 
	//	 * @param user 昵称
	//	 * @param password 会议室密码
	//	 * @param roomsName 会议室名
	//	 */
	//	public MultiUserChat joinMultiUserChat(String user, String roomsName, String password) {
	//		if (getConnection() == null)
	//			return null;
	//		try {
	//			// 使用XMPPConnection创建一个MultiUserChat窗口
	//			MultiUserChat muc = new MultiUserChat(getConnection(), roomsName + "@conference." + getConnection().getServiceName());
	//			// 聊天室服务将会决定要接受的历史记录数量
	//			DiscussionHistory history = new DiscussionHistory();
	//			history.setMaxChars(0);
	//			// history.setSince(new Date());
	//			// 用户加入聊天室
	//			muc.join(user, password, history, SmackConfiguration.getPacketReplyTimeout());
	//			L.i("MultiUserChat", "会议室【" + roomsName + "】加入成功........");
	//			return muc;
	//		} catch (XMPPException e) {
	//			e.printStackTrace();
	//			L.i("MultiUserChat", "会议室【" + roomsName + "】加入失败........");
	//			return null;
	//		}
	//	}

	//	调用这个两个方法都可以获取到MultiUserChat,根据需求选择一个就可以。
	//	利用MultiUserChat对象调用sendMessage()方法即可,很容易吧~
	//	try {  
	//	    multiUserChat.sendMessage(message);  
	//	} catch (XMPPException e) {  
	//	    e.printStackTrace();  
	//	}

	//	添加监听器,每个会议室聊天对象都要添加一个消息监听器,为了避免重复监听
	//	应该把会议室聊天对象放在一个集合当中,需要用到的时候取出来用即可。
	//	multiUserChat.addMessageListener(new TaxiMultiListener());

	//	其次就是给连接设置监听器了,最好放在登录方法里,关闭连接方法里移除监听
	//	// 添加連接監聽  
	//	TaxiConnectionListener connectionListener = new TaxiConnectionListener();  
	//	getConnection().addConnectionListener(connectionListener);  

	//	connection.removeConnectionListener(connectionListener);
}