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

/**
* Abstraction for topics within a Forum.
* @nosubgrouping
*/
class Topic {

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

    # Error codes for the TOPIC
    const OK = 0;
    const NONEXISTENT = 1;

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

    /**
    * Object Constructor. After constructing the object, be sure to call
    * GetErrorStatus() and verify that it returns Topic::OK.
    * @param int $TopicId The Id desired from the database, or -1 to generate a
    *      a new topic
    * @see GetErrorStatus()
    */
    public function __construct($TopicId = NULL )
    {
        $this->ErrorStatus = self::OK;
        # locate class in database
        $this->DB = new Database();
        $DB = $this->DB;
        # if ID supplied
        if ($TopicId !== NULL)
        {
            $this->TopicId = intval($TopicId);
            $DB->Query("SELECT * FROM Topics WHERE TopicId = ".$this->TopicId);

            # if row was loaded
            if ($DB->NumRowsSelected() > 0)
            {
                # set attributes to values returned by database
                $this->DBFields = $DB->FetchRow();
            }
            else
            {
                $this->ErrorStatus = self::NONEXISTENT;
            }
        }
        elseif (func_num_args()==0)
        {
            # add record to database with that ID
            $DB->Query("INSERT INTO Topics (TopicId) VALUES (NULL)");
            $this->TopicId = $DB->Query("SELECT LAST_INSERT_ID()"
                    ." AS TopicId FROM Topics", "TopicId");
        }
        else
        {
            $this->ErrorStatus = self::NONEXISTENT;
        }
    }

    /**
    * Remove this topic from the database, deleting the underlying messages.
    */
    public function Delete()
    {
        if ($this->ErrorStatus == self::OK)
        {
            # decrement the topic count for the parent forum
            $Forum = new Forum($this->ForumId());
            $Forum->TopicCount($Forum->TopicCount() - 1);

            $this->DB->Query("Select * from Messages where ParentId = ".
                             $this->TopicId." AND ParentType = 1");

            # delete messages associated with this topic
            while ($Entry = $this->DB->FetchRow())
            {
                $Message = new Message($Entry["MessageId"]);
                $Message->Delete();
            }
            $this->DB->Query("DELETE FROM Topics WHERE TopicId=".$this->TopicId);
        }
    }

    /*@}*/

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

    /**
    * Get the list of messages in this topic.
    * @return Returns an array of Message objects, indexed by message ID.
    */
    public function GetMessageList()
    {
        $Messages = array();

        # query for messages associated with this topic
        $this->DB->Query("
            SELECT * FROM Messages
            WHERE ParentId = '".addslashes($this->TopicId)."'
            AND ParentType = '1'
            ORDER BY DatePosted ASC");

        # create Message objects from the results
        while (FALSE !== ($Row = $this->DB->FetchRow()))
        {
            $Messages[$Row["MessageId"]] = new Message($Row["MessageId"]);
        }

        return $Messages;
    }

    /**
    * Get the ID of this topic.
    * @return Returns the ID of this topic.
    */
    public function TopicId()
    {
        return $this->TopicId;
    }

    /**
    * Get the CWIS name of the user who created this topic.
    * @return Returns the CWIS name of the user who created this topic.
    */
    public function CreatorName()
    {
        $CreatorName = new CWUser((int)$this->CreatorId());
        return $CreatorName->Get("UserName");
    }

    /**
    * Get the e-mail address of the user who created this topic.
    * @return Returns the e-mail address of the user who created this topic.
    */
    public function CreatorEmail()
    {
        $CreatorName = new CWUser((int)$this->CreatorId());
        return $CreatorName->Get("EMail");
    }

    /**
    * Set or modify the forum with which this topic is associated.
    * @param int $NewValue ID of the forum with which this topic is associated.
    *      This parameter is optional.
    * @return Returns the ID of the forum currently associated with this topic.
    */
    public function ForumId($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("ForumId", $NewValue);
    }

    /**
    * Get or set the creator of this topic.
    * @param int $NewValue User ID of the creator of this topic. This parameter
    *      is optional.
    * @return Returns the user ID of user who created the topic.
    */
    public function CreatorId($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("CreatorId", $NewValue);
    }

    /**
    * Get or set the creation date of this topic.
    * @param string $NewValue Creation date of this topic. This parameter is
    *      optional.
    * @return Returns the current creation date.
    */
    public function DateCreated($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("DateCreated", $NewValue);
    }

    /**
    * Get or modify the name of this topic.
    * @param string $NewValue Name of this topic. This parameter is optional.
    * @return Returns the current name of this topic.
    */
    public function TopicName($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("TopicName", $NewValue);
    }

    /**
    * Get or set the view count for this topic.
    * @param int $NewValue View count value for this topic. This parameter is
    *      optional.
    * @return Returns the current view count for this topic.
    */
    public function ViewCount($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("ViewCount", $NewValue);
    }

    /**
    * Get or set the message count for this topic.
    * @param int $NewValue Message count for this topic. This parameter is
    *      optional.
    * @return Returns the current message count.
    */
    public function MessageCount($NewValue = DB_NOVALUE)
    {
        return $this->UpdateValue("MessageCount", $NewValue);
    }

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

    /*@}*/

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

    private $TopicId;
    private $DB;
    private $DBFields;
    private $ErrorStatus;

    /**
    * Convenience method used to supply parameters to Database::UpdateValue()
    * @param string $FieldName Name of the field to update
    * @param mixed $NewValue New value to set for the field
    */
    private function UpdateValue($FieldName, $NewValue)
    {
        if ($this->ErrorStatus == self::OK)
        {
            return $this->DB->UpdateValue("Topics", $FieldName, $NewValue,
                    "TopicId = '".$this->TopicId."'", $this->DBFields, TRUE);
        }
        else
        {
            return NULL;
        }
    }

}
