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 getConfig (&$modx, $varName) {
    $sql = "select varValue from Config where varName = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($varName));
    if (! $result) {
        $msg = $stmt->errorInfo();
        echo 'Error in getVar of snippet "getProjectsJS". ' . $msg[2] . PHP_EOL;
    }
    $stmt->setFetchMode(PDO::FETCH_NUM);
    while ($row = $stmt->fetch()) {
        $output = $row[0];
    }
    return $output;
}

function deleteOne (&$modx, &$output, &$abortFlag) {
/* Delete an artist/project/type from the database. */

    /* Delete all the download entries. */
    $sql = "delete from Downloads where artist = ? and project = ? and projectType = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["delArtist"], $_POST["delProject"], $_POST["delProjectType"]));
    if ($result) {
        $output .= "Delete from Downloads succeeded.<br>" . PHP_EOL;
    } else {
        $output .= "Delete from Downloads failed. " . $msg[2] . "<br>" . PHP_EOL;
        $abortFlag = true;
        return;
    }

    /* Get generalStyle, specificStyle and title for this project & save for a later delete if this
       project is the only one that uses them. */
    $sql = "select * from Projects where artist = ? and project = ? and projectType = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["delArtist"], $_POST["delProject"], $_POST["delProjectType"]));
    if ($result) {
        $stmt->setFetchMode(PDO::FETCH_ASSOC);
        while ($row = $stmt->fetch()) {
            $generalStyle = $row["generalStyle"];
            $specificStyle = $row["specificStyle"];
            $title = $row["title"];
        }
    } else {
        $output .= "Select from Projects failed. " . $msg[2] . "<br>" . PHP_EOL;
        $abortFlag = true;
        return;
    }

    /* Delete the selected artist/project/projectType */
    $sql = "delete from Projects where artist = ? and project = ? and projectType = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["delArtist"], $_POST["delProject"], $_POST["delProjectType"]));
    if ($result) {
        $output .= "Delete from Projects succeeded.<br>" . PHP_EOL;
    } else {
        $output .= "Delete from Projects failed. " . $msg[2] . "<br>" . PHP_EOL;
        $abortFlag = true;
        return;
    }

    /* Are there any more projects in this section? (i.e. with this artist/generalStyle/specificStyle/title?) */
    $sql = "select count(*) from Projects where artist = ? and generalStyle = ? and specificStyle = ? and title = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["delArtist"], $generalStyle, $specificStyle, $title));
    if ($result) {
        $stmt->setFetchMode(PDO::FETCH_NUM);
        while ($row = $stmt->fetch()) {
            $count = $row[0];
        }
    } else {
        $output .= "Select count(*) from Projects failed. " . $msg[2] . "<br>" . PHP_EOL;
        $abortFlag = true;
        return;
    }

    /* If this is the only project remaining in the section, delete the SectionComments row. */
    if ($count == 0) {
        $sql = "delete from SectionComments where artist = ? and generalStyle = ? and specificStyle = ? and title = ?";
        $stmt = $modx->prepare($sql);
        $result = $stmt->execute(array ($_POST["delArtist"], $generalStyle, $specificStyle, $title));
        if ($result) {
            $output .= "Delete from SectionComments succeeded.<br>" . PHP_EOL;
        } else {
            $output .= "Delete from SectionComments failed. " . $msg[2] . "<br>" . PHP_EOL;
            $abortFlag = true;
            return;
        }
    }

    /* Are there any more projects by this artist? */
    $sql = "select count(*) from Projects where artist = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["delArtist"]));
    if ($result) {
        $stmt->setFetchMode(PDO::FETCH_NUM);
        while ($row = $stmt->fetch()) {
            $count = $row[0];
        }
    } else {
        $output .= "Select count (*) from Projects failed. " . $msg[2] . "<br>" . PHP_EOL;
        $abortFlag = true;
        return;
    }

    /* If this Artist doesn't have any projects, delete it. */
    if ($count == 0) {
        $sql = "delete from Artists where artist = ?";
        $stmt = $modx->prepare($sql);
        $result = $stmt->execute(array ($_POST["delArtist"]));
        if ($result) {
            $output .= "Delete from Artists succeeded.<br>" . PHP_EOL;
        } else {
            $output .= "Delete from Artists failed. " . $msg[2] . "<br>" . PHP_EOL;
            $abortFlag = true;
            return;
        }
    }
}

