/* $stylesChunkName, $latestChunkName, $projectsChunkName and $numNew should be passed in */

function saveConfig ($varName, $varValue, &$modx, &$output) {
    $sql = "delete from Config where varName = ?";
    $delStmt = $modx->prepare($sql);
    $result = $delStmt->execute(array($varName));
    if ($result) {
        $sql = "insert into Config (varName, varValue) values (?, ?)";
        $insStmt = $modx->prepare($sql);
        $result = $insStmt->execute(array($varName, $varValue));
        if ($result) {
            $output .= "Delete from &amp; insert to Config succeeded. (" . $varName . "=" . $varValue . ")<br>" . PHP_EOL;
        } else {
            $msg = $selFullProject->errorInfo();
            $output .= "Delete from Config succeeded but insert failed. (" . $varName . "=" . $varValue . ") " . $msg[2] . "<br>" . PHP_EOL;
        }
    } else {
        $msg = $selFullProject->errorInfo();
        $output .= "Delete from Config failed. (" . $varName . "=" . $varValue . ") " . $msg[2] . "<br>" . PHP_EOL;
    }
}

function saveChunk (&$modx, $chunkName, $chunkContent, &$output) {
/* Retrieve or create the chunk and then set the new contents into it. */
    $chunk = $modx->getObject('modChunk', array('name' => $chunkName));
    if (! $chunk) { /* The chunk doesn't exist so create it */
        $chunk = $modx->newObject('modChunk');
        $chunk->set('name', $chunkName);
    }
    $chunk->set('description', 'This chunk was generated by snippet ms-mtk-generate on ' . date(DATE_RFC850));
    $chunk->setContent($chunkContent);
    if ($chunk->save(true)) {
        $output .= "Chunk " . $chunkName . " save succeeded.<br>" . PHP_EOL;
    } else {
        $output .= "Chunk " . $chunkName . " saved failed.<br>" . PHP_EOL;
    }
}

function makeAnchor ($inStr) {
/* Strip characters that aren't allowed in anchors. */
    $inStr = str_replace (" ", "", $inStr);
    $inStr = str_replace (",", "", $inStr);
    $inStr = str_replace (".", "", $inStr);
    $inStr = str_replace ("'", "", $inStr);
    $inStr = str_replace ("&amp;", "", $inStr);
    return $inStr;
}

function fullProjectExists ($artist, $project, &$selFullProject) {
/* Given an artist and project, determine if a full project exists. */
    $result = $selFullProject->execute(array($artist, $project));
    if (! $result) {
        $msg = $selFullProject->errorInfo();
        echo "Error selecting full project within fullProjectExists. " . $msg[2];
    }
    $selFullProject->setFetchMode(PDO::FETCH_ASSOC);
    if ($row = $selFullProject->fetch()) {
        return 1; /* A full project exists */
    } else {
        return 0; /* A full project doesn't exist */
    }
}

function getDLHTML ($artist, $project, $projectType, $urlIdentifier, $numDLs, $explicit, &$selGenerationRule, &$selDownloads) {
/* Return the HTML for the download(s) for this project */

    /* First, get the generation rule. */
    $result = $selGenerationRule->execute(array($urlIdentifier, $numDLs));
    if (! $result) {
        $msg = $selGenerationRule->errorInfo();
        echo "Error selecting DownloadSites within getDLHTML. " . $msg[2] . "<br>";
    }
    $selGenerationRule->setFetchMode(PDO::FETCH_ASSOC);
    if ($row = $selGenerationRule->fetch()) {
        $rule = $row["generationRule"];
    } else {
        echo "Generation rule not found for " . $urlIdentifier . "-" . $numDLs . " in getDLHTML<br>";
    }

    /* Now get the downloads & substitute them in the rule. */
    $result = $selDownloads->execute(array($artist, $project, $projectType));
    if (! $result) {
        $msg = $selDownloads->errorInfo();
        echo "Error selecting Downloads within getDLHTML. " . $msg[2] . "<br>";
    }
    $selDownloads->setFetchMode(PDO::FETCH_ASSOC);
    $count = 0;
    while ($row = $selDownloads->fetch()) { /* Here's where most of the substitution occurs */
        $rule = str_replace ('$URL' . $count . '$', $row["DLURL"], $rule);
        $rule = str_replace ('$DLSIZE' . $count . '$', $row["DLSize"], $rule);
        $totDlSize += $row["DLSize"];
        $count++;
    }
    $rule = str_replace ('$TOTDLSIZE$', $totDlSize, $rule);
    if ($explicit) {
        $rule = str_replace ('$EXPLICIT$', " (contains explicit lyrics)", $rule);
    } else {
        $rule = str_replace ('$EXPLICIT$', "", $rule);
    }

    return $rule;
}

