/// <summary> Saves the data rendered by this element to the provided bibliographic object during postback </summary>
        /// <param name="Bib"> Object into which to save the user's data, entered into the html rendered by this element </param>
        public override void Save_To_Bib(SobekCM_Item Bib)
        {
            string subject_text = String.Empty;

            string[] getKeys = HttpContext.Current.Request.Form.AllKeys;
            foreach (string thisKey in getKeys)
            {
                if (thisKey.IndexOf(html_element_name.Replace("_", "") + "_text") == 0)
                {
                    subject_text = HttpContext.Current.Request.Form[thisKey];
                }

                if (thisKey.IndexOf(html_element_name.Replace("_", "") + "_select") == 0)
                {
                    string subject_type = HttpContext.Current.Request.Form[thisKey];
                    Subject_Info_Standard standardSubject = new Subject_Info_Standard {Authority = "fast"};

                    if (subject_text.Trim().Length > 0)
                    {
                        switch (subject_type)
                        {
                            case "genre":
                                standardSubject.Add_Genre( subject_type );
                                break;

                            case "geographic":
                                standardSubject.Add_Geographic( subject_type );
                                break;

                            case "occupational":
                                standardSubject.Add_Occupation( subject_type );
                                break;

                            case "temporal":
                                standardSubject.Add_Temporal( subject_type );
                                break;

                            case "topic":
                                standardSubject.Add_Topic( subject_type );
                                break;
                        }

                        if ((standardSubject.Topics_Count > 0) || (standardSubject.Genres_Count > 0) || (standardSubject.Geographics_Count > 0) || (standardSubject.Occupations_Count > 0) || (standardSubject.Temporals_Count > 0))
                            Bib.Bib_Info.Add_Subject(standardSubject);
                    }

                    subject_text = String.Empty;
                }
            }
        }
        private static void read_subject_object(XmlReader r, Bibliographic_Info thisBibInfo)
        {
            string language = String.Empty;
            string authority = String.Empty;
            string id = String.Empty;

            if (r.MoveToAttribute("ID"))
                id = r.Value;
            if (r.MoveToAttribute("lang"))
                language = r.Value;
            if (r.MoveToAttribute("authority"))
                authority = r.Value;

            // Move to the next element
            while (r.Read())
            {
                if (r.NodeType == XmlNodeType.Element)
                    break;
            }

            // Determine the subject type
            Subject_Info_Type type = Subject_Info_Type.UNKNOWN;

            // What is the name of this node?
            switch (r.Name)
            {
                case "mods:topic":
                case "mods:geographic":
                case "mods:genre":
                case "mods:temporal":
                case "mods:occupation":
                case "topic":
                case "geographic":
                case "genre":
                case "temporal":
                case "occupation":
                    type = Subject_Info_Type.Standard;
                    break;

                case "mods:hierarchicalGeographic":
                case "hierarchicalGeographic":
                    type = Subject_Info_Type.Hierarchical_Spatial;
                    break;

                case "mods:cartographics":
                case "cartographics":
                    type = Subject_Info_Type.Cartographics;
                    break;

                case "mods:name":
                case "name":
                    type = Subject_Info_Type.Name;
                    break;

                case "mods:titleInfo":
                case "titleInfo":
                    type = Subject_Info_Type.TitleInfo;
                    break;
            }

            // If no type was determined, return null
            if (type == Subject_Info_Type.UNKNOWN)
                return;

            // Was this the standard subject object?
            if (type == Subject_Info_Type.Standard)
            {
                Subject_Info_Standard standardSubject = new Subject_Info_Standard();
                standardSubject.Language = language;
                standardSubject.Authority = authority;
                standardSubject.ID = id;

                do
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        if ((standardSubject.Topics_Count > 0) || (standardSubject.Geographics_Count > 0) || (standardSubject.Genres_Count > 0) ||
                            (standardSubject.Temporals_Count > 0) || (standardSubject.Occupations_Count > 0))
                        {
                            thisBibInfo.Add_Subject(standardSubject);
                        }
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:topic":
                            case "topic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Topic(r.Value);
                                break;

                            case "mods:geographic":
                            case "geographic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Geographic(r.Value);
                                break;

                            case "mods:genre":
                            case "genre":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Genre(r.Value);
                                break;

                            case "mods:temporal":
                            case "temporal":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Temporal(r.Value);
                                break;

                            case "mods:occupation":
                            case "occupation":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Occupation(r.Value);
                                break;
                        }
                    }
                } while (r.Read());
            }

            // Was this the hierarchical geography subject?
            if (type == Subject_Info_Type.Hierarchical_Spatial)
            {
                Subject_Info_HierarchicalGeographic geoSubject = new Subject_Info_HierarchicalGeographic();
                geoSubject.Language = language;
                geoSubject.Authority = authority;
                geoSubject.ID = id;

                while (r.Read())
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        thisBibInfo.Add_Subject(geoSubject);
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:continent":
                            case "continent":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Continent = r.Value;
                                break;

                            case "mods:country":
                            case "country":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Country = r.Value;
                                break;

                            case "mods:province":
                            case "province":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Province = r.Value;
                                break;

                            case "mods:region":
                            case "region":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Region = r.Value;
                                break;

                            case "mods:state":
                            case "state":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.State = r.Value;
                                break;

                            case "mods:territory":
                            case "territory":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Territory = r.Value;
                                break;

                            case "mods:county":
                            case "county":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.County = r.Value;
                                break;

                            case "mods:city":
                            case "city":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.City = r.Value;
                                break;

                            case "mods:citySection":
                            case "citySection":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.CitySection = r.Value;
                                break;

                            case "mods:island":
                            case "island":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Island = r.Value;
                                break;

                            case "mods:area":
                            case "area":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Area = r.Value;
                                break;
                        }
                    }
                }
            }

            // Was this the cartographics subject?
            if (type == Subject_Info_Type.Cartographics)
            {
                Subject_Info_Cartographics mapSubject = new Subject_Info_Cartographics();
                mapSubject.Language = language;
                mapSubject.Authority = authority;
                mapSubject.ID = id;

                while (r.Read())
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        if ((mapSubject.Projection.Length > 0) || (mapSubject.Coordinates.Length > 0) || (mapSubject.Scale.Length > 0))
                        {
                            thisBibInfo.Add_Subject(mapSubject);
                        }
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:coordinates":
                            case "coordinates":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    mapSubject.Coordinates = r.Value;
                                break;

                            case "mods:scale":
                            case "scale":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    mapSubject.Scale = r.Value;
                                break;

                            case "mods:projection":
                            case "projection":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    mapSubject.Projection = r.Value;
                                break;
                        }
                    }
                }
            }

            // Was this the name subject?
            if (type == Subject_Info_Type.Name)
            {
                Subject_Info_Name nameSubject = new Subject_Info_Name();
                nameSubject.Language = language;
                nameSubject.Authority = authority;
                nameSubject.ID = id;

                do
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        thisBibInfo.Add_Subject(nameSubject);
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:name":
                            case "name":
                                Name_Info nameInfo = read_name_object(r);
                                nameSubject.Set_Internal_Name(nameInfo);
                                break;

                            case "mods:topic":
                            case "topic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Topic(r.Value);
                                break;

                            case "mods:geographic":
                            case "geographic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Geographic(r.Value);
                                break;

                            case "mods:genre":
                            case "genre":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Genre(r.Value);
                                break;

                            case "mods:temporal":
                            case "temporal":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Temporal(r.Value);
                                break;
                        }
                    }
                } while (r.Read());
            }

            // Was this the title subject?
            if (type == Subject_Info_Type.TitleInfo)
            {
                Subject_Info_TitleInfo titleSubject = new Subject_Info_TitleInfo();
                titleSubject.Language = language;
                titleSubject.Authority = authority;
                titleSubject.ID = id;

                do
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        thisBibInfo.Add_Subject(titleSubject);
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:titleInfo":
                            case "titleInfo":
                                Title_Info titleInfo = read_title_object(r);
                                titleSubject.Set_Internal_Title(titleInfo);
                                break;

                            case "mods:topic":
                            case "topic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Topic(r.Value);
                                break;

                            case "mods:geographic":
                            case "geographic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Geographic(r.Value);
                                break;

                            case "mods:genre":
                            case "genre":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Genre(r.Value);
                                break;

                            case "mods:temporal":
                            case "temporal":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Temporal(r.Value);
                                break;
                        }
                    }
                } while (r.Read());
            }
        }
        private static void Add_Subject(Bibliographic_Info thisBibInfo, MARC_Record record, int tag, string topical_codes, string geographic_codes, string temporal_codes, string genre_codes, string occupation_codes)
        {
            // Step through all of the subjects under this tag
            int subj_index = 1;
            string source;
            foreach (MARC_Field thisRecord in record[tag])
            {
                // Only continue if there is an id in this record
                if (thisRecord.has_Subfield('a'))
                {
                    // Was there  a source?
                    source = String.Empty;
                    if (thisRecord.has_Subfield('2'))
                    {
                        source = thisRecord['2'];
                    }
                    else if ((tag != 653))
                    {
                        switch (thisRecord.Indicator2)
                        {
                            case '0':
                                source = "lcsh";
                                break;

                            case '1':
                                source = "lcshac";
                                break;

                            case '2':
                                source = "mesh";
                                break;

                            case '3':
                                source = "nal";
                                break;

                            case '5':
                                source = "csh";
                                break;

                            case '6':
                                source = "rvm";
                                break;

                            case '9':
                                source = "local";
                                break;
                        }
                    }

                    Subject_Info_Standard obj = new Subject_Info_Standard();
                    obj.Authority = source;
                    obj.ID = "SUBJ" + tag + "_" + subj_index;
                    subj_index++;

                    // Add the topics
                    foreach (char thisTopicChar in topical_codes)
                    {
                        if (thisRecord.has_Subfield(thisTopicChar))
                        {
                            string topicString = thisRecord[thisTopicChar];
                            if (topicString.IndexOf("|") > 0)
                            {
                                string[] topicStringSplit = topicString.Split("|".ToCharArray());
                                foreach (string thisTopicString in topicStringSplit)
                                    obj.Add_Topic(Remove_Trailing_Punctuation(thisTopicString));
                            }
                            else
                            {
                                obj.Add_Topic(Remove_Trailing_Punctuation(topicString));
                            }
                        }
                    }

                    // Add the temporals
                    foreach (char thisTempChar in temporal_codes)
                    {
                        if (thisRecord.has_Subfield(thisTempChar))
                        {
                            string tempString = thisRecord[thisTempChar];
                            if (tempString.IndexOf("|") > 0)
                            {
                                string[] tempStringSplit = tempString.Split("|".ToCharArray());
                                foreach (string thisTempString in tempStringSplit)
                                    obj.Add_Temporal(Remove_Trailing_Punctuation(thisTempString));
                            }
                            else
                            {
                                obj.Add_Temporal(Remove_Trailing_Punctuation(tempString));
                            }
                        }
                    }

                    // Add the geographics
                    foreach (char thisGeoChar in geographic_codes)
                    {
                        if (thisRecord.has_Subfield(thisGeoChar))
                        {
                            string geoString = thisRecord[thisGeoChar];
                            if (geoString.IndexOf("|") > 0)
                            {
                                string[] geoStringSplit = geoString.Split("|".ToCharArray());
                                foreach (string thisGeoString in geoStringSplit)
                                    obj.Add_Geographic(Remove_Trailing_Punctuation(thisGeoString));
                            }
                            else
                            {
                                obj.Add_Geographic(Remove_Trailing_Punctuation(geoString));
                            }
                        }
                    }

                    // Add the genres
                    foreach (char thisGenreChar in genre_codes)
                    {
                        if (thisRecord.has_Subfield(thisGenreChar))
                        {
                            string genreString = thisRecord[thisGenreChar];
                            if (genreString.IndexOf("|") > 0)
                            {
                                string[] genreStringSplit = genreString.Split("|".ToCharArray());
                                foreach (string thisGenreString in genreStringSplit)
                                    obj.Add_Genre(Remove_Trailing_Punctuation(thisGenreString));
                            }
                            else
                            {
                                obj.Add_Genre(Remove_Trailing_Punctuation(genreString));
                            }
                        }
                    }

                    // Add the occupations
                    foreach (char thisOccChar in occupation_codes)
                    {
                        if (thisRecord.has_Subfield(thisOccChar))
                        {
                            string occString = thisRecord[thisOccChar].Replace("--", "|");
                            if (occString.IndexOf("|") > 0)
                            {
                                string[] occStringSplit = occString.Split("|".ToCharArray());
                                foreach (string thisOccString in occStringSplit)
                                    obj.Add_Occupation(Remove_Trailing_Punctuation(thisOccString.Trim()));
                            }
                            else
                            {
                                obj.Add_Occupation(Remove_Trailing_Punctuation(occString));
                            }
                        }
                    }

                    // Add this subject
                    thisBibInfo.Add_Subject(obj);
                }
            }
        }
        /// <summary> Saves the data rendered by this element to the provided bibliographic object during postback </summary>
        /// <param name="Bib"> Object into which to save the user's data, entered into the html rendered by this element </param>
        public override void Save_To_Bib(SobekCM_Item Bib)
        {
            string[] getKeys = HttpContext.Current.Request.Form.AllKeys;
            foreach (string thisKey in getKeys)
            {
                if (thisKey.IndexOf("formsubjecttype_") == 0)
                {
                    string diff = thisKey.Replace("formsubjecttype_","");
                    string topic1 = HttpContext.Current.Request.Form["formsubjecttopic1_" + diff].Trim();
                    string topic2 = HttpContext.Current.Request.Form["formsubjecttopic2_" + diff].Trim();
                    string topic3 = HttpContext.Current.Request.Form["formsubjecttopic3_" + diff].Trim();
                    string topic4 = HttpContext.Current.Request.Form["formsubjecttopic4_" + diff].Trim();
                    string temporal1 = HttpContext.Current.Request.Form["formsubjecttemporal1_" + diff].Trim();
                    string temporal2 = HttpContext.Current.Request.Form["formsubjecttemporal2_" + diff].Trim();
                    string geographic1 = HttpContext.Current.Request.Form["formsubjectgeo1_" + diff].Trim();
                    string geographic2 = HttpContext.Current.Request.Form["formsubjectgeo2_" + diff].Trim();
                    string genre1 = HttpContext.Current.Request.Form["formsubjectgenre1_" + diff].Trim();
                    string genre2 = HttpContext.Current.Request.Form["formsubjectgenre2_" + diff].Trim();
                    string occcupation = HttpContext.Current.Request.Form["formsubjectoccup1_" + diff].Trim();
                    string authority = HttpContext.Current.Request.Form["formsubjectauthority_" + diff].Trim();
                    string language = HttpContext.Current.Request.Form["formsubjectlanguage_" + diff].Trim();
                    string marc = HttpContext.Current.Request.Form["formsubjectmap_" + diff].Trim();

                    if ((topic1.Length > 0) || (topic2.Length > 0) || (topic3.Length > 0) || (topic4.Length > 0) ||
                        (temporal1.Length > 0) || (temporal2.Length > 0) || (geographic1.Length > 0) || (geographic2.Length > 0) ||
                        (genre1.Length > 0) || (genre2.Length > 0) || (occcupation.Length > 0))
                    {
                        Subject_Info_Standard newSubject = new Subject_Info_Standard();
                        if (topic1.Length > 0) newSubject.Add_Topic(topic1);
                        if (topic2.Length > 0) newSubject.Add_Topic(topic2);
                        if (topic3.Length > 0) newSubject.Add_Topic(topic3);
                        if (topic4.Length > 0) newSubject.Add_Topic(topic4);
                        if (temporal1.Length > 0) newSubject.Add_Temporal(temporal1);
                        if (temporal2.Length > 0) newSubject.Add_Temporal(temporal2);
                        if (geographic1.Length > 0) newSubject.Add_Geographic(geographic1);
                        if (geographic2.Length > 0) newSubject.Add_Geographic(geographic2);
                        if (genre1.Length > 0) newSubject.Add_Genre(genre1);
                        if (genre2.Length > 0) newSubject.Add_Genre(genre2);
                        if (occcupation.Length > 0) newSubject.Add_Occupation(occcupation);
                        newSubject.Authority = authority;
                        newSubject.Language = language;
                        if ((marc.Length > 0) && (marc != "none"))
                        {
                            newSubject.ID = "SUBJ" + marc + "_" + diff;
                        }
                        Bib.Bib_Info.Add_Subject(newSubject);

                    }
                }
            }
        }