function insertSectionComments (&$modx, &$output, &$abortFlag) {
    $sql = "insert into SectionComments (artist, generalStyle, specificStyle, title, comment) values (?, ?, ?, ?, ?)";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["artist"], $_POST["generalStyle"], $_POST["specificStyle"], $_POST["albumTitle"], $_POST["comment"]));
    if ($result) {
        $output .= "Insert to SectionComments succeeded.<br>" . PHP_EOL;
    } else {
        $msg = $stmt->errorInfo();
        if ($msg[1] == 1062) { /* 1062 is duplicate key so update the row */
            $output .= "Insert to SectionComments failed on duplicate key.<br>";
            $sql = "update SectionComments set comment = ? where artist = ? and generalStyle = ? and specificStyle = ? and title = ?";
            $stmt = $modx->prepare($sql);
            $result = $stmt->execute(array ($_POST["comment"], $_POST["artist"], $_POST["generalStyle"], $_POST["specificStyle"], $_POST["albumTitle"]));
            if ($result) {
                $output .= "Update to SectionComments succeeded.<br>" . PHP_EOL;
            } else {
                $msg = $stmt->errorInfo();
                $output .= "Update to SectionComments failed. " . $msg[2] . "<br>" . PHP_EOL;
                $abortFlag = true;
            }
        } else {
            $output .= "Insert to SectionComments failed. " . $msg[2] . "<br>" . PHP_EOL;
            $abortFlag = true;
        }
    }
}

function insertDownloads (&$modx, &$output, &$abortFlag) {
/* First delete any downloads that may be there. That would be none for a new add. */
    $sql = "delete from Downloads where artist = ? and project = ? and projectType = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["artist"], $_POST["project"], $_POST["projectType"]));
    if ($result) {
        $output .= "Delete from Downloads succeeded.<br>" . PHP_EOL;
    } else {
        $msg = $stmt->errorInfo();
        $output .= "Delete from Downloads failed. " . $msg[2] . "<br>" . PHP_EOL;
        $abortFlag = true;
    }

    /* Now loop through the download fields inserting into the DB. */
    $sql = "insert into Downloads (artist, project, projectType, DLURL, DLSize) value (?, ?, ?, ?, ?)";
    $stmt = $modx->prepare($sql);
    for ($idx=1; $idx<10; $idx++) {
        if (($_POST["DLURL" . $idx] != "") && ($_POST["dlSize" . $idx] != "")) {
            $result = $stmt->execute(array ($_POST["artist"], $_POST["project"], $_POST["projectType"], $_POST["DLURL" . $idx], $_POST["dlSize" . $idx]));
            if ($result) {
                $output .= "Insert to Downloads succeeded.<br>" . PHP_EOL;
            } else {
                $msg = $stmt->errorInfo();
                $output .= "Insert to Downloads failed. " . $msg[2] . "<br>" . PHP_EOL;
                $abortFlag = true;
            }
        }
    }
}