function getNumProjects ($artist, $generalStyle, $specificStyle, $title, &$selDistinctProject) {
/* Return a count of the projects within this artist/generalStyle/specificStyle/title section */
    $result = $selDistinctProject->execute(array($artist, $generalStyle, $specificStyle, $title));
    if (! $result) {
        $msg = $selDistinctProject->errorInfo();
        echo "Error on execute within getSectionAnchors. " . $msg[2] . "<br>";
    }
    $selDistinctProject->setFetchMode(PDO::FETCH_ASSOC);
    $count = 0;
    while ($row = $selDistinctProject->fetch()) {
        $count++;
    }
    return $count;
}

function sectionHasNewAddition ($artist, $generalStyle, $specificStyle, $title, &$selNewProjects) {
/* Return the number of new projects within this generalStyle/artist/specificStyle/title section. This could
   have been done with a "count(*)" function but we're reusing the selNewProjects prepared statement. */
    $result = $selNewProjects->execute(array($artist, $generalStyle, $specificStyle, $title));
    if (! $result) {
        $msg = $selNewProjects->errorInfo();
        echo "Error on execute in sectionHasNewAddition. " . $msg[2] . "<br>";
    }
    $selNewProjects->setFetchMode(PDO::FETCH_ASSOC);
    $count = 0;
    while ($row = $selNewProjects->fetch()) {
        $count++;
    }
    return $count;
}

function getProjectNames ($artist, $generalStyle, $specificStyle, $title, &$selDistinctProject) {
/* Return a comma separated string of the projects within this artist/generalStyle/specificStyle/title section */
    $projects = array();
    $result = $selDistinctProject->execute(array($artist, $generalStyle, $specificStyle, $title));
    if (! $result) {
        $msg = $selDistinctProject->errorInfo();
        echo "Error on execute within getProjectNames. " . $msg[2] . "<br>";
    }

    /* Get all the project names into an array. */
    $selDistinctProject->setFetchMode(PDO::FETCH_ASSOC);
    while ($row = $selDistinctProject->fetch()) {
        array_push ($projects, $row["project"]);
    }
    
    /* String together all the project names. The first and last are treated differently. */
    $projectNames = $projects[0];
    for ($idx=1; $idx<count($projects); $idx++) {
        if ($idx == (count($projects) - 1)) {
            $projectNames .= " &amp; " . $projects[$idx]; /* This is the last one, precede it with an ampersand. */
        } else {
            $projectNames .= ", " . $projects[$idx];
        }
    }

    return $projectNames;
}

function genSectionAnchors ($artist, $artistAnchor, $generalStyle, $specificStyle, $title, &$selDistinctProject) {
/* Return a chunk call to format all the anchors within the artist/generalStyle/specificStyle/title section.
   There's one anchor per distinct project (i.e no dups for Full/Excerpt) */
    $result = $selDistinctProject->execute(array($artist, $generalStyle, $specificStyle, $title));
    if (! $result) {
        $msg = $selDistinctProject->errorInfo();
        echo "Error on execute within getSectionAnchors. " . $msg[2] . "<br>";
    }
    $selDistinctProject->setFetchMode(PDO::FETCH_ASSOC);
    while ($row = $selDistinctProject->fetch()) {
        $chunkContent .= "<span id=" . '"' . $artistAnchor . "_" . makeAnchor($row{"project"}) . '"' . "></span>" . PHP_EOL;
    }
    return $chunkContent;
}

