<?PHP

/**
 * CWIS plugin that provides foldering functionality for resources.
 */
class Folders extends Plugin
{

    /**
     * Register information about this plugin.
     * @return void
     */
    public function Register()
    {
        $this->Name = "Folders";
        $this->Version = "1.0.1";
        $this->Description = "Functionality for adding resources into folders.";
        $this->Author = "Internet Scout";
        $this->Url = "http://scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array("CWISCore" => "2.3.1");
        $this->EnabledByDefault = FALSE;

        $this->CfgSetup["NumDisplayedResources"] = array(
            "Type" => "Number",
            "Label" => "Resource to Display in Sidebar",
            "Help" => "The number of resources to display in the sidebar for "
                     ."the selected folder",
            "MaxVal" => 20);
    }

    /**
     * Create the database tables necessary to use this plugin.
     * @return NULL on success or an error message otherwise
     */
    public function Install()
    {
        $Database = new Database();

        # selected folders table
        if (FALSE === $Database->Query("
            CREATE TABLE IF NOT EXISTS Folders_SelectedFolders (
                OwnerId      INT,
                FolderId     INT,
                PRIMARY KEY  (OwnerId)
            );"))
        { return "Could not create the selected folders table"; }

        $this->ConfigSetting("NumDisplayedResources", 5);
    }

    /**
     * Uninstall the plugin.
     * @return NULL|string NULL if successful or an error message otherwise
     */
    public function Uninstall()
    {
        $Database = new Database();

        # selected folders table
        if (FALSE === $Database->Query("DROP TABLE Folders_SelectedFolders;"))
        { return "Could not remove the selected folders table"; }
    }

    /**
     * Declare the events this plugin provides to the application framework.
     * @return array the events this plugin provides
     */
    public function DeclareEvents()
    {
        return array(
            "FOLDERS_GET_SELECTED_FOLDER" => ApplicationFramework::EVENTTYPE_FIRST,
            "FOLDERS_RESOURCE_IN_SELECTED_FOLDER" => ApplicationFramework::EVENTTYPE_FIRST);
    }

    /**
     * Hook the events into the application framework.
     * @return array the events to be hooked into the application framework
     */
    public function HookEvents()
    {
        return array(
            "EVENT_IN_HTML_HEADER" => "InHtmlHeader",
            "EVENT_REQUEST_SIDEBAR_CONTENT" => "RequestSidebarContent",
            "FOLDERS_GET_SELECTED_FOLDER" => "GetSelectedFolder",
            "FOLDERS_RESOURCE_IN_SELECTED_FOLDER" => "ResourceInSelectedFolder");
    }

    /**
     * Print HTML intended for the document head element.
     * @return void
     */
    public function InHtmlHeader()
    {
        global $AF;

        $AF->RequireUIFile("CW-Popup.js");
        $AF->RequireUIFile("jquery-ui.js");
?>
        <link rel="stylesheet" type="text/css" href="plugins/Folders/include/folders.css" />
        <script type="text/javascript" src="plugins/Folders/include/Folders.js"></script>
        <script type="text/javascript" src="plugins/Folders/include/main.js"></script>
<?PHP
    }

    /**
     * Return a HTML list of resources in the currently selected folder.
     * @return string HTML content
     */
    public function RequestSidebarContent()
    {
        global $User;

        # do not return content if the user is not logged in
        if (!$User->IsLoggedIn())
        {
            return NULL;
        }

        $SelectedFolder = $this->GetSelectedFolder($User);
        $Name = $SelectedFolder->Name();
        $ItemIds = $SelectedFolder->GetItemIds();
        $ItemCount = count($ItemIds);
        $HasResources = $ItemCount > 0;
        $NumDisplayedResources = $this->ConfigSetting("NumDisplayedResources");
        $HasMoreResources = $ItemCount > $NumDisplayedResources;
        $ResourceInfo = array();

        foreach ($ItemIds as $ResourceId) {
            $Resource = new Resource($ResourceId);
            $Title = Folders_Common::GetSafeResourceTitle($Resource);

            $ResourceInfo[$ResourceId] = array(
                "ResourceId" => defaulthtmlentities($Resource->Id()),
                "ResourceTitle" => NeatlyTruncateString($Title, 24));

            # only display the first $NumDisplayedResources
            if (count($ResourceInfo) >= $NumDisplayedResources)
            {
                break;
            }
        }

        $SafeFolderId = defaulthtmlentities($SelectedFolder->Id());
        $SafeName = defaulthtmlentities(NeatlyTruncateString($Name, 18));

        ob_start();
?>
        <!-- BEGIN FOLDERS DISPLAY -->
        <div class="cw-section cw-section-simple cw-html5-section folders-sidebar">
          <div class="cw-section-header cw-html5-header">
            <a href="index.php?P=P_Folders_ViewFolder&amp;FolderId=<?PHP print $SafeFolderId; ?>">
              <?PHP if ($Name) { ?>
                <b><?PHP print $SafeName; ?></b>
              <?PHP } else { ?>
                <b>Current Folder</b>
              <?PHP } ?>
            </a>
            <a class="cw-button cw-button-constrained cw-button-elegant" href="index.php?P=P_Folders_ManageFolders">Manage</a>
          </div>
          <div class="cw-section-body">
            <?PHP if ($HasResources) { ?>
              <ul class="cw-list cw-list-noindent cw-list-dotlist">
                <?PHP foreach ($ResourceInfo as $Info) { extract($Info); ?>
                  <li>
                    <a href="index.php?P=FullRecord&amp;ID=<?PHP print $ResourceId; ?>">
                      <?PHP print $ResourceTitle; ?>
                    </a>
                  </li>
                <?PHP } ?>
              </ul>
              <?PHP if ($HasMoreResources) { ?>
                <a class="folders-seeall" href="index.php?P=P_Folders_ViewFolder&amp;FolderId=<?PHP print $SafeFolderId; ?>">See all &rarr;</a>
              <?PHP } ?>
            <?PHP } else { ?>
              <p class="folders-noitems">There are no resources in this folder.</p>
            <?PHP } ?>
          </div>
        </div>
        <!-- END FOLDERS DISPLAY -->
<?PHP
        $Content = ob_get_contents();
        ob_end_clean();

        return $Content;
    }

    /**
     * Get the selected folder for the given owner.
     * @param mixed User object, user ID, or NULL to use the global user object
     * @return Folder|null selected folder or NULL if it can't be retrieved
     */
    public function GetSelectedFolder($Owner=NULL)
    {
        global $User;

        # look for passed in user object, user ID, and then the global user
        # object
        $IsLoggedIn = $User->IsLoggedIn();
        $Owner = $Owner instanceof User ? $Owner->Id() : $Owner;
        $Owner = !$Owner && $IsLoggedIn ? $User->Id() : $Owner;

        $FolderFactory = new Folders_FolderFactory($Owner);

        try
        {
            $SelectedFolder = $FolderFactory->GetSelectedFolder();
        }

        catch (Exception $Exception)
        {
            return NULL;
        }

        return $SelectedFolder;
    }

    /**
     * Get the resource folder for the given owner.
     * @param mixed User object, user ID, or NULL to use the global user object
     * @return Folder|null resource folder that contains folders of resources or
     *   NULL if it can't be retrieved
     */
    public function GetResourceFolder($Owner=NULL)
    {
        global $User;

        # look for passed in user object, user ID, and then the global user
        # object
        $IsLoggedIn = $User->IsLoggedIn();
        $Owner = $Owner instanceof User ? $Owner->Id() : $Owner;
        $Owner = !$Owner && $IsLoggedIn ? $User->Id() : $Owner;

        $FolderFactory = new Folders_FolderFactory($Owner);

        try
        {
            $ResourceFolder = $FolderFactory->GetResourceFolder();
        }

        catch (Exception $Exception)
        {
            return NULL;
        }

        return $ResourceFolder;
    }

    /**
     * Determine whether the given resource is in the currently selected folder.
     * @param Resource $Resource resource
     * @param User|integer User object or user ID
     * @return boolean TRUE if the resource is in the folder, FALSE otherwise
     */
    public function ResourceInSelectedFolder(Resource $Resource, $Owner=NULL)
    {
        return $this->GetSelectedFolder($Owner)->ContainsItem($Resource->Id());
    }

}
