private void PopulateXRayPreviews(string bookTitle, XRay xray)
        {
            //Old X-ray Preview
            for (int i = 0; i < 8; i++)
            {
                frmXR.Controls["lblTerm" + (i + 1)].Visible = true;
                frmXR.Controls["lblTerm" + (i + 1)].Text = "Term " + i + " ...Waiting...";
                frmXR.Controls["pbTerm" + (i + 1)].Visible = true;
            }
            frmXR.lblBookTitle.Text = bookTitle;
            frmXR.lblXrayTermsAll.Text = String.Format("All {0}", xray.Terms.Count);
            frmXR.lblXrayTermsRest.Text = String.Format("|  People {0}  |  Terms {1}",
                xray.Terms.Count(t => t.Type.Equals("character")),
                xray.Terms.Count(t => t.Type.Equals("topic")));

            if (xray.Terms.Count != 0)
            {
                int numLabels = Math.Min(8, xray.Terms.Count);
                for (int i = 0; i < numLabels; i++)
                {
                    frmXR.Controls["lblTerm" + (i + 1)].Text = xray.Terms[i].TermName;
                    frmXR.Controls["pbTerm" + (i + 1)].Visible = true;
                }
                if (xray.Terms.Count < 8)
                {
                    for (int i = xray.Terms.Count + 1; i < 9; i++)
                    {
                        frmXR.Controls["lblTerm" + i].Visible = false;
                        frmXR.Controls["pbTerm" + i].Visible = false;
                    }
                }
            }

            //New X-ray Preview
            for (int i = 1; i <= 4; i++)
            {
                frmXRN.Controls["lblTermName" + i].Visible = true;
                frmXRN.Controls["lblTermMentions" + i].Visible = true;
                frmXRN.Controls["lblTermDescription" + i].Visible = true;
            }
            frmXRN.lblTitle.Text = "X-Ray — " + bookTitle;
            if (xray.Terms.Count != 0)
            {
                int numLabels = Math.Min(4, xray.Terms.Count);
                for (int i = 0; i < numLabels; i++)
                {
                    frmXRN.Controls["lblTermName" + (i + 1)].Text = xray.Terms[i].TermName;
                    frmXRN.Controls["lblTermMentions" + (i + 1)].Text = xray.Terms[i].Locs.Count + " Mentions";
                    frmXRN.Controls["lblTermDescription" + (i + 1)].Text = xray.Terms[i].Desc;
                }
                if (xray.Terms.Count < 4)
                {
                    for (int i = xray.Terms.Count + 1; i < 5; i++)
                    {
                        frmXRN.Controls["lblTermName" + i].Visible = false;
                        frmXRN.Controls["lblTermMentions" + i].Visible = false;
                        frmXRN.Controls["lblTermDescription" + i].Visible = false;
                    }
                }
            }
        }
        private void btnSaveShelfari_Click(object sender, EventArgs e)
        {
            if (txtShelfari.Text == "")
            {
                MessageBox.Show("No Shelfari link was specified.", "Missing Shelfari Link");
                return;
            }
            if (!File.Exists(txtMobi.Text))
            {
                MessageBox.Show("Specified book was not found.", "Book Not Found");
                return;
            }
            if (!Directory.Exists(Environment.CurrentDirectory + @"\xml\"))
                Directory.CreateDirectory(Environment.CurrentDirectory + @"\xml\");
            string path = Environment.CurrentDirectory + @"\xml\" + Path.GetFileNameWithoutExtension(txtMobi.Text) + ".xml";
            try
            {
                txtXMLFile.Text = path;

                XRay xray = new XRay(txtShelfari.Text, this, settings.spoilers);
                if (xray.SaveXml(path) > 0)
                {
                    Log("Error while processing.");
                    return;
                }
                Log("Shelfari info has been saved to: " + path);
            }
            catch (Exception)
            {
                Log("Error while saving Shelfari data to XML. Path was: " + path);
                return;
            }
        }
        private void btnBuild_Click(object sender, EventArgs e)
        {
            //Check current settings
            if (!File.Exists(txtMobi.Text))
            {
                MessageBox.Show(@"Specified book was not found.", @"Book Not Found");
                return;
            }
            if (rdoShelfari.Checked && txtShelfari.Text == "")
            {
                MessageBox.Show(@"No Shelfari link was specified.", @"Missing Shelfari Link");
                return;
            }
            if (!File.Exists(settings.mobi_unpack))
            {
                MessageBox.Show(@"Kindleunpack was not found.\r\nPlease review the settings page.", @"Kindleunpack Not Found");
                return;
            }
            if (!Directory.Exists(settings.outDir))
            {
                MessageBox.Show(@"Specified output directory does not exist.\r\nPlease review the settings page.", @"Output Directory Not found");
                return;
            }
            if (Properties.Settings.Default.realName.Trim().Length == 0
                || Properties.Settings.Default.penName.Trim().Length == 0)
            {
                MessageBox.Show(
                    @"Both Real and Pen names are required for End Action\r\n" +
                    @"file creation. This information allows you to rate this\r\n" +
                    @"book on Amazon. Please review the settings page.",
                    @"Amazon Customer Details Not found");
                return;
            }
            //Create temp dir and ensure it exists
            string randomFile = Functions.GetTempDirectory();
            if (!Directory.Exists(randomFile))
            {
                MessageBox.Show(@"Temporary path not accessible for some reason.", @"Temporary Directory Error");
                return;
            }

            prgBar.Value = 0;
            
            //0 = asin, 1 = uniqid, 2 = databasename, 3 = rawML, 4 = author, 5 = title
            List<string> results;
            if (settings.useKindleUnpack)
            {
                Log("Running Kindleunpack to get metadata...");
                results = Functions.GetMetaData(txtMobi.Text, settings.outDir, randomFile, settings.mobi_unpack);
            }
            else
            {
                Log("Extracting metadata...");
                try
                {
                    results = Functions.GetMetaDataInternal(txtMobi.Text, settings.outDir, true, randomFile).getResults();
                }
                catch (Exception ex)
                {
                    Log("Error getting metadata: " + ex.Message);
                    return;
                }
            }
            if (results.Count != 6)
            {
                Log(results[0]);
                return;
            }

            if (settings.saverawml)
            {
                Log("Saving rawML to dmp directory...");
                File.Copy(results[3], Path.Combine(Environment.CurrentDirectory + @"\dmp", Path.GetFileName(results[3])), true);
            }

            // Added author name to log output
            Log(String.Format("Got metadata!\r\nDatabase Name: {0}\r\nASIN: {1}\r\nAuthor: {2}\r\nTitle: {3}\r\nUniqueID: {4}",
                results[2], results[0], results[4], results[5], results[1]));

            Log(String.Format("Attempting to build X-Ray...\r\nSpoilers: {0}", settings.spoilers ? "Enabled" : "Disabled"));
            Log("Offset: " + settings.offset.ToString());

            //Create X-Ray and attempt to create the base file (essentially the same as the site)
            XRay xray;
            try
            {
                if (rdoShelfari.Checked)
                    xray = new XRay(txtShelfari.Text, results[2], results[1], results[0], this, settings.spoilers,
                        settings.offset, "", false);
                else
                    xray = new XRay(txtXMLFile.Text, results[2], results[1], results[0], this, settings.spoilers,
                        settings.offset, "");
                if (xray.CreateXray() > 0)
                {
                    Log("Error while processing.");
                    return;
                }
                Log("Initial X-Ray built, adding locations and chapters...");
                //Expand the X-Ray file from the unpacked mobi
                if (xray.ExpandFromRawMl(results[3], settings.ignoresofthyphen, !settings.useNewVersion) > 0)
                {
                    Log("Error while processing locations and chapters.");
                    return;
                }
            }
            catch (Exception ex)
            {
                Log("An error occurred while creating the new X-Ray database. Is it opened in another program?\r\n" + ex.Message);
                return;
            }

            Log("Saving X-Ray to file...");
            string outFolder = "";
            string _newPath = "";
            try
            {
                if (settings.android)
                {
                    outFolder = settings.outDir + @"\Android\" + results[0];
                    Directory.CreateDirectory(outFolder);
                }
                else
                    outFolder = settings.useSubDirectories ? Functions.GetBookOutputDirectory(results[4], Path.GetFileNameWithoutExtension(txtMobi.Text)) : settings.outDir;
            }
            catch (Exception ex)
            {
                Log("Failed to create output directory: " + ex.Message + "\r\nFiles will be placed in the default output directory.");
                outFolder = settings.outDir;
            }
            _newPath = outFolder + "\\" + xray.GetXRayName(settings.android);

            if (settings.useNewVersion)
            {
                try
                {
                    SQLiteConnection.CreateFile(_newPath);
                }
                catch (Exception ex)
                {
                    Log("An error occurred while creating the new X-Ray database. Is it opened in another program?\r\n" + ex.Message);
                    return;
                }
                SQLiteConnection m_dbConnection;
                m_dbConnection = new SQLiteConnection(("Data Source=" + _newPath + ";Version=3;"));
                m_dbConnection.Open();
                string sql;
                try
                {
                    using (StreamReader streamReader = new StreamReader("BaseDB.sql", Encoding.UTF8))
                    {
                        sql = streamReader.ReadToEnd();
                    }
                }
                catch (Exception ex)
                {
                    Log("An error occurred while opening the BaseDB.sql file. Ensure you extracted it to the same directory as the program.\n"
                        + ex.Message);
                    m_dbConnection.Dispose();
                    return;
                }
                SQLiteCommand command = new SQLiteCommand("BEGIN; " + sql + " COMMIT;", m_dbConnection);
                Log("Building new X-Ray database. May take a few minutes...");
                command.ExecuteNonQuery();
                command = new SQLiteCommand("PRAGMA user_version = 1; PRAGMA encoding = utf8; BEGIN;", m_dbConnection);
                command.ExecuteNonQuery();
                Log("Done building initial database. Populating with info from source X-Ray...");
                try
                {
                    xray.PopulateDb(m_dbConnection);
                }
                catch (Exception ex)
                {
                    Log("An error occurred while creating the new X-Ray database. Is it opened in another program?\r\n" + ex.Message);
                    m_dbConnection.Close();
                    m_dbConnection.Dispose();
                    return;
                }
                Log("Updating indices...");
                sql = "CREATE INDEX idx_occurrence_start ON occurrence(start ASC);\n"
                      + "CREATE INDEX idx_entity_type ON entity(type ASC);\n"
                      + "CREATE INDEX idx_entity_excerpt ON entity_excerpt(entity ASC); COMMIT;";
                command = new SQLiteCommand(sql, m_dbConnection);
                command.ExecuteNonQuery();
                m_dbConnection.Close();
                m_dbConnection.Dispose();
            }
            else
            {
                using (StreamWriter streamWriter = new StreamWriter(_newPath, false, settings.utf8 ? Encoding.UTF8 : Encoding.Default))
                {
                    streamWriter.Write(xray.ToString());
                }
            }
            if (Properties.Settings.Default.playSound)
            {
                System.Media.SoundPlayer player = new System.Media.SoundPlayer(Environment.CurrentDirectory + @"\done.wav");
                player.Play();
            }

            Log("X-Ray file created successfully!\r\nSaved to " + _newPath);

            try
            {
                PopulateXRayPreviews(results[5], xray);
                btnPreview.Enabled = true;
                cmsPreview.Items[2].Enabled = true;
            }
            catch (Exception ex)
            {
                Log("Error populating X-Ray preview windows: " + ex.Message);
            }

            try
            {
                Directory.Delete(randomFile, true);
            }
            catch (Exception)
            {
                Log("An error occurred while trying to delete temporary files.\r\nTry deleting these files manually.");
            }
        }