function anchorAlreadyGenerated ($idx, &$artists) {
/* This would be hard to do in SQL! Figure out whether the artist at $idx has occurred previously (perhaps in
   another style) and already had its default anchor generated. Having two anchors with the same name is an
   error in HTML. */
    $found = false;
    $r = 0;
    While (($r < $idx) and (! $found)) {
        if ($artists[$r] == $artists[$idx]) {
            $found = true;
        }
        $r++;
    }
    return $found;
}

function genArtistHeader ($artist, $artistAnchor, $generalStyle, $specificStyle, $title, $idx, &$artists, &$selNewProjects, &$selDistinctProject) {
/* Generate the MODX chunk contents for this section's anchors & header including the artist, title & specificStyle.  */
    global $bannerNum;

    $chunkContent = "";

    /* Generate the default anchor if it hasn't already been generated. */
    if (! anchorAlreadyGenerated ($idx, $artists)) {
        $chunkContent .= "<span id=" . '"' . $artistAnchor . '"' . "></span>" . PHP_EOL;
    }

    /* Generate anchors for each unique project */
    $chunkContent .= genSectionAnchors($artist, $artistAnchor, $generalStyle, $specificStyle, $title, $selDistinctProject);

    /* Use the title field or construct the title by concatenating the project names. */
    if ($title == "") {
        $headerTitle = getProjectNames ($artist, $generalStyle, $specificStyle, $title, $selDistinctProject);
    } else {
        $headerTitle = $title;
    }

    /* Generate the artist header (new or not). */
    $numNewAdditions = sectionHasNewAddition ($artist, $generalStyle, $specificStyle, $title, $selNewProjects);
    for ($i=0; $i<$numNewAdditions; $i++) {
        $chunkContent .= '[[+shuffledBanner' . str_pad($bannerNum++, 1, '0') . ']]' . PHP_EOL;
    }
    $chunkContent .= "<ul>" . PHP_EOL . 
                     "    <li>" . PHP_EOL;
    if ($numNewAdditions > 0) {
        $chunkContent .= '    <span class="artistHeader"><span class="newTextColor">NEW! </span>' . $artist . ": " . $headerTitle . "</span><br>" . PHP_EOL;
    } else {
        $chunkContent .= '    <span class="artistHeader">' . $artist . ": " . $headerTitle . "</span><br>" . PHP_EOL;
    }
    $chunkContent .= '    <span class="artistStyle">Style: ' . $specificStyle . ' (<a href="#LatestAdditions">back to top</a>)</span><br>' . PHP_EOL .
                     "    <ul>" . PHP_EOL;
    return $chunkContent;
}