function insertProject (&$modx, $dlIdentifier, $numDLs, &$output, &$abortFlag) {
    $sql = "insert into Projects " .
        "(artist, project, projectType, generalStyle, specificStyle, title, dateAdded, previewURL, wimpyURL, explicitLyrics, " .
        "numTracks, moreInfoTID, discussFID, showFID, active, urlIdentifier, numDLs, isNew) " .
        "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["artist"], $_POST["project"], $_POST["projectType"], $_POST["generalStyle"], $_POST["specificStyle"], 
                                    $_POST["albumTitle"], $_POST["dateAdded"], $_POST["previewURL"], $_POST["wimpyURL"], $_POST["explicitLyrics"],
                                    $_POST["numTracks"], $_POST["moreInfoTID"], $_POST["discussFID"], $_POST["showFID"], 1, $dlIdentifier, $numDLs, 1));
    if ($result) {
        $output .= "Insert to Projects succeeded.<br>" . PHP_EOL;
    } else {
        $msg = $stmt->errorInfo();
        if ($msg[1] == 1062) { /* 1062 is duplicate key so update the row */
            $output .= "Insert to Projects failed on duplicate key.<br>" . PHP_EOL;
            $sql = "update Projects " .
                "set generalStyle=?, specificStyle=?, title=?, dateAdded=?, previewURL=?, wimpyURL=?, explicitLyrics=?, " .
                "numTracks=?, moreInfoTID=?, discussFID=?, showFID=?, active=?, urlIdentifier=?, numDLs=? " .
                "where artist=? and project=? and projectType=?";
            $stmt = $modx->prepare($sql);
            $result = $stmt->execute(array ($_POST["generalStyle"], $_POST["specificStyle"], $_POST["albumTitle"], $_POST["dateAdded"],
                                            $_POST["previewURL"], $_POST["wimpyURL"], $_POST["explicitLyrics"], $_POST["numTracks"],
                                            $_POST["moreInfoTID"], $_POST["discussFID"], $_POST["showFID"], $_POST["active"], $dlIdentifier, $numDLs,
                                            $_POST["artist"], $_POST["project"], $_POST["projectType"]));
            if ($result) {
                $output .= "Update to Projects succeeded.<br>" . PHP_EOL;
            } else {
                $msg = $stmt->errorInfo();
                $output .= "Update to Projects failed. " . $msg[2] . "<br>" . PHP_EOL;
                $abortFlag = true;
            }
        } else {
            $output .= "Insert to Projects failed. " . $msg[2] . "<br>" . PHP_EOL;
            $abortFlag = true;
        }
    }
}

function insertTitle (&$modx, &$output, &$abortFlag) {
    $sql = "insert into Titles (title) values (?)";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["albumTitle"]));
    if ($result) {
        $output .= "Insert to Titles succeeded.<br>" . PHP_EOL;
    } else {
        $msg = $stmt->errorInfo();
        if ($msg[1] == 1062) { /* 1062 is duplicate key so all's well, the data already there */
            $output .= "Insert to Titles failed on duplicate key.<br>" . PHP_EOL;
        } else {
            $output .= "Insert to Titles failed. " . $msg[2] . "<br>" . PHP_EOL;
            $abortFlag = true;
        }
    }
}

function insertSpecificStyle (&$modx, &$output, &$abortFlag) {
    $sql = "insert into SpecificStyles (specificStyle) values (?)";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["specificStyle"]));
    if ($result) {
        $output .= "Insert to SpecificStyles succeeded.<br>" . PHP_EOL;
    } else {
        $msg = $stmt->errorInfo();
        if ($msg[1] == 1062) { /* 1062 is duplicate key so all's well, the data already there */
            $output .= "Insert to SpecificStyles failed on duplicate key.<br>" . PHP_EOL;
        } else {
            $output .= "Insert to SpecificStyles failed. " . $msg[2] . "<br>" . PHP_EOL;
            $abortFlag = true;
        }
    }
}

function insertArtist (&$modx, &$output, &$abortFlag) {
/* Insert a row into the Artist DB table. If insert fails on dup key, update the row instead. */
    $sql = "insert into Artists (artist, artistSort, artistAnchor) values (?, ?, ?)";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($_POST["artist"], $_POST["artistSort"], $_POST["artistAnchor"]));
    if ($result) {
        $output .= "Insert to Artists was successful.<br>" . PHP_EOL;
    } else {
        $msg = $stmt->errorInfo();
        if ($msg[1] == 1062) { /* 1062 is duplicate key so update the row */
            $output .= "Insert to Artists failed on duplicate key.<br>";
            $sql = "update Artists set artistSort = ?, artistAnchor = ? where artist = ?";
            $stmt = $modx->prepare($sql);
            $result = $stmt->execute(array ($_POST["artistSort"], $_POST["artistAnchor"], $_POST["artist"]));
            if ($result) {
                $output .= "Update to Artists succeeded.<br>" . PHP_EOL;
            } else {
                $msg = $stmt->errorInfo();
                $output .= "Update to Artists failed. " . $msg[2] . "<br>" . PHP_EOL;
                $abortFlag = true;
                return;
            }
        } else {
            $output .= "Insert to Artists failed. " . $msg[2] . "<br>" . PHP_EOL;
            $abortFlag = true;
            return;
        }
    }
}

