<?php

	lt_include( PLOG_CLASS_PATH.'class/dao/privatemessagereceiverreadstatus.class.php' );	

    /**
	 * \ingroup DAO
	 *
     * Model for the private message feature
     */
    class PrivateMessages extends Model
	{

		function PrivateMessages()
		{
			$this->Model();

			$this->table = $this->getPrefix()."private_messages";
		}

		/**
         * Adds a private message to the database
         *
         * @param privateMessage a PrivateMessage Object
         * @return True if successful or false otherwise.
         */
        function addPrivateMessage( $privateMessage )
        {
        	$result = $this->add( $privateMessage );

			if( $result ) {
				// clean the cache
                $this->_cache->removeData( $privateMessage->getId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
                $this->_cache->removeData( $privateMessage->getBoxId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES_BY_BOX_ID );
				// update corresponding counters
				$box = $privateMessage->getBox();
				$box->setNumPrivateMessages( $box->getNumPrivateMessages() + 1 );
				$box->setNumUnreadPrivateMessages( $box->getNumUnreadPrivateMessages() + 1 );
				$privateMessageBoxes = new PrivateMessageBoxes();
				$privateMessageBoxes->updatePrivateMessageBox( $box );
			}

            return $result;
        }

		/**
         * Updates a private message to the database
         *
         * @param $privateMessage a PrivateMessage object
         * @return True if successful or false otherwise.
         */
        function updatePrivateMessage( &$privateMessage )
        {
			// get the previous version of this private message before saving it
			$prevVersion = $this->getPrivateMessage( $privateMessage->getId());

        	$result = $this->update( $privateMessage );

            if( !$result ) {
            	return false;
            }

            // clean the cache
            $this->_cache->removeData( $privateMessage->getId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
            $this->_cache->removeData( $privateMessage->getBoxId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES_BY_BOX_ID );
 			// update corresponding counters
			$box = $prevVersion->getBox();
			if( $prevVersion->getReceiverReadStatus() == PRIVATE_MESSAGE_RECEIVER_UNREAD &&
				$privateMessage->getReceiverReadStatus() == PRIVATE_MESSAGE_RECEIVER_READ )
			{
				$box->setNumUnreadPrivateMessages( $box->getNumUnreadPrivateMessages() - 1 );
				$privateMessageBoxes = new PrivateMessageBoxes();
				$privateMessageBoxes->updatePrivateMessageBox( $box );
			} elseif ( $prevVersion->getReceiverReadStatus() == PRIVATE_MESSAGE_RECEIVER_READ &&
					   $privateMessage->getReceiverReadStatus() == PRIVATE_MESSAGE_RECEIVER_UNREAD )
			{
				$box->setNumUnreadPrivateMessages( $box->getNumUnreadPrivateMessages() + 1 );
				$privateMessageBoxes = new PrivateMessageBoxes();
				$privateMessageBoxes->updatePrivateMessageBox( $box );
			}

          	return true;
        }

		/**
         * Mark private message as read, a shortcut to updatePrivateMessage
         *
         * @param $privateMessage a PrivateMessage object
         * @return True if successful or false otherwise.
         */
        function markPrivateMessasgeAsRead( &$privateMessage )
        {
			$privateMessage->setStatus( PRIVATE_MESSAGE_READ );
			$result = $this->updatePrivateMessage( $privateMessage );

			return $result;
        }

		/**
         * Mark private message as unread, a shortcut to updatePrivateMessage
         *
         * @param $privateMessage a PrivateMessage object
         * @return True if successful or false otherwise.
         */
        function markPrivateMessasgeAsUnread( &$privateMessage )
        {
			$privateMessage->setStatus( PRIVATE_MESSAGE_UNREAD );
			$result = $this->updatePrivateMessage( $privateMessage );

			return $result;
        }

		/**
         * Get all iprivate messages from a boxId from the db.
		 *
         * @param boxId Box identifier of the message
		 * @param searchTerms
		 * @param page
		 * @param itemsPerPage
		 * @return Returns an array of Private Messages for that specific Receiver.
         */
		function getPrivateMessagesFromBoxId( $boxId, $searchTerms = "", $page = -1, $itemsPerPage = 15 )
		{
			$privateMessages = $this->getMany( "box_id",
			                                   $boxId,
			                                   DaoCacheConstants::CACHE_PRIVATE_MESSAGES_BY_BOX_ID,
			                                   Array( DaoCacheConstants::CACHE_PRIVATE_MESSAGES => "getId" ),
			                                   Array( "date" => "DESC" ),
			                                   $searchTerms,
			                                   $page,
			                                   $itemsPerPage );

            if( !$privateMessages )
            	return Array();
            else
            	return( $privateMessages );
		}

		function getNumPrivateMessagesFromBoxId( $boxId, $searchTerms = "" )
		{
			return( count( $this->getPrivateMessagesFromBoxId( $boxId, $searchTerms )));
		}

		/**
         * get a specific private message from the db.
		 *
		 * @param $messageId The id of the private message.
		 * @return Returns the specific private message as a PrivateMessage object.
         */
		function getPrivateMessage( $messageId )
        {
        	$privateMessage = $this->get( "id", $messageId, DaoCacheConstants::CACHE_PRIVATE_MESSAGES );

        	return $privateMessage;
		}

		/**
         * get a specific private message from the db.
		 *
		 * @param $messageId The id of the private message.
		 * @param $receiverId The user identifier. Used as a security function, so that you
		 * can only see your own private messages.
		 * @return Returns the specific private message as a PrivateMessage object.
         */
		function getPrivateMessageByReceiverId( $messageId, $receiverId )
        {
        	$privateMessage = $this->get( "id", $messageId, DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
        	if( !$privateMessage )
        		return false;

        	if( $privateMessage->getReceiverId() == $receiverId )
				return $privateMessage;
			else
				return false;
		}

		/**
         * get a specific private message from the db.
		 *
		 * @param $messageId The id of the private message.
		 * @param $senderId The user identifier. Used as a security function, so that you
		 * can only see your own private messages.
		 * @return Returns the specific private message as a PrivateMessage object.
         */
		function getPrivateMessageBySenderId( $messageId, $senderId )
        {
        	$privateMessage = $this->get( "id", $messageId, DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
        	if( !$privateMessage )
        		return false;

        	if( $privateMessage->getSenderId() == $senderId )
				return $privateMessage;
			else
				return false;
		}

        /**
         * Removes a private message object from the database.
         *
         * @param messageId The private message identifier.
         * @param receiverId The receiver identifier.
         * @return True if successful or false otherwise.
         */
        function deletePrivateMessage( $messageId, $receiverId )
        {
        	$privateMessage = $this->getPrivateMessage( $messageId, $receiverId );
        	if( $privateMessage ) {
        		$this->delete( "id", $messageId );
                $this->_cache->removeData( $privateMessage->getId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
                $this->_cache->removeData( $privateMessage->getBoxId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES_BY_BOX_ID );

			    // update corresponding counters
				$box = $privateMessage->getBox();
				$box->setNumPrivateMessages( $box->getNumPrivateMessages() - 1 );
				if( $privateMessage->getReceiverReadStatus() == PRIVATE_MESSAGE_RECEIVER_UNREAD )
				{
					$box->setNumUnreadPrivateMessages( $box->getNumUnreadPrivateMessages() - 1 );
				}
				$privateMessageBoxes = new PrivateMessageBoxes();
				$privateMessageBoxes->updatePrivateMessageBox( $box );

				return true;
        	}
        	else
        		return false;
        }

        /**
         * Removes all the private messages from the given receiver id
         *
         * @param receiverId The receiver identifier
         */
        function deletePrivateMessagesByBoxId( $boxId )
        {
        	$privateMessages = $this->getPrivateMessagesFromBoxId( $boxId );
        	if( $this->delete( "box_id", $boxId )) {
        		foreach( $privateMessages as $privateMessage ) {
        			$this->_cache->removeData( $privateMessage->getId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
        		}
	        	$this->_cache->removeData( $boxId, DaoCacheConstants::CACHE_PRIVATE_MESSAGES_BY_BOX_ID );
	        	return true;
        	}
        	else
        		return false;
        }

        /**
         * Removes all the users' private messages from the given sender id
         *
         * @param receiverId The receiver identifier
         */
        function deleteAllUsersPrivateMessagesBySenderId( $senderId )
        {
        	$privateMessages = $this->_getAllUsersPrivateMessagesBySenderId( $senderId );
        	if( $this->delete( "sender_id", $senderId )) {
        		if( $privateMessages ) {
	        		foreach( $privateMessages as $privateMessage ) {
	        			$this->_cache->removeData( $privateMessage->getId(), DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
	        		}
	        	}
	        	return( $this->_cache->removeData( $boxId, DaoCacheConstants::CACHE_PRIVATE_MESSAGES_BY_BOX_ID ));
        	}
        	else
        		return false;
        }

        /**
		 * Retrieves the private messages of the given sender identifier. This method only
		 * used in $this->deleteAllUsersPrivateMessagesBySenderId()
         *
         * @param friendId Identifier of the user
		 */
		function _getAllUsersPrivateMessagesBySenderId( $senderId )
		{
			$privateMessages = Array();
			$query = "SELECT id FROM ".$this->table." WHERE sender_id = '".$senderId;

			$result = $this->Execute( $query );
			if( !$result )
				return $result;

			while( $row = $result->FetchRow()) {
				// use the primary key to retrieve the items via the cache
				$privateMessages[] = $this->get( "id", $row["id"], DaoCacheConstants::CACHE_PRIVATE_MESSAGES );
			}

            return $privateMessages;
		}

		/**
		 * @see Model::getSearchConditions
		 */
		function getSearchConditions( $searchTerms )
		{
			return( "(normalized_subject LIKE '%".LtDb::qstr( $searchTerms )."%' OR normalized_message LIKE '%".LtDb::qstr( $searchTerms )."%')" );
		}

		/**
		 * @private
		 */
        function mapRow( $row )
        {
            $privateMessage = new PrivateMessage( $row["box_id"],
			                                      $row["receiver_id"],
			                                      $row["sender_id"],
			                                      $row["subject"],
			                                      $row["message"],
			                                      $row["date"],
			                                      $row["receiver_read_status"],
			                                      $row["id"] );

			// set the normalized text and topic
			$privateMessage->setNormalizedSubject( $row['normalized_subject'] );
			$privateMessage->setNormalizedMessage( $row['normalized_message'] );

			return $privateMessage;
        }
	}
?>