function genProjectData (&$modx, &$output) {
    /* Set up arrays */
    $artists = array();
    $artistAnchors = array();
    $projects = array();
    $projectTypes = array();
    $generalStyles = array();
    $specificStyles = array();
    $titles = array();
    $previewURLs = array();
    $wimpyURLs = array();
    $explicitLyricss = array();
    $numTrackss = array();
    $moreInfoTIDs = array();
    $discussFIDs = array (); 
    $showFIDs = array();
    $actives = array();
    $urlIdentifiers = array();
    $numDLss  = array();
    $isNews  = array();
    $styleAnchors  = array();
    $comments  = array(); 

    $sql =  "select * from Artists, Projects, Styles, SectionComments ";
    $sql .= "    where ";
    $sql .= "        active = 1 and ";
    $sql .= "        Artists.artist = Projects.artist and ";
    $sql .= "        Projects.generalStyle = Styles.generalStyle and ";
    $sql .= "        SectionComments.artist = Projects.artist and ";
    $sql .= "        SectionComments.generalStyle = Projects.generalStyle and ";
    $sql .= "        SectionComments.specificStyle = Projects.specificStyle and ";
    $sql .= "        SectionComments.title = Projects.title and ";
    $sql .= "        active = 1 ";
    $sql .= "    order by ";
    $sql .= "        sequence, ";
    $sql .= "        artistSort, ";
    $sql .= "        Projects.title, ";
    $sql .= "        Projects.specificStyle, ";
    $sql .= "        Projects.project, ";
    $sql .= "        projectType ";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute();
    if (! $result) {
        $msg = $stmt->errorInfo();
        echo "Error in function genProjectData in snippet ms-mtk-generate. " . $msg[2];
    }
    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $numRows = 0;
    while ($row = $stmt->fetch()) {    /* MySQL doesn't allow 2 cursors open at the same time (?!) so buffer the results of the main select. */
        array_push ($artists, $row["artist"]);
        array_push ($artistAnchors, $row["artistAnchor"]);
        array_push ($projects, $row["project"]);
        array_push ($projectTypes, $row["projectType"]);
        array_push ($generalStyles, $row["generalStyle"]);
        array_push ($specificStyles, $row["specificStyle"]);
        array_push ($titles, $row["title"]);
        array_push ($previewURLs, $row["previewURL"]);
        array_push ($wimpyURLs, $row["wimpyURL"]);
        array_push ($explicitLyricss, $row["explicitLyrics"]);
        array_push ($numTrackss, $row["numTracks"]);
        array_push ($moreInfoTIDs, $row["moreInfoTID"]);
        array_push ($discussFIDs, $row["discussFID"]);
        array_push ($showFIDs, $row["showFID"]);
        array_push ($actives, $row["active"]);
        array_push ($urlIdentifiers, $row["urlIdentifier"]);
        array_push ($numDLss, $row["numDLs"]);
        array_push ($isNews, $row["isNew"]);
        array_push ($styleAnchors, $row["styleAnchor"]);
        array_push ($comments, $row["comment"]);
        $numRows++;
    }
    $output .= $numRows . " projects processed.<br>" . PHP_EOL;

    /* Prepare a select to see if the current section contains a New Addition. */
    $sql = "select * from Projects where artist = ? and generalStyle = ? and specificStyle = ? and title = ? and isNew = 1";
    $selNewProjects = $modx->prepare($sql);

    /* Prepare a select to get all projects for a section. */
    $sql = "select distinct project from Projects where artist = ? and generalStyle = ? and specificStyle = ? and title = ? and active = 1";
    $selDistinctProject = $modx->prepare($sql);

    /* Prepare a select to get the generationRule for a given DownloadSite template. */
    $sql = "select * from DownloadSites where urlIdentifier = ? and numDLs = ?";
    $selGenerationRule = $modx->prepare($sql);

    /* Prepare a select to get the download(s) for a given project. */
    $sql = "select * from Downloads where artist = ? and project = ? and projectType = ? order by DLURL";
    $selDownloads = $modx->prepare($sql);

    /* Prepare a select to see if there's a full project given an artist and project name. */
    $sql = "select * from Projects where artist = ? and project = ? and projectType = 'Full'";
    $selFullProject = $modx->prepare($sql);

    /* Init vars for the loop that follows */
    $chunkContent = "";
    $bannerNum = 0;
    $idx = 0;

    /* Gen the first style and artist header */
    $chunkContent .= '<span id="' . $styleAnchors[0] . '"></span>' . PHP_EOL;
    $chunkContent .= '<span class="musicStyleHeader">' . $generalStyles[0] . "</span><br>" . PHP_EOL . PHP_EOL;
    $lastGeneralStyle = $generalStyles[0];
    $chunkContent .= genArtistHeader ($artists[0], $artistAnchors[0], $generalStyles[0], $specificStyles[0], $titles[0], $idx, $artists, $selNewProjects, $selDistinctProject);
    $lastArtist = $artists[0];
    $lastSpecificStyle = $specificStyles[0];
    $lastTitle = $titles[0];

    /* Loop through the project data arrays. */
    while ($idx<count($artists)) {
        if ($generalStyles[$idx] != $lastGeneralStyle) {
            $chunkContent .= "    </ul>" . PHP_EOL . 
                             "    " . $comments[$idx - 1] . "<br>" . PHP_EOL .
                             "    </li>" . PHP_EOL . 
                             "</ul>" . PHP_EOL . PHP_EOL . PHP_EOL;
            $chunkContent .= '<span id="' . $styleAnchors[$idx] . '"></span>' . PHP_EOL;
            $chunkContent .= '<span class="musicStyleHeader">' . $generalStyles[$idx] . "</span><br>" . PHP_EOL . PHP_EOL;
            $lastGeneralStyle = $generalStyles[$idx];
            $chunkContent .= genArtistHeader ($artists[$idx], $artistAnchors[$idx], $generalStyles[$idx], $specificStyles[$idx], $titles[$idx], $idx, $artists, $selNewProjects, $selDistinctProject);
            $lastArtist = $artists[$idx];
            $lastSpecificStyle = $specificStyles[$idx];
            $lastTitle = $titles[$idx];
        } elseif (($artists[$idx] != $lastArtist) or ($specificStyles[$idx] != $lastSpecificStyle) or ($titles[$idx] != $lastTitle)) {
            $chunkContent .= "    </ul>" . PHP_EOL .
                             "    " . $comments[$idx - 1] . "<br>" . PHP_EOL .
                             "    </li>" . PHP_EOL .
                             "</ul>" . PHP_EOL . PHP_EOL . PHP_EOL;
            $chunkContent .= genArtistHeader ($artists[$idx], $artistAnchors[$idx], $generalStyles[$idx], $specificStyles[$idx], $titles[$idx], $idx, $artists, $selNewProjects, $selDistinctProject);
            $lastArtist = $artists[$idx];
            $lastSpecificStyle = $specificStyles[$idx];
            $lastTitle = $titles[$idx];
        }

        /* Format a project line here. First whether or not the project name should show up. */
        $chunkContent .= "    <li>" . PHP_EOL .
                         '        <span class="projectLine"><span class="projectNameType">';
        if ((getNumProjects($artists[$idx], $generalStyles[$idx], $specificStyles[$idx], $titles[$idx], $selDistinctProject) == 1) and
            ($titles[$idx] == "")) {
            /* Don't show the name of this project, it's the only one up in the header. */
        } else {
            $chunkContent .= $projects[$idx] . " -- ";
        }

        /* Format project type */
        if ($projectTypes[$idx] == "Full") {
            $chunkContent .= '<strong class="fullProjectTextColor">Full Multitrack:</strong></span> ';
        } else {
            $chunkContent .= '<strong class="excerptProjectTextColor">Edited Excerpt:</strong></span> ';
        }

        /* Format previews */
        $chunkContent .= 'preview <a href="' . $previewURLs[$idx] . '">MP3</a>&nbsp;</span><div class="WimpyButton_7780205" data-wimpybutton="' . $wimpyURLs[$idx] . '"></div>';

        /* Format number of tracks */
        $chunkContent .= '<span class="projectLine">&nbsp;&nbsp;<strong>&bull;</strong>&nbsp;&nbsp;' . $numTrackss[$idx];
        if ($numTrackss[$idx] == 1) {
            $chunkContent .= " track: ";
        } else {
            $chunkContent .= " tracks: ";
        }

        /* Get the download HTML */
        $chunkContent .= getDLHTML ($artists[$idx], $projects[$idx], $projectTypes[$idx], $urlIdentifiers[$idx], $numDLss[$idx],
                                    $explicitLyricss[$idx], $selGenerationRule, $selDownloads);

        /* Gen more info if needed */
        if ($moreInfoTIDs[$idx] != "0") {
            $chunkContent .= '&nbsp;&nbsp;<strong>&bull;</strong>&nbsp;&nbsp;<a href="http://discussion.cambridge-mt.com/showthread.php?tid=' .
                             $moreInfoTIDs[$idx] . '">More info...</a>';
        }

        /* Gen discussion group link if needed */
        if (($showFIDs[$idx]) && ($discussFIDs[$idx])) {
            $chunkContent .= '&nbsp;&nbsp;<strong>&bull;</strong>&nbsp;&nbsp;<a href="http://discussion.cambridge-mt.com/forumdisplay.php?fid=' . 
                              $discussFIDs[$idx] . '">&rarr;Mixes and discussion</a>';
        }

        /* Gen the direct link */
        $directLink = $artistAnchors[$idx] . "_" . makeAnchor($projects[$idx]);
        if ($projectTypes[$idx] == "Full") {
            /* Always do a direct link for full projects. */
            $chunkContent .= '&nbsp;&nbsp;<strong>&bull;</strong>&nbsp;&nbsp;(<a href="#' . $directLink . '">direct-link URL</a>)';
        } else {
            if (! fullProjectExists ($artists[$idx], $projects[$idx], $selFullProject)) {
                /* Only do a direct link on an Excerpt if it has no corresponding full project. */
                $chunkContent .= '&nbsp;&nbsp;<strong>&bull;</strong>&nbsp;&nbsp;(<a href="#' . $directLink . '">direct-link URL</a>)';
            }
        }

        $chunkContent .= "</span>" . PHP_EOL;
        $chunkContent .= "    </li>" . PHP_EOL . PHP_EOL;
        $idx++;
    }
    $chunkContent .= "    </ul>" . PHP_EOL . 
                     "    " . $comments[$idx - 1] . "<br>" . PHP_EOL .
                     "    </li>" . PHP_EOL .
                     "</ul>" . PHP_EOL . PHP_EOL;
    return $chunkContent;
}