function findUrlIdentifier (&$modx, $dl, $numDLs, &$output, &$abortFlag) {
/* Find the URL identifier that matches the firt download and the number of downloads. */
    $sql = "select * from DownloadSites where numDLs = ?";
    $stmt = $modx->prepare($sql);
    $result = $stmt->execute(array ($numDLs));
    if ($result) {
        $output .= "Select from DownloadSites succeeded.<br>" . PHP_EOL;
    } else {
        $msg = $stmt->errorInfo();
        $output .= "Select from DownloadSites failed." . $msg[2] . "<br>" . PHP_EOL;
        $abortFlag = true;
    }
    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $urlId = "";
    while ($row = $stmt->fetch()) {
        if (strpos ($dl, $row["urlIdentifier"]) === false) {
            /* There was no match, do nothing */
        } else {
            $urlId = $row["urlIdentifier"];
        }
    }
    return $urlId;
}

function countDLs () {  
/* Count the downloads that were on the screen */
    $cnt = 0;
    for ($idx=1; $idx<10; $idx++) {
        if (($_POST["DLURL" . $idx] != "") && ($_POST["dlSize" . $idx] != "")) {
            $cnt++;
        }
    }
    return $cnt;
}

function updateAdd (&$modx, &$output, &$abortFlag) {
/* Do a couple edit checks before inserting (or updating) the DB */
    $numDLs = countDLs ();
    if ($numDLs == 0) {
        $output .= "There are no downloads defined for this project.<br>";
    } else {
        $dlIdentifier = findUrlIdentifier ($modx, $_POST["DLURL1"], $numDLs, $output, $abortFlag);
        if ($dlIdentifier == "") {
            $output .= "There is no entry in DownloadSites that matches the first download of this project.<br>";
        } else {
            insertArtist ($modx, $output, $abortFlag);
            insertSpecificStyle ($modx, $output, $abortFlag);
            insertTitle ($modx, $output, $abortFlag);
            insertProject ($modx, $dlIdentifier, $numDLs, $output, $abortFlag);
            insertDownloads ($modx, $output, $abortFlag);
            insertSectionComments ($modx, $output, $abortFlag);
        }
    }
}

if (!empty($_POST)) {
    $modx->beginTransaction();
    $output = "Transaction began.<br>" . PHP_EOL;
    $abortFlag = false;

    /* Determine which button was clicked. */
    if (array_key_exists ("updateAdd", $_POST)) {
        updateAdd ($modx, $output, $abortFlag);
        saveConfig ("lastArtist", $_POST["artist"], $modx, $output); 
        saveConfig ("lastProject", $_POST["project"], $modx, $output); 
        saveConfig ("lastType", $_POST["projectType"], $modx, $output); 
    } elseif (array_key_exists ("delete", $_POST)) {
        deleteOne ($modx, $output, $abortFlag);
        saveConfig ("lastArtist", "", $modx, $output); 
        saveConfig ("lastProject", "", $modx, $output); 
        saveConfig ("lastType", "", $modx, $output); 
    }

    /* Commit or roll back the transacton. */
    if ($abortFlag) {
        $modx->rollBack();
        $output .= "Transaction rolled back.<br>" . PHP_EOL;
    } else {
        $modx->commit();
        $output .= "Transaction committed.<br>" . PHP_EOL;
    }

    if (($abortFlag) || (getConfig($modx, 'debug') == "1")) {
        /* 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')));
    }
}