<?PHP
#
#   FILE:  Message.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2012-2013 Edward Almasy and Internet Scout Research Group
#   http://scout.wisc.edu/cwis
#

/**
* Abstraction for forum messages and resource comments.
* \nosubgrouping
*/
class Message
{

    # ---- PUBLIC INTERFACE --------------------------------------------------

    const OK = 0;
    const NONEXISTENT = 1;

    const PARENTTYPE_TOPIC = 1;
    const PARENTTYPE_RESOURCE = 2;

    /** @name Setup/Initialization/Destruction */
    /*@{*/

    /**
    * Object constructor.
    * After constructing the object, be sure to call GetErrorStatus() and verify
    * that it returns Message::OK.
    * @param int $MessageId The message Id to retrieve from the database, or
    *   -1 to create a new message
    */
    public function __construct($MessageId = NULL)
    {
        $this->ErrorStatus = self::NONEXISTENT;
        $this->DB = new Database();

        # no ID supplied
        if (is_null($MessageId))
        {
            # add record to database with that ID
            $this->DB->Query("INSERT INTO Messages (MessageId) VALUES (NULL)");
            $this->DB->Query("SELECT LAST_INSERT_ID() AS Id FROM Messages");

            if ($this->DB->NumRowsSelected())
            {
                $this->MessageId = intval($this->DB->FetchField("Id"));
                $this->ErrorStatus = self::OK;
            }
        }

        # ID supplied
        else
        {
            $this->DB->Query("
                SELECT * FROM Messages
                WHERE MessageId = '".intval($MessageId)."'");

            if ($this->DB->NumRowsSelected())
            {
                # set attributes to values returned by database
                $this->DBFields = $this->DB->FetchRow();
                $this->MessageId = intval($this->DBFields["MessageId"]);
                $this->ErrorStatus = self::OK;
            }
        }
    }

    /**
    * Delete this message from the underlying database
    */
    public function Delete()
    {
        if ($this->ErrorStatus == self::OK)
        {
            $this->DB->Query("DELETE FROM Messages WHERE MessageId = ".$this->MessageId);
        }
    }

    /*@}*/

    /** @name Accessors */
    /*@{*/

    /**
    * Get this message's messageId.
    * @return int Message ID.
    */
    public function MessageId()
    {
        return $this->MessageId;
    }

    /**
    * Get the CWIS username of the most recent poster.
    * @return string CWIS username of the most recent poster.
    */
    public function PosterName()
    {
        $PosterName = new CWUser((int)$this->PosterId());
        return $PosterName->Get("UserName");
    }

    /**
    * Get the email address of the most recent poster
    * @return string Email address of the most recent poster.
    */
    public function PosterEmail()
    {
        $PosterName = new CWUser((int)$this->PosterId());
        return $PosterName->Get("EMail");
    }

    /**
    * Get the CWIS user ID of the most recent editor.
    * @param int $NewValue New editor ID.  (OPTIONAL)
    * @return int CWIS user ID of the most recent editor.
    */
    public function EditorId($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("EditorId", $NewValue);
    }

    /**
    * Get or set the ParentId.
    * For forum posts, the ParentId is a TopicId.
    * For resource comments, the ParentId is the ResourceId.
    * @param int $NewValue New value to set (OPTIONAL)
    * @return The current ParentId
    */
    public function ParentId($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("ParentId", $NewValue);
    }

    /**
    * Get or set the ParentType.
    * Parent Type = 1 for forum posts and
    * Parent Type = 2 for resource comments
    * @param int $NewValue New parent type.  (OPTIONAL)
    * @return int Current parent type.
    */
    public function ParentType($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("ParentType", $NewValue);
    }

    /**
    * Get or set the date posted.
    * @param string $NewValue New posting date.  (OPTIONAL)
    * @return string Posting date.
    */
    public function DatePosted($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("DatePosted", $NewValue);
    }

    /**
    * Get or set the date the message was last edited
    * @param string $NewValue New edit date.  (OPTIONAL)
    * @return string Date the message was last edited.
    */
    public function DateEdited($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("DateEdited", $NewValue);
    }

    /**
    * Get or set the poster id (e.g., the author) for this message.
    * @param int $NewValue New poster ID.  (OPTIONAL)
    * @return int ID number of this message's author.
    */
    public function PosterId($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("PosterId", $NewValue);
    }

    /**
    * Get or set the message subject.
    * @param string $NewValue New subject text.  (OPTIONAL)
    * @return string Message subject.
    */
    public function Subject($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("Subject", $NewValue);
    }

    /**
    * Get or set the message body.
    * @param string $NewValue New body text.  (OPTIONAL)
    * @return string Message body.
    */
    public function Body($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("Body", $NewValue);
    }

    /**
    * Retrieve the error status.
    * @return Message::OK if everything worked, something else otherwise
    */
    public function GetErrorStatus()
    {
        return $this->ErrorStatus;
    }

    /*@}*/

    # ---- PRIVATE INTERFACE -------------------------------------------------

    private $MessageId;
    private $DB;
    private $DBFields;
    private $ErrorStatus;

    /**
    * Convenience function to supply parameters to Database->UpdateValue().
    * @param string $FieldName The name of the field to be updated.
    * @param mixed $NewValue The new value of the specified field.
    * @return The updated value if the operation was successful,
    *        otherwise NULL.
    */
    private function UpdateValue($FieldName, $NewValue)
    {
        if ($this->ErrorStatus == self::OK)
        {
            return $this->DB->UpdateValue(
                    "Messages", $FieldName, $NewValue,
                    "MessageId = '".$this->MessageId."'", $this->DBFields, TRUE);
        }
        else
        {
            return NULL;
        }
    }
}