function genOneNewAddition ($artist, $anchor, $project, $projectType, $wimpyURL, $specificStyle, &$stmt, &$output) {
/* Generate one new addition line and set the "isNew" flag on that project. */
    $projectLink = $anchor . "_" . makeAnchor($project);

    $chunkContent .= '<span class="previewArtist">' . $artist . ' -- </span><span class="previewProject"><a href="#' . $projectLink . '">' . 
                     $project . "</a></span>" . PHP_EOL;
    $chunkContent .= '<div class="WimpyButton_7780205" data-wimpybutton="' . $wimpyURL . '"></div> -- (' . $specificStyle . ")<br>" . PHP_EOL;

    /* Mark this artist/project/type as "New" */
    $result = $stmt->execute(array($artist, $project, $projectType));
    if (! $result) {
        $msg = $stmt->errorInfo();
        $output .= "Update to Projects failed. " . $msg[2];
    }

    return $chunkContent;
}

function genLatest (&$modx, $numNew) {
/* Generate the HTML for the $numNew latest additions to the library. This routine
   sets the "isNew" flag in the Projects table so genProjects can flag the artist
   entry with "NEW!" when it runs. */

    /* Setup the arrays for the main select. We only need these 6 columns from the Projects table. */
    $artists = array();
    $artistAnchors = array();
    $projects = array();
    $projectTypes = array();
    $wimpyURLs = array();
    $specificStyles = array();

    /* Reset "isNew" to false (zero) on all rows. */
    $sql = 'update Projects set isNew=0';
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute();
    if (! $result) {
        $msg = $stmt->errorInfo();
        echo "Error on execute of '" . $sql . "'. " . $msg[2];
    }

    /* Select all projects ordered from newest to oldest. */
    $sql = "select * from Artists, Projects where Artists.artist = Projects.artist order by dateAdded desc";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute();
    if (! $result) {
        $msg = $stmt->errorInfo();
        echo "Error on execute of " . $sql . ". " . $msg[2];
    }
    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    while ($row = $stmt->fetch()) {    /* MySQL doesn't allow 2 cursors open at the same time (?!) so buffer the results of the main select. */
        array_push ($artists, $row["artist"]);
        array_push ($artistAnchors, $row["artistAnchor"]);
        array_push ($projects, $row["project"]);
        array_push ($projectTypes, $row["projectType"]);
        array_push ($wimpyURLs, $row["wimpyURL"]);
        array_push ($specificStyles, $row["specificStyle"]);
    }

    /* Prepare the select to see if there's a corresponding Full project to a given Excerpt. */
    $sql = "select * from Projects where artist = ? and project = ? and projectType = 'Full'";
    $selFullStmt = $modx->prepare($sql);

    /* Prepare the update to reset the isNew flag on all Projects. This will happen in genOneNewAddition. */
    $sql = "update Projects set isNew = 1 where artist = ? and project = ? and projectType = ?";
    $updStmt = $modx->prepare($sql);

    /* Loop through the buffered project data. */
    $countNew = 0;
    $idx = 0;
    while (($idx<count($artists)) && ($countNew < $numNew)) {
        if ($projectTypes[$idx] == "Excerpt") {
            if (fullProjectExists ($artists[$idx], $projects[$idx], $selFullStmt)) {
                /* Do nothing this is an Excerpt that has a corresponding Full project. */
            } else {
                $chunkContent .= genOneNewAddition ($artists[$idx], $artistAnchors[$idx], $projects[$idx], $projectTypes[$idx], $wimpyURLs[$idx], 
                                                    $specificStyles[$idx], $updStmt, $output);
                $countNew++;
            }
        } else {
            $chunkContent .= genOneNewAddition ($artists[$idx], $artistAnchors[$idx], $projects[$idx], $projectTypes[$idx], $wimpyURLs[$idx], 
                                                $specificStyles[$idx], $updStmt, $output);
            $countNew++;
        }
        $idx++;
    }
    return $chunkContent;
}

