<?php


namespace IPS\chatbox\modules\front\conversation;

/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
	header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
	exit;
}

/**
 * main
 */
class _main extends \IPS\Dispatcher\Controller
{
	/**
	 * Execute
	 *
	 * @return	void
	 */
	public function execute()
	{
		parent::execute();
	}

	/**
	 * ...
	 *
	 * @return	void
	 */
	protected function manage()
	{
		// This is the default method if no 'do' parameter is specified
	}
	
	/**
	 * Open a room
	 */
	protected function openRoom()
	{
		$this->ajaxCheck();
		
		try
		{
			$room = \IPS\chatbox\Rooms\Room::load( \IPS\Request::i()->room );
			
			if ( !$room->_canView() )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_room' ) ) );
			}
		}
		catch( \OutOfRangeException $e ) 
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_room' ) ) );
		}
	
		\IPS\Output::i()->json( array( 'html' => (string) $room->show(NULL, TRUE, TRUE), 'config' => $room->jsVars() ) );
	}

	/*-------------------------------------------------------------------------*/
	// Get conversation
	/*-------------------------------------------------------------------------*/
	protected function getCon( $id )
	{
		try
		{
			$con = \IPS\chatbox\Member\Conversation::load( $id );
			return $con;
		}
		catch ( \OutOfRangeException $e )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_con' ) ) );
		}		
	}
	
	/*-------------------------------------------------------------------------*/
	// get msg by id
	/*-------------------------------------------------------------------------*/
	protected function getMsgByID( $id )
	{
		try
		{
			$chat = \IPS\chatbox\Member\Post::load( $id );
			return $chat;
		}
		catch ( \OutOfRangeException $e ) 
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_nomsg' ) ) );
		}
	}
	
	/*-------------------------------------------------------------------------*/
	// Get my conversations data
	/*-------------------------------------------------------------------------*/
	protected $_convoData = NULL;
	
	protected function convoData()
	{
		if ( $this->_convoData !== NULL )
		{
			return $this->_convoData;
		}		
		
		$max = 50;
		
		$myCons = iterator_to_array( \IPS\Db::i()->select( 'map_con_id', 'chatbox_conversations_user_map', array( 'map_user_id=? AND map_online=?', \IPS\Member::loggedIn()->member_id, 1 ), 'map_update DESC', array( 0, $max ) ) );	
		
		if ( $myCons )
		{
			$this->_convoData = iterator_to_array( \IPS\Db::i()->select( '*', 'chatbox_conversations', array( \IPS\Db::i()->in( 'con_id', $myCons, FALSE ) ) )->setKeyField( 'con_id' ) );	
		}
		else
		{
			$this->_convoData = array();
		}

		return $this->_convoData;
	}
	
	/*-------------------------------------------------------------------------*/
	// Update chats
	/*-------------------------------------------------------------------------*/	
	protected function updateChat()
	{
		# Check perm
		$this->ajaxCheck();

		# Ping to check the conversations & rooms
		if ( \IPS\Request::i()->activeTab == 0 )
		{
			if ( \IPS\Settings::i()->chatbox_bar_room == 1 )
			{
				$return['ping']['rooms'] = $this->pingRooms();
			}
			if ( \IPS\Settings::i()->chatbox_bar_con == 1 && \IPS\chatbox\Member\Conversation::_canUse() )
			{
				$ping = $this->pingChats();
				$return['ping']['chats'] = $ping['chats'];
				$return['ping']['online'] = $ping['online'];
			}
		}
		
		# Update new content in open tabs
		if ( \IPS\chatbox\Member\Conversation::_canUse() )
		{
			$return['tabs'] = $this->updateOpenTabs(); 
		}
		
		# Mark as read
		if ( \IPS\Request::i()->focusTabs != 0 )
		{
			$readWhere = array( 'map_con_id IN (?) AND map_user_id=?', \IPS\Request::i()->focusTabs, \IPS\Member::loggedIn()->member_id );
			\IPS\Db::i()->update( 'chatbox_conversations_user_map', "map_unread=0, map_update=" . time(), $readWhere );										
		}	
			
		# Update edited/deleted msg
		if ( isset( \IPS\Data\Store::i()->chatbox_con_changes ) )
		{
			$conCache = \IPS\Data\Store::i()->chatbox_con_changes;
			if ( $conCache[ \IPS\Member::loggedIn()->member_id ] )
			{
				$return['changes'] = $conCache[ \IPS\Member::loggedIn()->member_id ];
			}
			unset( $conCache[ \IPS\Member::loggedIn()->member_id ] );
			\IPS\Data\Store::i()->chatbox_con_changes = $conCache;
		}

		# Return
		if ( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->json( $return );
		}
	}
	
	/*-------------------------------------------------------------------------*/
	// Ping
	/*-------------------------------------------------------------------------*/	
	protected function pingRooms()
	{	
		$includeClubs = \IPS\Settings::i()->chatbox_bar_club;
		
		$lastUpdate = \IPS\chatbox\Rooms\Room::cacheAjax('lastUpdateRooms');
		
		if ( \IPS\Request::i()->roomsLastUpdate < $lastUpdate )
		{
			$publicRooms = \IPS\chatbox\Rooms\Room::publicRooms( $includeClubs );
			$rooms = array();
			
			foreach( $publicRooms as $room )
			{
				if ( ! \in_array( $room->id, explode(",", \IPS\Settings::i()->chatbox_bar_show_rooms) ) && ! $room->club() )
				{
					continue;
				}
				if ( !$room->isBlocked() && $room->_canView() )
				{
					$club = $room->club();
					
					$rooms[] = array(
						'id'			=> $room->id,
						'title'			=> $club ? "[" . $club->name . "] " . $room->_title : $room->_title,
						'icon'			=> $room->icon ? $room->icon : 'comments',
						'users'			=> $room->_canSeeOnline() ? $room->online() : null,
					);
				}
			}

			$rooms[0]['totalRooms'] = $rooms ? \count( $rooms ) : 0;
			$rooms[0]['lastUpdate'] = $lastUpdate;
		}
		
		return $rooms;
	}
	
	protected function pingChats()
	{
		$myID = \IPS\Member::loggedIn()->member_id;

		# Conversation data
		$convoData = $this->convoData();
		if ( !$convoData )
		{
			return NULL;
		}
		
		# Last message
		$lastChatIDs = array();
		$myCons = array();
		
		foreach( $convoData as $con )
		{
			$lastChatIDs[] = $con['con_lastID'];
			$myCons[] = $con['con_id'];
		}
		$postData = iterator_to_array( \IPS\Db::i()->select( '*', 'chatbox_conversations_posts', array( \IPS\Db::i()->in( 'chat_id', $lastChatIDs, FALSE ) ) )->setKeyField( 'chat_con' ) );
		$files = \IPS\Application::load('chatbox')->showFiles( $postData, 'con' );
	
		# Get all users in conversation
		$maps = \IPS\Db::i()->select( '*', 'chatbox_conversations_user_map', array( \IPS\Db::i()->in( 'map_con_id', $myCons ) ) );
		foreach( $maps as $map )
		{
			$data[ $map['map_con_id'] ][ $map['map_user_id'] ] = $map;
			$mIDs[] = $map['map_user_id'];
		}
		
		# Member Data
		$groups = \IPS\Application::load('chatbox')->memGroupCache();
		foreach( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->in( 'member_id', array_unique( $mIDs ), FALSE ) ) ) as $mem )
		{
			$mem['groupData'] = $groups[ $mem['member_group_id'] ];
			$memData[ $mem['member_id'] ] = $mem;
		}
		
		# Ignored
		$filterMems = \IPS\Application::load('chatbox')->filterMems();
				
		# My conversations
		foreach( $data as $conID => $rows )
		{			
			$myData = $rows[ $myID ];

			if ( $convoData[ $conID ]['con_isGroup'] != 1 )
			{				
				$u = NULL;
				unset( $rows[ $myID ] );
				$u = reset( $rows );
				$reData = $memData[ $u['map_user_id'] ];

				if ( $filterMems['ignored'] )
				{
					if ( \in_array( $reData['member_id'], $filterMems['ignored'] ) )
					{
						continue;
					}
				}
				
				if ( $filterMems['only'] )
				{
					if ( ! \in_array( $reData['member_id'], $filterMems['only'] ) )
					{
						continue;
					}
				}

				$icon = \IPS\Member::photoUrl( $reData );
				$title = \IPS\Application::load('chatbox')->userGroupFormat( $reData, $reData['name'] );
				$isOnline = \IPS\Application::load('chatbox')->isOnline( $reData );
			}
			else
			{
				foreach( $data[ $myData['map_con_id'] ] as $mid => $gMem )
				{
					$gMems[ $mid ] = $memData[ $mid ];
				}
				$el = \IPS\chatbox\Member\Conversation::elGroup( $conID, $gMems );
				$name = strip_tags( preg_replace( "/\r|\n|\t/", "", html_entity_decode( $convoData[ $conID ]['con_name'] ) ) );
				$title = $name ? $name : $el['title'];
				$icon = $el['icon'];
			}
			
			$lastMsg = $postData[ $conID ]['chat_content'];
			
			if ( $postData[ $conID ]['chat_member_id'] > -1 )
			{
				if ( $lastMsg )
				{
					$lastMsg = strip_tags( preg_replace( "/\r|\n|\t/", "", html_entity_decode( $lastMsg ) ) );
				}
				else
				{
					$lastMsg = $files[ $convoData[ $conID ]['con_lastID'] ] ? \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_txt_img' ) : NULL;
				}
			}
			else
			{
				$lastMsg = $lastMsg ? \IPS\Member::loggedIn()->language()->addToStack('chatbox_con_sys_' . $postData[ $conID ]['chat_sys'], FALSE, array( 'sprintf' => $lastMsg ) ) : NULL;
			}
			
			$lastMsgTime = $postData[ $conID ]['chat_time'];
			
			$inDay = ( \IPS\Settings::i()->chatbox_time_moment && ( time() - $lastMsgTime ) <= 86400 ) ? true : false;
			$timeFormat = $inDay && \IPS\Settings::i()->chatbox_time_moment ? \IPS\DateTime::ISO8601 : \IPS\Settings::i()->chatbox_time_format;

			$chats[] = array(
				'id'			=> $conID,
				'title'			=> $title,
				'icon'			=> $icon,
				'isOnline'		=> $isOnline,
				'lastMsg'		=> $lastMsg,
				'inDay'			=> $inDay,
				'lastMsgTime'	=> \IPS\DateTime::ts( $lastMsgTime )->format( $timeFormat ),
				'lastMsgID'		=> $convoData[ $conID ]['con_lastID'],
				'update'		=> $myData['map_update'],
				'unread'		=> $myData['map_unread'],
				'isGroup'		=> $convoData[ $conID ]['con_isGroup'] == 1 ? true : false,
				'conName'		=> $convoData[ $conID ]['con_name'],
			);
			
			if ( $isOnline )
			{
				$online[] = $conID;
			}				
		}

		if ( $chats )
		{
			usort($chats, function ($item1, $item2) {
				return $item2['lastMsgID'] <=> $item1['lastMsgID'];
			});	
		}
		
		if ( !$chats[0]['lastMsgID'] || $chats[0]['lastMsgID'] != (int) \IPS\Request::i()->conLastMsgID )
		{
			$return['chats'] = $chats;		
		}

		# Online status
		$return['online'] = $online;

		# Done
		return $return;
	}
	
	/*-------------------------------------------------------------------------*/
	// Get all new messages in open tabs
	/*-------------------------------------------------------------------------*/
	protected function updateOpenTabs()
	{
		# Options
		$opts = \IPS\chatbox\Member\Conversation::options();
		
		# Can report?	
		$canReport = ( \IPS\Member::loggedIn()->group['g_can_report'] == '1' || \in_array( 'IPS\chatbox\Member\Post', explode( ',', \IPS\Member::loggedIn()->group['g_can_report'] ) ) ) && \IPS\Settings::i()->chatbox_report == 1;
		
		# Get messages
		$loadMoreMode 	= (int) \IPS\Request::i()->loadMoreMode;
		$tabs 			= json_decode( \IPS\Request::i()->tabData, TRUE );
		$totalTabs 		= $tabs ? \count( $tabs ) : 0;

		if ( $totalTabs > 0 )
		{
			$convoData = $this->convoData();
			
			$filterMems = \IPS\Application::load('chatbox')->filterMems();
			
			foreach( $tabs as $k => $conf )
			{
				$conID = str_replace( 'convo_', '', $k );
				
				if ( ! $convoData[ $conID ] )
				{
					continue;
				}
				
				if ( \IPS\Request::i()->activeTab > 0 && \IPS\Request::i()->activeTab != $conID )
				{
					continue;
				}
				
				# Update users in this conversation
				if ( $conf['firstLoad'] )
				{
					$maps = iterator_to_array( \IPS\Db::i()->select( '*', 'chatbox_conversations_user_map', array( 'map_con_id=?', $conID ) )->setKeyField( 'map_user_id' ) );
					
					\IPS\Db::i()->update( 'chatbox_conversations', array( 
						'con_users' => implode(',', array_keys( $maps ) ),
					), array( "con_id=?", $conID ) );				
				}

				# Check lastID
				$useSQL = true;
				
				$lastID = $conf['lastID'] ? (int) $conf['lastID'] : 0;
				
				$new[ $conID ]['cacheLevel'] = $useSQL ? 0 : 1;
				
				if ( $useSQL )
				{
					$where[ $conID ][] = $loadMoreMode > 0 ? array( 'chat_id<?', (int) $loadMoreMode ) : array( 'chat_id>?', (int) $lastID );
					$where[ $conID ][] = array( 'chat_con=?', $conID );
					
					if ( $convoData[ 'con_users' ] )
					{
						$where[ $conID ][] = array( 'chat_member_id IN(-1,' . $convoData[ 'con_users' ] . ')' );
					}						
					
					if ( $filterMems != null )
					{
						if ( $filterMems['ignored'] )
						{
							$where[ $conID ][] = array( 'chat_member_id NOT IN(' . implode( ",", $filterMems['ignored'] ) . ')' );
						}
						
						if ( $filterMems['only'] )
						{
							$where[ $conID ][] = array( 'chat_member_id IN(' . implode( ",", $filterMems['only'] ) . ')' );
						}					
					}
					
					$data[ $conID ] = iterator_to_array( new \IPS\Patterns\ActiveRecordIterator( 
						\IPS\Db::i()->select( 
							'*', 
							'chatbox_conversations_posts', 
							$where[ $conID ], 
							'chat_id DESC', 
							array( 0, (int) $opts['limit'] )
						),
						'IPS\chatbox\Member\Post'
					) );					
				}
			}

			if ( $data )
			{
				foreach( $data as $cID => $chats )
				{	
					if ( !$chats )
					{
						if ( $loadMoreMode > 0 )
						{
							$new[ $cID ]['noOlder'] = 1;
						}
						continue;
					}
					
					$new[ $cID ]['lastID'] = $chats[0]->id;
					
					if ( $chats )
					{
						$chats = $opts['sort'] == 'asc' ? array_reverse($chats) : $chats;
						
						$files = \IPS\Application::load('chatbox')->showFiles( $chats, 'con' );
						$authors = \IPS\Application::load('chatbox')->joinAuthor( $chats );
						
						foreach( $chats as $chat )
						{
							$inDay = ( time() - $chat->time ) <= 86400 ? true : false;
							$timeFormat = $inDay && \IPS\Settings::i()->chatbox_time_moment ? \IPS\DateTime::ISO8601 : \IPS\Settings::i()->chatbox_time_format;
							
							if ( $chat->member_id > -1 )
							{
								$chatterName = $authors[ $chat->member_id ]['name'];
								$chatterKey = "user@" . $chat->member_id;
								$chatterPhoto = \IPS\Member::photoUrl( $authors[ $chat->member_id ] );
								$chatterNameFormat = \IPS\Application::load('chatbox')->userGroupFormat( $authors[ $chat->member_id ]['groupData'], $chatterName );
								$content = \IPS\Application::load('chatbox')->parseContent( $opts, $chat->content ) . $files[ $chat->id ];
							}
							else
							{
								$chatterName = NULL;
								$chatterKey = NULL;
								$chatterPhoto = NULL;
								$chatterNameFormat = NULL;								
								$content = \IPS\Member::loggedIn()->language()->addToStack('chatbox_con_sys_' . $chat->sys, FALSE, array( 'sprintf' => $chat->content ) );
							}
							
							$new[ $cID ]['messages'][] = array(
								'id'				=> $chat->id,
								'chatterID'			=> $chat->member_id,
								'chatterName' 		=> $chatterName,
								'chatterKey' 		=> $chatterKey,
								'chatterPhoto' 		=> $chatterPhoto,
								'chatterNameFormat' => $chatterNameFormat,
								'content' 			=> $content,
								'inDay'				=> $inDay,
								'time'				=> \IPS\DateTime::ts( $chat->time )->format( $timeFormat ),
								'canEdit'			=> $chat->item()->canEditMsg( $chat ),
								'canDelete'			=> $chat->item()->_canDelete( $chat->member_id ),
								'canReport'			=> $canReport,
							);
						}
						
					}
				}
			}		
		}

		if ( $loadMoreMode > 0 && \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->json( array( 'tabs' => $new ) );
		}

		return $new;
	}
	
	/*-------------------------------------------------------------------------*/
	// Check Use permission
	/*-------------------------------------------------------------------------*/	
	public function checkUsePerm()
	{
		if ( ! \IPS\chatbox\Member\Conversation::_canUse() && ! \IPS\chatbox\Member\Conversation::_canManage() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_perm_chat' ) ) );
		}
	}
	 
	/*-------------------------------------------------------------------------*/
	// Csrf & ajax check
	/*-------------------------------------------------------------------------*/	
	protected function ajaxCheck()
	{
		\IPS\Session::i()->csrfCheck();
		
		if ( ! \IPS\IN_DEV )
		{			
			if ( ! \IPS\Request::i()->isAjax() )
			{
				\IPS\Output::i()->error( 'chatbox_error_noajax', '2CHATBOX103/3', 403, '' );
			}		
		}
	}
	
	/*-------------------------------------------------------------------------*/
	// Open new conversation
	/*-------------------------------------------------------------------------*/	
	public function openConversation()
	{
		$this->ajaxCheck();
		
		$this->checkUsePerm();

		if ( \IPS\Request::i()->conID )
		{
			$con = $this->getCon( \IPS\Request::i()->conID );
			
			if ( ! $con->canChat() )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_perm_chat' ) ) );
			}			
		}
		else
		{
			# Check member ID
			$to = \IPS\Member::load( \IPS\Request::i()->memberID );
			
			if ( ! $to->member_id )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_user' ) ) );
			}
			
			if ( \IPS\Member::loggedIn()->member_id == $to->member_id )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_unknown' ) ) );		
			}
			
			# Find the existing conversation
			$con = \IPS\chatbox\Member\Conversation::findConvo( $to );
			
			# Update map
			\IPS\Db::i()->update( 'chatbox_conversations_user_map', "map_online=1", array( 'map_con_id=? AND map_user_id=?', $con->id, \IPS\Member::loggedIn()->member_id ) );
		}

		# Return
		\IPS\Output::i()->json( array( 'html' => (string) $con->show(), 'conID' => $con->id ) );
	}

	/*-------------------------------------------------------------------------*/
	// Send message
	/*-------------------------------------------------------------------------*/		
	protected function postEditor()
	{
		# Ajax Check
		$this->ajaxCheck();
		
		# Check use permission
		$this->checkUsePerm();

		# Check conversation
		$con = $this->getCon( \IPS\Request::i()->conID );
		
		if ( ! $con->canChat() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_perm_chat' ) ) );
		}		
		
		# Forms
		$form = $con->editor();
		
		if ( $values = $form->values() )
		{
			$files = $values[ 'file_con_' . $con->id ];
			$msg = $values['chatCON_' . $con->id];
			
			# Chatter ID
			$chatterID = $member ? $member_id : \IPS\Member::loggedIn()->member_id;
					
			# Is deleted?
			if ( $con->maps()[$chatterID]['map_online'] == -1 )
			{
				\IPS\Output::i()->json( array( 'type' => 'deletedCon', 'conID' => $con->id, 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_deleted_con' ) ) );
			}
			
			# Options
			$opts = \IPS\chatbox\Member\Conversation::options();
			
			# Check and parse msg
			if ( !$files || $msg )
			{
				$msg = \IPS\Application::load('chatbox')->checkMSG( $msg, $opts );
			}
			
			# Get last chat
			$lastChat = array();
			if ( $con->lastChat )
			{
				$lastChat = json_decode( $con->lastChat, TRUE );
			}

			# Check Flood
			if ( $opts['flood'] > 0 && ! \IPS\chatbox\Member\Conversation::_canManage() && !\IPS\chatbox\Member\Conversation::_canBypassFlood() )
			{
				$myLastChat = (int) $lastChat[ $chatterID ];
				
				if ( time() - $myLastChat < $opts['flood'] )
				{
					$wait = $opts['flood'] - ( time() - $myLastChat );
					\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack('chatbox_error_flood', FALSE, array( 'sprintf' => $wait ) ) ) );
				}
			}
					
			# Save message
			$title = \IPS\Application::load('chatbox')->autoTitle( $msg ? $msg : \IPS\Member::loggedIn()->language()->get('chatbox_txt_img') );
			$title_furl = \IPS\Http\Url\Friendly::seoTitle( $title );
			$id = \IPS\Db::i()->insert( 'chatbox_conversations_posts', array(
				'chat_con'				=> $con->id,
				'chat_member_id'		=> $chatterID,
				'chat_content'			=> $msg,
				'chat_title'			=> $title,
				'chat_title_furl'		=> $title_furl,
				'chat_time'				=> time(),
			) );

			if ( $con->canUpload() )
			{
				\IPS\Application::load('chatbox')->processUploadFiles( $files, 'con', $id );
			}
			
			# Save last time chat & lastID
			$lastChat[ $chatterID ] = time();
			$con->lastChat = json_encode( $lastChat );
			$con->lastID = $id;
			$con->save();
			
			# Count unread msg
			\IPS\Db::i()->update( 'chatbox_conversations_user_map', "map_unread=map_unread+1, map_online=1, map_update=" . time(), array( 'map_con_id=? AND map_user_id!=?', $con->id, $chatterID ) );

			# Claim Attachments
			\IPS\File::claimAttachments( 'con_msg', $id, NULL, NULL );		
		}

		# Ouput Forms
		\IPS\Output::i()->json( 'OK' );	
	}
	
	/*-------------------------------------------------------------------------*/
	// Use editor to edit msg
	/*-------------------------------------------------------------------------*/	
	protected function editEditor()
	{
		# Ajax Check
		$this->ajaxCheck();
	
		# Check use permission
		$this->checkUsePerm();
			
		# Get msg by ID
		$chat = $this->getMsgByID( \IPS\Request::i()->chatID );		

		# Check permission
		if ( ! $chat->item()->canEditMsg( $chat ) )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_perm_edit' ) ) );
		}
		
		# Form
		$form = $chat->item()->editor($chat);
		
		if ( $values = $form->values() )
		{
			$files = $values[ 'file_con_' . $chat->con ];
			$content = \IPS\Request::i()->newMsg;
			$opts = \IPS\chatbox\Member\Conversation::options();
			
			# Check and parse msg
			if ( !$files || $content )
			{
				\IPS\Application::load('chatbox')->checkMSG( $content, $opts );
			}
			
			# Save
			$chat->title = \IPS\Application::load('chatbox')->autoTitle( $content );
			$chat->title_furl = \IPS\Http\Url\Friendly::seoTitle( $chat->title );
			$chat->content = $content;
			$chat->save();
			
			if ( $chat->item()->canUpload() )
			{
				\IPS\Application::load('chatbox')->processUploadFiles( $files, 'con', $chat->id );
				if ( $files )
				{
					$content = \IPS\Application::load('chatbox')->parseContent( $opts, $content ) . ' ' . (string) reset($files)->url;
				}
			}
			
			if ( $opts['use_editor'] )
			{
				\IPS\File::claimAttachments( 'con_msg', $chat->id, NULL, NULL );
			}
			
			# Save to datastore to update for all online users
			$chat->item()->markMsg( $chat->id, $content );
			
			# Done
			\IPS\Output::i()->json( array( 'content' => $content ) );
		}
		
		# Done
		if ( ! $opts['use_editor'] )
		{
			$form->class = 'ipsForm_noLabels ipsPadding cbCleanTextEdit';
		}
		else
		{
			$form->class = 'ipsForm_noLabels ipsPadding cbEditorEdit';
		}
		
		$output = (string) $form;
		
		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
		}
		else
		{
			\IPS\Output::i()->output = $output;
		}
	}	
	
	/*-------------------------------------------------------------------------*/
	// Find member
	/*-------------------------------------------------------------------------*/	
	protected function findMember()
	{
		# Check perm
		$this->ajaxCheck();
		$this->checkUsePerm();
		
		# Do search
		$results = array();
		
		$input = str_replace( array( '%', '_' ), array( '\%', '\_' ), mb_strtolower( \IPS\Request::i()->input ) );
		
		$where[] = array( "name LIKE CONCAT(?, '%')", $input );
	
		if ( \IPS\Request::i()->ignoreUsers )
		{
			$where[] = array( 'member_id NOT IN (?)', \IPS\Request::i()->ignoreUsers );
		}
		else
		{
			$where[] = array( "member_id != ?", \IPS\Member::loggedIn()->member_id );
		}
		
		$select = \IPS\Db::i()->select( '*', 'core_members', $where, 'LENGTH(name) ASC', array( 0, 20 ) );

		foreach ( $select as $row )
		{
			$member = \IPS\Member::constructFromData( $row );
			$isBan = ( \IPS\chatbox\Member\Conversation::_isBan( $member ) || ! \IPS\chatbox\Member\Conversation::_canJoin( $member ) );
			
			$results[] = array(
				'id'		=> 	$member->member_id,
				'value' 	=> 	$member->name,
				'name'		=> 	htmlspecialchars( $member->name, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ),
				'extra'		=> 	!$isBan ? $member->groupName : \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_is_ban' ),
				'photo'		=> 	(string) $member->photo,
				'isOnline'	=> 	\IPS\Application::load('chatbox')->isOnline( $member ),
				'isBan'		=>	$isBan,
			);
		}
				
		\IPS\Output::i()->json( $results );
	}
		
	/*-------------------------------------------------------------------------*/
	// Delete the conversation
	/*-------------------------------------------------------------------------*/	
	protected function delCon()
	{
		# Ajax Check
		$this->ajaxCheck();
		
		# Check use permission
		$this->checkUsePerm();	
		
		# Check conversation
		$con = $this->getCon( \IPS\Request::i()->conID );

		if ( ! $con->canDeleteCon() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_perm_del_con' ) ) );
		}

		$con->delete();

		# Done
		\IPS\Output::i()->json( 'OK' );		
	}
		
	/*-------------------------------------------------------------------------*/
	// Delete Message
	/*-------------------------------------------------------------------------*/		
	protected function deleteMSG()
	{
		# Ajax Check
		$this->ajaxCheck();
		
		# Check use permission
		$this->checkUsePerm();
		
		# Get msg by ID
		$chat = $this->getMsgByID( \IPS\Request::i()->chatID );	

		# Check permission
		if ( ! $chat->item()->_canDelete( $chat->member_id ) )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_no_perm_del' ) ) );
		}		

		# Save to datastore to update for all online users
		$chat->item()->markMsg( $chat->id );	
		
		# Delete
		$chat->delete();
		
		if ( $chat->item()->lastID <= (int) \IPS\Request::i()->chatID )
		{
			$chat->item()->updateLastID();
		}
		
		# Done
		\IPS\Output::i()->json( 'OK' );
	}
	
	/*-------------------------------------------------------------------------*/
	// Create a group chat
	/*-------------------------------------------------------------------------*/	
	public function createGroup()
	{
		$lang = \IPS\Member::loggedIn()->language();
		
		# Check permission
		$this->ajaxCheck();
		$this->checkUsePerm();
		
		if ( ! \IPS\chatbox\Member\Conversation::_canCreateGroup() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_no_perm_gcreate' ) ) );
		}
		
		$minUsers 	= 2;
		$maxUsers 	= \IPS\Settings::i()->chatbox_con_g_max_users;
		$maxGroups 	= 50;

		# Check my groups
		$myGroups = \IPS\Db::i()->select( 'COUNT(*)', 'chatbox_conversations', array( 'con_starter_id=? AND con_isGroup=1', \IPS\Member::loggedIn()->member_id ) )->first();
		if ( $myGroups >= $maxGroups )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack('chatbox_error_max_groups', FALSE, array( 'sprintf' => $maxGroups ) ) ) );				
		}
		
		# Form	
		$form = new \IPS\Helpers\Form( 'createGroup', 'cb_btn_create' );
		$form->class = 'cbCreateGroupForm';
		$form->add( new \IPS\Helpers\Form\Text( 'cb_group_name', '', FALSE, array() ) );
		$form->add( new \IPS\Helpers\Form\Text( 'cb_group_users', NULL, FALSE, array( 
			'autocomplete' 		=> array(
				'source' 				=> 'app=chatbox&module=conversation&controller=main&do=findMember',
				'resultItemTemplate' 	=> 'chatbox.search.mem',
				'minimized'				=> false,
				'unique'				=> true,
				'minItems'				=> $minUsers,
				'maxItems'				=> $maxUsers,
				'minAjaxLength'			=> 3,		
			)
		) ) );
		if ( $values = $form->values() )
		{
			$total = $values['cb_group_users'] ? \count( $values['cb_group_users'] ) : 0;
			
			if ( $total < $minUsers || $total > $maxUsers )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack('chatbox_can_not_create_group', FALSE, array( 'sprintf' => $maxUsers ) ) ) );
			}
			
			$newName = $values['cb_group_name'];
			$newName = trim( strip_tags( $newName ) );
			if ( !$newName || mb_strlen( $newName ) > 150 )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_group_rename' ) ) );
			}
			
			$con = \IPS\chatbox\Member\Conversation::createItem( \IPS\Member::loggedIn(), NULL, \IPS\DateTime::create(), NULL );
			$con->isGroup = 1;
			$con->name = $newName ? $newName : NULL;
			$con->save();
		
			$values['cb_group_users'][] = \IPS\Member::loggedIn()->name;

			$where[] = array( \IPS\Db::i()->in( 'name', $values['cb_group_users'] ) );
			$where[] = array( \IPS\Db::i()->in( 'member_group_id', explode( ',', \IPS\Settings::i()->chatbox_con_get ), FALSE ) );

			foreach ( \IPS\Db::i()->select( '*', 'core_members', $where ) as $row )
			{
				\IPS\Db::i()->insert( 'chatbox_conversations_user_map', array(
					'map_user_id'		=> $row['member_id'],
					'map_con_id'		=> $con->id,
					'map_unread'		=> 1,
					'map_online'		=> 1,
					'map_update'		=> time(),
				) );				
			}
			
			$con->addSystemMsg( 'created', \IPS\Member::loggedIn()->name );
			
			\IPS\Output::i()->json( array( 'html' => (string) $con->show(), 'conID' => $con->id ) );
		}
		
		# Output
		$output = $form->customTemplate( array( \call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
		}
		else
		{
			\IPS\Output::i()->output = $output;
		}		
	}
	
	/*-------------------------------------------------------------------------*/
	// Group permission check
	/*-------------------------------------------------------------------------*/	
	protected function checkGroupPerm( $gID )
	{
		$con = $this->getCon( $gID );
		
		if ( ! $con->isGroup )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_not_group' ) ) );
		}
		
		if ( ! $con->canChat() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_not_in_group' ) ) );
		}
		
		return $con;
	}
	
	/*-------------------------------------------------------------------------*/
	// Config Group
	/*-------------------------------------------------------------------------*/	
	public function configGroup()
	{
		# Check permission
		$this->ajaxCheck();
		$this->checkUsePerm();
		
		$lang = \IPS\Member::loggedIn()->language();

		$con = $this->checkGroupPerm( \IPS\Request::i()->conID );
		
		if ( ! $con->isGroupOwner() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_no_perm_config' ) ) );
		}

		# Options 
		$opts = $con->groupOptions();
		
		# Form	
		$form = new \IPS\Helpers\Form( 'configGroup', 'cb_btn_conf' );
		$form->class = 'cbConfigGroupForm ipsAreaBackground_light';
		$form->actionButtons[] = \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->button( "cancel", FALSE, null, 'ipsButton ipsButton_link formCancel' );
		$form->hiddenValues['conID'] = $con->id;
		
		$form->add( new \IPS\Helpers\Form\YesNo( 'cb_gOpt_mem_invite', $opts['mem_invite'] ) );
		
		if ( $values = $form->values() )
		{
			foreach( \array_keys( $values ) as $key )
			{
				if ( $key != 'conID' )
				{
					$dataOpts[ str_replace( 'cb_gOpt_', '', $key ) ] = $values[ $key ];
					unset( $values[ $key ] );
				}
			}

			if ( $dataOpts )
			{
				$saved = json_encode( $dataOpts );
			}
			
			$con->group_options = $saved;
			$con->save();

			\IPS\Output::i()->json('OK');
		}
		
		# Output
		$output = $form->customTemplate( array( \call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
		}
		else
		{
			\IPS\Output::i()->output = $output;
		}
	}
	
	/*-------------------------------------------------------------------------*/
	// Invite people to group chat
	/*-------------------------------------------------------------------------*/	
	public function inviteGroup()
	{
		# Check permission
		$this->ajaxCheck();
		$this->checkUsePerm();
		
		$lang = \IPS\Member::loggedIn()->language();
		
		# Check conversation
		$con = $this->checkGroupPerm( \IPS\Request::i()->conID );

		# Check permissions
		if ( ! $con->canInviteGroup() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_no_perm_invite' ) ) );
		}
				
		$maps = $con->maps();
		$currentUsers = $maps ? \count( $maps ) : 0;
		$maxUsers = \IPS\Settings::i()->chatbox_con_g_max_users;
		
		if ( \count( $maps ) >= $maxUsers )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack('chatbox_error_max_users_in_group', FALSE, array( 'sprintf' => $maxUsers ) ) ) );				
		}
		
		$maxItems = $maxUsers - $currentUsers;

		# Form	
		$form = new \IPS\Helpers\Form( 'inviteGroup', 'cb_btn_invite' );
		$form->class = 'cbInviteGroupForm ipsForm_noLabels ipsAreaBackground_light';
		$form->actionButtons[] = \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->button( "cancel", FALSE, null, 'ipsButton ipsButton_link formCancel' );
		$form->hiddenValues['conID'] = $con->id;
		$form->add( new \IPS\Helpers\Form\Text( 'cb_group_users', NULL, FALSE, array( 
			'autocomplete' 		=> array(
				'source' 				=> 'app=chatbox&module=conversation&controller=main&do=findMember&ignoreUsers=' . implode( ',', array_keys( $maps ) ),
				'resultItemTemplate' 	=> 'chatbox.search.mem',
				'minimized'				=> false,
				'unique'				=> true,
				'minItems'				=> 1,
				'maxItems'				=> $maxItems,
				'minAjaxLength'			=> 3,
			)
		) ) );
		
		if ( $values = $form->values() )
		{
			$total = $values['cb_group_users'] ? \count( $values['cb_group_users'] ) : 0;
			
			if ( $total < 1 || $total > $maxItems )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack('chatbox_can_not_create_group', FALSE, array( 'sprintf' => $maxUsers ) ) ) );
			}

			$where[] = array( \IPS\Db::i()->in( 'name', $values['cb_group_users'] ) );
			$where[] = array( \IPS\Db::i()->in( 'member_group_id', explode( ',', \IPS\Settings::i()->chatbox_con_get ), FALSE ) );

			foreach ( \IPS\Db::i()->select( '*', 'core_members', $where ) as $row )
			{
				if ( ! $maps[ $row['member_id'] ] )
				{
					\IPS\Db::i()->insert( 'chatbox_conversations_user_map', array(
						'map_user_id'		=> $row['member_id'],
						'map_con_id'		=> $con->id,
						'map_online'		=> 1,
						'map_unread'		=> 1,
						'map_update'		=> time(),
					) );
				}
			}
			
			$con->addSystemMsg( 'joined', implode( "&#44; ", $values['cb_group_users'] ) );
			
			\IPS\Output::i()->json( array( 'html' => (string) $con->show(), 'conID' => $con->id ) );
		}
		
		# Output
		$output = $form->customTemplate( array( \call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
		}
		else
		{
			\IPS\Output::i()->output = $output;
		}
	}
	
	/*-------------------------------------------------------------------------*/
	// Rename Group
	/*-------------------------------------------------------------------------*/	
	public function renameGroup()
	{
		# Check permission
		$this->ajaxCheck();
		$this->checkUsePerm();
		
		$lang = \IPS\Member::loggedIn()->language();

		$con = $this->checkGroupPerm( \IPS\Request::i()->conID );
		
		if ( ! $con->isGroupOwner() )
		{
			\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_no_perm_rename' ) ) );
		}

		# Form	
		$form = new \IPS\Helpers\Form( 'renameGroup', 'cb_btn_rename' );
		$form->class = 'cbRenameGroupForm ipsForm_noLabels ipsAreaBackground_light';
		$form->actionButtons[] = \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->button( "cancel", FALSE, null, 'ipsButton ipsButton_link formCancel' );
		$form->hiddenValues['conID'] = $con->id;
		$form->add( new \IPS\Helpers\Form\Text( 'cb_group_new_name', NULL, TRUE, array( 
			'placeholder'	=> $lang->addToStack('cb_group_new_name'),
		) ) );
		
		if ( $values = $form->values() )
		{
			$newName = $values['cb_group_new_name'];
			$newName = trim( strip_tags( $newName ) );
			if ( !$newName || mb_strlen( $newName ) > 150 )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => $lang->addToStack( 'chatbox_error_group_rename' ) ) );
			}
			
			$con->name = $newName;
			$con->save();
			$con->addSystemMsg( 'rename', $newName );
			
			\IPS\Output::i()->json( array( 'newName' => $newName ) );
		}
		
		# Output
		$output = $form->customTemplate( array( \call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
		}
		else
		{
			\IPS\Output::i()->output = $output;
		}
	}
	
	/*-------------------------------------------------------------------------*/
	// Leave Group
	/*-------------------------------------------------------------------------*/
	public function leaveGroup()
	{
		# Check permission
		$this->ajaxCheck();
		$this->checkUsePerm();
		
		$lang = \IPS\Member::loggedIn()->language();
		
		# Check conversation
		$con = $this->checkGroupPerm( \IPS\Request::i()->conID );		
				
		# Update
		\IPS\Db::i()->delete( 'chatbox_conversations_user_map', array( 'map_con_id=? AND map_user_id=?', $con->id, \IPS\Member::loggedIn()->member_id ) );
		
		$maps = $con->maps( TRUE );

		if ( !$maps )
		{
			$con->delete();
		}
		else
		{
			if ( \IPS\Member::loggedIn()->member_id == $con->starter_id )
			{
				$con->starter_id = key($maps);
				$con->save();
			}
		}
		
		$con->addSystemMsg( 'left', \IPS\Member::loggedIn()->name );
		
		# Done
		\IPS\Output::i()->json( array( 'conID' => $con->id ) );
	}		
	
	/*-------------------------------------------------------------------------*/
	// User in groups
	/*-------------------------------------------------------------------------*/
	public function usersInGroup()
	{
		# Check permission
		$this->ajaxCheck();
		$this->checkUsePerm();
		
		$lang = \IPS\Member::loggedIn()->language();
		
		# Check conversation
		$con = $this->checkGroupPerm( \IPS\Request::i()->conID );

		# Members
		$participants = $con->participants();
		$owner = $participants[ $con->starter_id ];
		unset( $participants[ $con->starter_id ] );
		array_unshift($participants, $owner);
		
		# Done
		$output = \IPS\Theme::i()->getTemplate( 'conversation', 'chatbox', 'front' )->groupMembers( $con, $participants );
		
		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
		}
		else
		{
			\IPS\Output::i()->output = $output;
		}		
	}
	
	/*-------------------------------------------------------------------------*/
	// Ignored Users
	/*-------------------------------------------------------------------------*/
	public function ignoredUsers()
	{
		# Check permission
		$this->ajaxCheck();
		if( ! \IPS\Member::loggedIn()->member_id || \IPS\Settings::i()->chatbox_ignore != 1 )
		{
			\IPS\Output::i()->error( 'chatbox_error_noperm', '2CHATBOX103/4', 403, '' );
		}
		
		# Form to add new 
		$lang = \IPS\Member::loggedIn()->language();
		
		$form = new \IPS\Helpers\Form();
		$form->class = 'ipsForm_noLabels';
		
		$form->add( new \IPS\Helpers\Form\Member( 'member', NULL, TRUE, array( 'placeholder' => \IPS\Member::loggedIn()->language()->addToStack('ignore_placeholder') ) ) );		
		
		# Submit
		if ( $values = $form->values() )
		{
			if ( $values['member']->member_id == \IPS\Member::loggedIn()->member_id )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'cannot_ignore_self' ) ) );
			}
			
			if ( !$values['member']->canBeIgnored() )
			{
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'cannot_ignore_that_member' ) ) );
			}
			
			try
			{
				\IPS\Db::i()->select( '*', 'chatbox_ignored_users', array( 'ignore_owner_id=? AND ignore_ignore_id=?', \IPS\Member::loggedIn()->member_id, $values['member']->member_id ) )->first();
				\IPS\Output::i()->json( array( 'type' => 'error', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'chatbox_error_ignored' ) ) );
			}
			catch ( \UnderflowException $e ){}
			
			$mem = \IPS\Db::i()->insert( 'chatbox_ignored_users', array(
				'ignore_owner_id'		=> \IPS\Member::loggedIn()->member_id,
				'ignore_ignore_id'		=> $values['member']->member_id
			) );
			
			$html = \IPS\Theme::i()->getTemplate( 'global' )->ignoreRows( NULL, NULL, array( array( 'ignore_ignore_id' => $values['member']->member_id ) ) );
				
			if ( \IPS\Request::i()->isAjax() )
			{
				\IPS\Output::i()->json( array( 'html' => $html ) );
			}
			else
			{
				\IPS\Output::i()->redirect( $url );
			}			
		}
		
		# Table
		$url = \IPS\Http\Url::internal( "app=chatbox&module=conversation&controller=main&do=ignoredUsers" );
		$table = new \IPS\Helpers\Table\Db( 'chatbox_ignored_users', $url, array( 'ignore_owner_id=?', \IPS\Member::loggedIn()->member_id ) );
		$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'global' ), 'ignoreRows' );
		$table->sortBy = 'ignore_id';
		$table->limit = 10;
		
		# Output
		$output = \IPS\Theme::i()->getTemplate( 'global' )->ignoredUsers( (string) $form, (string) $table );
		
		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
		}
		else
		{
			\IPS\Output::i()->output = $output;
		}		
	}
	
	public function delIgnoredUser()
	{
		# Check permission
		$this->ajaxCheck();
		if( ! \IPS\Member::loggedIn()->member_id || \IPS\Settings::i()->chatbox_ignore != 1 )
		{
			\IPS\Output::i()->error( 'chatbox_error_noperm', '2CHATBOX103/8', 403, '' );
		}
		
		\IPS\Db::i()->delete( 'chatbox_ignored_users', array( 'ignore_owner_id=? AND ignore_ignore_id=?', \IPS\Member::loggedIn()->member_id, (int) \IPS\Request::i()->id ) );

		if( \IPS\Request::i()->isAjax() )
		{
			\IPS\Output::i()->json( 'OK' );	
		}
		else
		{
			\IPS\Output::i()->redirect( isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : \IPS\Http\Url::internal( '' ) );
		}		
	}
	
	public function toggleMemberChat()
	{
		\IPS\Session::i()->csrfCheck();
		
		if ( ! \IPS\chatbox\Member\Conversation::_canUse() )
		{
			\IPS\Output::i()->error( 'chatbox_error_no_perm_chat', '2CHATBOX103/9', 403, '' );
		}
		
		if ( \IPS\Request::i()->cookie['chatbox_disable_member_chat'] == 1 )
		{
			\IPS\Request::i()->setCookie( 'chatbox_disable_member_chat', 0 );
		}
		else
		{
			\IPS\Request::i()->setCookie( 'chatbox_disable_member_chat', 1 );
		}
		
		\IPS\Output::i()->redirect( isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : \IPS\Http\Url::internal( '' ) );
	}
		
	
	
	
	
	
	
	
	
	
}