function genStyles (&$modx) {
/* Generate the Styles HTML. */
    $sql = "select * from Styles order by sequence";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute();
    if (! $result) {
        $msg = $stmt->errorInfo();
        echo "Error on execute in genStyles. " . $msg[2];
    }
    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $chunkContent = ""; 
    while ($row = $stmt->fetch()) {
        $chunkContent .= '  <a href="#' . $row["styleAnchor"] . '">' . $row["generalStyle"] . "</a><br>" . PHP_EOL;
    }
    return $chunkContent;
}

function generate (&$modx, &$output) {
/* Generate logic for styles, latest additions & projects (the main part). Save the entered data
   (chunk name, numNew) in the Config table, generate the text then save it to the chunk. */

    saveConfig ("stylesChunkName", $_POST["stylesChunkName"], $modx, $output);
    $chunkContent = genStyles ($modx);
    saveChunk ($modx, $_POST["stylesChunkName"], $chunkContent, $output);

    saveConfig ("latestChunkName", $_POST["latestChunkName"], $modx, $output);
    saveConfig ("numNew", $_POST["numNew"], $modx, $output);
    $chunkContent = genLatest ($modx, $_POST["numNew"]);
    saveChunk ($modx, $_POST["latestChunkName"], $chunkContent, $output);

    saveConfig ("projectsChunkName", $_POST["projectsChunkName"], $modx, $output);
    $chunkContent = genProjectData ($modx, $output);
    saveChunk ($modx, $_POST["projectsChunkName"], $chunkContent, $output);
}

function showFID (&$modx, &$output) {
    $sql = "update Projects set showFID = 1 where active = 1 and discussFID > 0";
    $updateStmt = $modx->prepare($sql);
    $result = $updateStmt->execute(array($artist, $project, $projectType));
    if ($result) {
        $output .= "Update to Projects succeeded.<br>" . PHP_EOL;
    } else {
        $msg = $updateStmt->errorInfo();
        $output .= "Update to Projects failed. " . $msg[2];
    }
}

/* Main line logic */
if (!empty($_POST)) {

    /* Determine which button was clicked. */
    if (array_key_exists ("Show", $_POST)) {
        showFID ($modx, $output);
    } elseif (array_key_exists ("Generate", $_POST)) {
        $bannerNum = 0; /* This should be global in functions that use it. */
        generate ($modx, $output);
    }

    /* Set Template Variables for ms-mtk Update Status. */
    $page = $modx->getObject('modResource', array("pagetitle" => "ms-mtk-UpdateStatus"));
    $page->setTVValue('updateStatus', $output);
    $resId = $modx->resource->get('id'); /* Get the ID of this page. */
    $url = $modx->makeUrl($resId); /* Turn the ID into a URL. */
    $page->setTVValue('returnToResource', $url); /* Set the URL into a TV for the page to return to on "Continue". */
    $modx->cacheManager->refresh(); /* Should probably change this to only clear the resource cache */
    $modx->sendRedirect($modx->makeUrl($page->get('id')));
}