/// <summary> Adds a new citation element to the end of the current elements in this field set </summary>
        /// <param name="NewElement"> New citation element to add </param>
        /// <remarks> If an element exists with the same MetadataTerm, it is removed first. </remarks>
        public void Append_Element(CitationElement NewElement)
        {
            // Ensure the dictionary is built (i.e., not null)
            if (elementsDictionary == null)
            {
                elementsDictionary = new Dictionary <string, CitationElement>(StringComparer.OrdinalIgnoreCase);
            }

            // Check that the count in the dictionary seems right
            if (elementsDictionary.Count != Elements.Count)
            {
                foreach (CitationElement thisElement in Elements)
                {
                    elementsDictionary[thisElement.MetadataTerm] = thisElement;
                }
            }

            // If this element already exists, remove it
            if (elementsDictionary.ContainsKey(NewElement.MetadataTerm))
            {
                CitationElement existing = elementsDictionary[NewElement.MetadataTerm];
                Elements.Remove(existing);
            }

            // Append the new one
            Elements.Add(NewElement);
            elementsDictionary[NewElement.MetadataTerm] = NewElement;
        }
        /// <summary> Removes a single citation element from this field set, if it exists </summary>
        /// <param name="MetadataTerm"> Unique identifier for the citation element to remove </param>
        public void Remove_Element(string MetadataTerm)
        {
            // Ensure the dictionary is built (i.e., not null)
            if (elementsDictionary == null)
            {
                elementsDictionary = new Dictionary <string, CitationElement>(StringComparer.OrdinalIgnoreCase);
            }

            // Check that the count in the dictionary seems right
            if (elementsDictionary.Count != Elements.Count)
            {
                foreach (CitationElement thisElement in Elements)
                {
                    elementsDictionary[thisElement.MetadataTerm] = thisElement;
                }
            }

            // If this doesn't exist, do nothin
            if (!elementsDictionary.ContainsKey(MetadataTerm))
            {
                return;
            }

            // Find the match from the dictionary first
            CitationElement match = elementsDictionary[MetadataTerm];

            Elements.Remove(match);
            elementsDictionary.Remove(MetadataTerm);
        }
        /// <summary> Adds a new citation element before an existing elements in this field set </summary>
        /// <param name="NewElement"> New citation element to add </param>
        /// <param name="RelativeElementID"> MetadataTerm for the element before which the new citation element should be inserted </param>
        /// <remarks> If an element exists with the same MetadataTerm, it is removed first. If the ID provided
        /// to add this element after does not exist, this is just appended to the very end. </remarks>
        public void Insert_Element_Before(CitationElement NewElement, string RelativeElementID)
        {
            // Ensure the dictionary is built (i.e., not null)
            if (elementsDictionary == null)
            {
                elementsDictionary = new Dictionary <string, CitationElement>(StringComparer.OrdinalIgnoreCase);
            }

            // Check that the count in the dictionary seems right
            if (elementsDictionary.Count != Elements.Count)
            {
                foreach (CitationElement thisElement in Elements)
                {
                    elementsDictionary[thisElement.MetadataTerm] = thisElement;
                }
            }

            // Does the relative element id exist?
            if (!elementsDictionary.ContainsKey(RelativeElementID))
            {
                // Relative doesn't exist.. just append
                Append_Element(NewElement);
            }

            // Find the index of the relative element
            int relativeIndex = Elements.IndexOf(elementsDictionary[RelativeElementID]);

            if (relativeIndex < 0)
            {
                Append_Element(NewElement);
            }
            else
            {
                // If this element already exists, remove it
                if (elementsDictionary.ContainsKey(NewElement.MetadataTerm))
                {
                    CitationElement existing = elementsDictionary[NewElement.MetadataTerm];
                    Elements.Remove(existing);
                }

                // Insert at the right spot
                Elements.Insert(relativeIndex, NewElement);
                elementsDictionary[NewElement.MetadataTerm] = NewElement;
            }
        }
        /// <summary> Wites a section of citation from a provided digital resource </summary>
        /// <param name="ElementInfo"> Additional possible data about this citation element </param>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Item"> Digital resource with all the data to write </param>
        /// <param name="LeftColumnWidth"> Number of pixels of the left column, or the definition terms </param>
        /// <param name="SearchLink"> Beginning of the search link that can be used to allow the web patron to select a term and run a search against this instance </param>
        /// <param name="SearchLinkEnd"> End of the search link that can be used to allow the web patron to select a term and run a search against this instance  </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public void Write_Citation_Section(CitationElement ElementInfo, StringBuilder Output, BriefItemInfo Item, int LeftColumnWidth, string SearchLink, string SearchLinkEnd, Custom_Tracer Tracer)
        {
            BriefItem_DescriptiveTerm creatorList = Item.Get_Description("Creator");

            bool first_creator = true;

            string displayLabel = (String.IsNullOrEmpty(ElementInfo.DisplayTerm)) ? "Creators" : ElementInfo.DisplayTerm;

            Output.AppendLine("        <dt class=\"sbk_CivCREATOR_Element\" style=\"width:" + LeftColumnWidth + "px;\" >" + displayLabel + ": </dt>");
            Output.Append("        <dd class=\"sbk_CivCREATOR_Element\" style=\"margin-left:" + LeftColumnWidth + "px;\" >");

            // Determine if ths standard itemprop was overriden
            string itemProp = (!String.IsNullOrWhiteSpace(ElementInfo.ItemProp)) ? ElementInfo.ItemProp : "creator";

            // Determine if the standard search code was overriden
            string searchCode = (!String.IsNullOrWhiteSpace(ElementInfo.SearchCode)) ? ElementInfo.SearchCode : "AU";

            foreach (BriefItem_DescTermValue thisValue in creatorList.Values)
            {
                // Was this the first?
                if (first_creator) first_creator = false;
                else Output.AppendLine("<br />");

                // It is possible a different search term is valid for this item, so check it
                string searchTerm = (!String.IsNullOrWhiteSpace(thisValue.SearchTerm)) ? thisValue.SearchTerm : thisValue.Value;

                Output.Append("<span itemprop=\"" + itemProp + "\">" + SearchLink.Replace("<%VALUE%>", search_link_from_value(searchTerm)).Replace("<%CODE%>", searchCode) + display_text_from_value(thisValue.Value) + SearchLinkEnd);

                if (!String.IsNullOrEmpty(thisValue.Authority))
                {
                    Output.Append(" ( " + display_text_from_value(thisValue.Authority) + " ) ");
                }

                if (!String.IsNullOrEmpty(thisValue.SubTerm))
                {
                    Output.Append(" ( <i>" + display_text_from_value(thisValue.SubTerm) + "</i> ) ");
                }

                Output.AppendLine("</span>");
            }
        }
        /// <summary> Wites a section of citation from a provided digital resource </summary>
        /// <param name="ElementInfo"> Additional possible data about this citation element </param>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Item"> Digital resource with all the data to write </param>
        /// <param name="LeftColumnWidth"> Number of pixels of the left column, or the definition terms </param>
        /// <param name="SearchLink"> Beginning of the search link that can be used to allow the web patron to select a term and run a search against this instance </param>
        /// <param name="SearchLinkEnd"> End of the search link that can be used to allow the web patron to select a term and run a search against this instance  </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public void Write_Citation_Section(CitationElement ElementInfo, StringBuilder Output, BriefItemInfo Item, int LeftColumnWidth, string SearchLink, string SearchLinkEnd, Custom_Tracer Tracer)
        {
            string displayLabel = (String.IsNullOrEmpty(ElementInfo.DisplayTerm)) ? "Spatial Coverage" : ElementInfo.DisplayTerm;

            Output.AppendLine("        <dt class=\"sbk_CivSPATIAL_COVERAGE_Element\" style=\"width:" + LeftColumnWidth + "px;\" >" + displayLabel + ": </dt>");
            Output.Append("        <dd class=\"sbk_CivSPATIAL_COVERAGE_Element\" style=\"margin-left:" + LeftColumnWidth + "px;\">");

            int spatial_count = 1;
            while (true)
            {
                // Determine the term to use
                string term = "Hierarchical Spatial";
                if (spatial_count > 1)
                    term = term + " (" + spatial_count + ")";

                // Look for the match
                BriefItem_DescriptiveTerm thisSpatial = Item.Get_Description(term);

                // If no match, break out of this while loop
                if ((thisSpatial == null) || (thisSpatial.Values == null))
                    break;

                // Past the first complex spatial subject?
                if ( spatial_count > 1 )
                    Output.AppendLine("<br />");

                // Step through each subterm
                StringBuilder spatial_builder = new StringBuilder();
                foreach (BriefItem_DescTermValue thisValue in thisSpatial.Values)
                {
                    if (spatial_builder.Length > 0) spatial_builder.Append(" -- ");

                    switch (thisValue.SubTerm)
                    {
                        case "Continent":
                        case "Province":
                        case "Region":
                        case "Territory":
                        case "City Section":
                        case "Island":
                        case "Area":
                            spatial_builder.Append(thisValue.Value);
                            break;

                        case "Country":
                            spatial_builder.Append(SearchLink.Replace("<%VALUE%>", HttpUtility.HtmlEncode(thisValue.Value.Replace("&amp;", "&").Replace("&", "").Replace("  ", " ")).Replace(",", "").Replace("&amp;", "&").Replace("&", "").Replace(" ", "+")).Replace("<%CODE%>", "CO") + thisValue.Value + SearchLinkEnd);
                            break;

                        case "State":
                            spatial_builder.Append(SearchLink.Replace("<%VALUE%>", HttpUtility.HtmlEncode(thisValue.Value.Replace("&amp;", "&").Replace("&", "").Replace("  ", " ")).Replace(",", "").Replace("&amp;", "&").Replace("&", "").Replace(" ", "+")).Replace("<%CODE%>", "ST") + thisValue.Value + SearchLinkEnd);
                            break;

                        case "County":
                            spatial_builder.Append(SearchLink.Replace("<%VALUE%>", HttpUtility.HtmlEncode(thisValue.Value.Replace("&amp;", "&").Replace("&", "").Replace("  ", " ")).Replace(",", "").Replace("&amp;", "&").Replace("&", "").Replace(" ", "+")).Replace("<%CODE%>", "CT") + thisValue.Value + SearchLinkEnd);
                            break;

                        case "City":
                            spatial_builder.Append(SearchLink.Replace("<%VALUE%>", HttpUtility.HtmlEncode(thisValue.Value.Replace("&amp;", "&").Replace("&", "").Replace("  ", " ")).Replace(",", "").Replace("&amp;", "&").Replace("&", "").Replace(" ", "+")).Replace("<%CODE%>", "CI") + thisValue.Value + SearchLinkEnd);
                            break;
                    }
                }

                // Display this
                Output.Append("          " + spatial_builder);

                // Move to check the next spatial
                spatial_count++;
            }

            Output.AppendLine("</dd>");
            Output.AppendLine();
        }
 /// <summary> Returns flag that indicates this citation section writer 
 /// will be writing alues to the output stream </summary>
 /// <param name="Item"> Digital resource to analyze for data to write </param>
 /// <param name="ElementInfo"> Additional possible data about this citation element </param>
 public bool Has_Data_To_Write(CitationElement ElementInfo, BriefItemInfo Item)
 {
     // Look for a match in the item description
     BriefItem_DescriptiveTerm firstSpatial = Item.Get_Description("Hierarchical Spatial");
     return ((firstSpatial != null) && (firstSpatial.Values.Count > 0));
 }
 /// <summary> Returns flag that indicates this citation section writer 
 /// will be writing alues to the output stream </summary>
 /// <param name="ElementInfo"> Additional possible data about this citation element </param>
 /// <param name="Item"> Digital resource to analyze for data to write </param>
 public bool Has_Data_To_Write(CitationElement ElementInfo, BriefItemInfo Item)
 {
     // Look for a match in the item description
     BriefItem_DescriptiveTerm firstCreator = Item.Get_Description("Creator");
     return ((firstCreator != null) && (firstCreator.Values.Count > 0));
 }
 /// <summary> Wites a section of citation from a provided digital resource </summary>
 /// <param name="ElementInfo"> Additional possible data about this citation element </param>
 /// <param name="Output"> Response stream for the item viewer to write directly to </param>
 /// <param name="Item"> Digital resource with all the data to write </param>
 /// <param name="LeftColumnWidth"> Number of pixels of the left column, or the definition terms </param>
 /// <param name="SearchLink"> Beginning of the search link that can be used to allow the web patron to select a term and run a search against this instance </param>
 /// <param name="SearchLinkEnd"> End of the search link that can be used to allow the web patron to select a term and run a search against this instance  </param>
 /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
 public void Write_Citation_Section(CitationElement ElementInfo, StringBuilder Output, BriefItemInfo Item, int LeftColumnWidth, string SearchLink, string SearchLinkEnd, Custom_Tracer Tracer)
 {
     // This should never get called currently
     throw new NotImplementedException();
 }
 /// <summary> Returns flag that indicates this citation section writer 
 /// will be writing alues to the output stream </summary>
 /// <param name="ElementInfo"> Additional possible data about this citation element </param>
 /// <param name="Item"> Digital resource to analyze for data to write </param>
 public bool Has_Data_To_Write(CitationElement ElementInfo, BriefItemInfo Item)
 {
     return false;
 }
        private static void read_citation_set_details(XmlReader ReaderXml, CitationSet Config)
        {
            CitationFieldSet currFieldSet = null;
            CitationElement currElement = null;

            while (ReaderXml.Read())
            {
                if (ReaderXml.NodeType == XmlNodeType.Element)
                {
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "fieldset":
                            if (ReaderXml.MoveToAttribute("ID"))
                            {
                                // Pull the attributes, basic info about this field set
                                string fieldSetId = ReaderXml.Value.Trim();
                                string defaultHeading = null;
                                string order = "append";
                                string afterid = "";
                                if (ReaderXml.MoveToAttribute("Heading"))
                                    defaultHeading = ReaderXml.Value.Trim();

                                // Does this field set already exist? ( in which case order and after id don't matter )
                                if (ReaderXml.MoveToAttribute("Order"))
                                    order = ReaderXml.Value.Trim().ToLower();
                                if (ReaderXml.MoveToAttribute("AfterID"))
                                    afterid = ReaderXml.Value.Trim();

                                // Ensure the order is one of the terms supported
                                if ((order != "first") && (order != "after") && (order != "append"))
                                    order = "append";

                                // Add this field set
                                currFieldSet = Config.AddFieldSet(fieldSetId, defaultHeading, order, afterid);
                            }
                            else
                            {
                                currFieldSet = null;
                            }
                            break;

                        case "language":
                            // Get the language code and term
                            string code = String.Empty;
                            if (ReaderXml.MoveToAttribute("Code"))
                                code = ReaderXml.Value.Trim().ToLower();
                            ReaderXml.Read();
                            string term = ReaderXml.Value.Trim();

                            // WHich level is this form?
                            if (!String.IsNullOrEmpty(code))
                            {
                                if (currElement != null)
                                {
                                    currElement.Add_Translation(Web_Language_Enum_Converter.Code_To_Enum(code), term);
                                }
                                else if (currFieldSet != null)
                                {
                                    currFieldSet.Add_Translation(Web_Language_Enum_Converter.Code_To_Enum(code), term);
                                }
                            }
                            break;

                        case "clear":
                            if ( currFieldSet != null )
                                currFieldSet.Clear_Elements();
                            break;

                        case "append":
                            // Collect the basic values
                            string appendMetadataTerm = (ReaderXml.MoveToAttribute("MetadataTerm")) ? ReaderXml.Value.Trim() : String.Empty;
                            string appendDisplayTerm = (ReaderXml.MoveToAttribute("DisplayTerm")) ? ReaderXml.Value.Trim() : appendMetadataTerm;
                            string appendItemProp = (ReaderXml.MoveToAttribute("ItemProp")) ? ReaderXml.Value.Trim() : null;
                            string appendSearchCode = (ReaderXml.MoveToAttribute("SearchCode")) ? ReaderXml.Value.Trim() : null;
                            currElement = new CitationElement
                            {
                                MetadataTerm = appendMetadataTerm,
                                DisplayTerm = appendDisplayTerm,
                                ItemProp = appendItemProp,
                                SearchCode = appendSearchCode
                            };

                            // Set the override display enumeration
                            string appendOverrideDisplay = (ReaderXml.MoveToAttribute("OverrideDisplayTerm")) ? ReaderXml.Value.Trim() : String.Empty;
                            switch (appendOverrideDisplay.ToLower())
                            {
                                case "subterm":
                                    currElement.OverrideDisplayTerm = CitationElement_OverrideDispayTerm_Enum.subterm;
                                    currElement.IndividualFields = true;
                                    break;

                                default:
                                    currElement.OverrideDisplayTerm = CitationElement_OverrideDispayTerm_Enum.NONE;
                                    break;
                            }

                            // Only actually add it if the metadata term is valid
                            if ((!String.IsNullOrEmpty(appendMetadataTerm)) && (currFieldSet != null))
                                currFieldSet.Append_Element(currElement);
                            break;

                        case "insert":
                            // Collect the basic values
                            string insertMetadataTerm = (ReaderXml.MoveToAttribute("MetadataTerm")) ? ReaderXml.Value.Trim() : String.Empty;
                            string insertDisplayTerm = (ReaderXml.MoveToAttribute("DisplayTerm")) ? ReaderXml.Value.Trim() : insertMetadataTerm;
                            string insertItemProp = (ReaderXml.MoveToAttribute("ItemProp")) ? ReaderXml.Value.Trim() : null;
                            string insertSearchCode = (ReaderXml.MoveToAttribute("SearchCode")) ? ReaderXml.Value.Trim() : null;
                            currElement = new CitationElement
                            {
                                MetadataTerm = insertMetadataTerm,
                                DisplayTerm = insertDisplayTerm,
                                ItemProp = insertItemProp,
                                SearchCode = insertSearchCode
                            };

                            // Set the override display enumeration
                            string insertOverrideDisplay = (ReaderXml.MoveToAttribute("OverrideDisplayTerm")) ? ReaderXml.Value.Trim() : String.Empty;
                            switch (insertOverrideDisplay.ToLower())
                            {
                                case "subterm":
                                    currElement.OverrideDisplayTerm = CitationElement_OverrideDispayTerm_Enum.subterm;
                                    currElement.IndividualFields = true;
                                    break;

                                default:
                                    currElement.OverrideDisplayTerm = CitationElement_OverrideDispayTerm_Enum.NONE;
                                    break;
                            }

                            // Only actually add it if the metadata term is valid
                            if ((!String.IsNullOrEmpty(insertMetadataTerm)) && (currFieldSet != null))
                            {
                                if (ReaderXml.MoveToAttribute("After"))
                                {
                                    currFieldSet.Insert_Element_After(currElement, ReaderXml.Value.Trim());
                                }
                                else if (ReaderXml.MoveToAttribute("Before"))
                                {
                                    currFieldSet.Insert_Element_Before(currElement, ReaderXml.Value.Trim());
                                }
                                else
                                {
                                    currFieldSet.Append_Element(currElement);
                                }
                            }
                            break;

                        case "remove":
                            if (( currFieldSet != null ) && ( ReaderXml.MoveToAttribute("Code")))
                                currFieldSet.Remove_Element(ReaderXml.Value.Trim());
                            currElement = null;
                            break;

                        case "sectionwriter":
                            if (currElement != null)
                            {
                                string assembly = (ReaderXml.MoveToAttribute("assembly")) ? ReaderXml.Value.Trim() : null;
                                string writer_class = (ReaderXml.MoveToAttribute("class")) ? ReaderXml.Value.Trim() : null;
                                if (!String.IsNullOrEmpty(writer_class))
                                {
                                    currElement.SectionWriter = new SectionWriter(assembly, writer_class);
                                }
                            }
                            break;

                    }
                }
                else if (ReaderXml.NodeType == XmlNodeType.EndElement)
                {
                    // This is closing out a field set or a single element
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "fieldset":
                            currFieldSet = null;
                            currElement = null;
                            break;

                        case "append":
                        case "insert":
                        case "remove":
                            currElement = null;
                            break;
                    }
                }
            }
        }
        /// <summary> Wites a section of citation from a provided digital resource </summary>
        /// <param name="ElementInfo"> Additional possible data about this citation element </param>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Item"> Digital resource with all the data to write </param>
        /// <param name="LeftColumnWidth"> Number of pixels of the left column, or the definition terms </param>
        /// <param name="SearchLink"> Beginning of the search link that can be used to allow the web patron to select a term and run a search against this instance </param>
        /// <param name="SearchLinkEnd"> End of the search link that can be used to allow the web patron to select a term and run a search against this instance  </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public void Write_Citation_Section(CitationElement ElementInfo, StringBuilder Output, BriefItemInfo Item, int LeftColumnWidth, string SearchLink, string SearchLinkEnd, Custom_Tracer Tracer)
        {
            bool first_coordinate = true;

            string displayLabel = ( String.IsNullOrEmpty(ElementInfo.DisplayTerm )) ? "Coordinates" : ElementInfo.DisplayTerm;

            Output.AppendLine("        <dt class=\"sbk_CivCOORDINATES_Element\" style=\"width:" + LeftColumnWidth + "px;\" >" + displayLabel + ": </dt>");
            Output.Append("        <dd class=\"sbk_CivCOORDINATES_Element\" style=\"margin-left:" + LeftColumnWidth + "px;\" >");

            // Add the points first
            if (Item.GeoSpatial.Point_Count > 0)
            {
                for (int i = 0; i < Item.GeoSpatial.Point_Count; i++)
                {
                    // Was this the first?
                    if ( first_coordinate ) first_coordinate = false;
                    else Output.AppendLine("<br />");

                    // Add this coordiante
                    if (Item.GeoSpatial.Points[i].Label.Length > 0)
                    {
                        Output.Append("          <span itemprop=\"geo\" itemscope itemtype=\"http://schema.org/GeoCoordinates\"><span itemprop=\"latitude\">" + Item.GeoSpatial.Points[i].Latitude + "</span> x <span itemprop=\"longitude\">" + Item.GeoSpatial.Points[i].Longitude + "</span> ( <span itemprop=\"name\">" + HttpUtility.HtmlEncode(Item.GeoSpatial.Points[i].Label) + "</span> )</span>");
                    }
                    else
                    {
                        Output.Append("          <span itemprop=\"geo\" itemscope itemtype=\"http://schema.org/GeoCoordinates\"><span itemprop=\"latitude\">" + Item.GeoSpatial.Points[i].Latitude + "</span> x <span itemprop=\"longitude\">" + Item.GeoSpatial.Points[i].Longitude + "</span></span>");
                    }
                }
            }

            // If there is a single polygon ,add it
            if (Item.GeoSpatial.Polygon_Count == 1)
            {
                // If not the first, add
                for (int i = 0; i < Item.GeoSpatial.Polygon_Count; i++)
                {
                    // Was this the first?
                    if (first_coordinate) first_coordinate = false;
                    else Output.AppendLine("<br />");

                    // Get the polygon and draw it
                    BriefItem_Coordinate_Polygon polygon = Item.GeoSpatial.Polygons[i];
                    StringBuilder polygonBuilder = new StringBuilder();
                    foreach (BriefItem_Coordinate_Point thisPoint in polygon.Edge_Points)
                    {
                        if (polygonBuilder.Length > 0)
                        {
                            polygonBuilder.Append(", " + thisPoint.Latitude + " x " + thisPoint.Longitude);
                        }
                        else
                        {
                            polygonBuilder.Append(thisPoint.Latitude + " x " + thisPoint.Longitude);
                        }
                    }

                    if (polygon.Label.Length > 0)
                    {
                        polygonBuilder.Append(" ( " + HttpUtility.HtmlEncode(polygon.Label) + " )");
                    }
                    if (polygonBuilder.ToString().Trim().Length > 0)
                    {
                        Output.Append("          " + polygonBuilder);
                    }
                }
            }

            Output.AppendLine("</dd>");
            Output.AppendLine();
        }
 /// <summary> Returns flag that indicates this citation section writer 
 /// will be writing alues to the output stream </summary>
 /// <param name="ElementInfo"> Additional possible data about this citation element </param>
 /// <param name="Item"> Digital resource to analyze for data to write </param>
 public bool Has_Data_To_Write(CitationElement ElementInfo, BriefItemInfo Item)
 {
     return ((Item.GeoSpatial != null) && ((Item.GeoSpatial.Point_Count > 0) || (Item.GeoSpatial.Polygon_Count > 0)));
 }
        /// <summary> Wites a section of citation from a provided digital resource </summary>
        /// <param name="ElementInfo"> Additional possible data about this citation element </param>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Item"> Digital resource with all the data to write </param>
        /// <param name="LeftColumnWidth"> Number of pixels of the left column, or the definition terms </param>
        /// <param name="SearchLink"> Beginning of the search link that can be used to allow the web patron to select a term and run a search against this instance </param>
        /// <param name="SearchLinkEnd"> End of the search link that can be used to allow the web patron to select a term and run a search against this instance  </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public void Write_Citation_Section(CitationElement ElementInfo, StringBuilder Output, BriefItemInfo Item, int LeftColumnWidth, string SearchLink, string SearchLinkEnd, Custom_Tracer Tracer)
        {
            // Set the default (since this always displays)
            string rights_statement = "All applicable rights reserved by the source institution and holding location.";
            string rights_image = String.Empty;
            string uri = String.Empty;

            const string SEE_TEXT = "See License Deed";

            // Look for a match in the item description
            BriefItem_DescriptiveTerm rightsTerm = Item.Get_Description("Rights Management");

            if ((rightsTerm != null) && (rightsTerm.Values.Count > 0))
            {
                rights_statement = rightsTerm.Values[0].Value;

                if ((rightsTerm.Values[0].URIs != null) && (rightsTerm.Values[0].URIs.Count == 1))
                {
                    uri = rightsTerm.Values[0].URIs[0];

                    switch (uri)
                    {
                        case "http://creativecommons.org/licenses/by-nc-nd/3.0/":
                            rights_image = UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Cc_By_Nc_Nd_Img;
                            break;

                        case "http://creativecommons.org/licenses/by-nc-sa/3.0/":
                            rights_image = UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Cc_By_Nc_Sa_Img;
                            break;

                        case "http://creativecommons.org/licenses/by-nc/3.0/":
                            rights_image = UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Cc_By_Nc_Img;
                            break;

                        case "http://creativecommons.org/licenses/by-nd/3.0/":
                            rights_image = UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Cc_By_Nd_Img;
                            break;

                        case "http://creativecommons.org/licenses/by-sa/3.0/":
                            rights_image = UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Cc_By_Sa_Img;
                            break;

                        case "http://creativecommons.org/licenses/by/3.0/":
                            rights_image = UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Cc_By_Img;
                            break;

                        case "http://creativecommons.org/publicdomain/zero/1.0/":
                            rights_image = UI_ApplicationCache_Gateway.Configuration.UI.StaticResources.Cc_Zero_Img;
                            break;
                    }
                }
            }

            string displayLabel = (String.IsNullOrEmpty(ElementInfo.DisplayTerm)) ? "Rights Management" : ElementInfo.DisplayTerm;

            Output.AppendLine("        <dt class=\"sbk_CivRIGHTS_Element\" style=\"width:" + LeftColumnWidth + "px;\" >" + displayLabel + ": </dt>");
            Output.Append("        <dd class=\"sbk_CivRIGHTS_Element\" style=\"margin-left:" + LeftColumnWidth + "px;\"><span itemprop=\"rights\">");

            if ((rights_statement.IndexOf("http://") == 0) || (rights_statement.IndexOf("https://") == 0))
            {
                Output.Append("<a href=\"" + rights_statement + "\" target=\"RIGHTS\" >" + rights_statement + "</a>");
            }
            else
            {
                // Show the rights image?
                if (String.IsNullOrEmpty(rights_image))
                {
                    if (!String.IsNullOrEmpty(uri))
                    {
                        Output.Append(rights_statement + " ( <a href=\"" + uri + "\" alt=\"" + SEE_TEXT + "\" target=\"license\">link</a> )");
                    }
                    else
                    {
                        Output.Append(rights_statement);
                    }
                }
                else
                {
                    // Since the image is derived from the URI, there must be a URI here
                    Output.Append("<a href=\"" + uri + "\" alt=\"" + SEE_TEXT + "\" target=\"cc_license\"><img src=\"" + rights_image + "\" /></a> " + rights_statement);
                }
            }

            Output.AppendLine("</span></dd>");
            Output.AppendLine();
        }
 /// <summary> Returns flag that indicates this citation section writer 
 /// will be writing alues to the output stream </summary>
 /// <param name="ElementInfo"> Additional possible data about this citation element </param>
 /// <param name="Item"> Digital resource to analyze for data to write </param>
 public bool Has_Data_To_Write(CitationElement ElementInfo, BriefItemInfo Item)
 {
     // Always show SOME rights
     return true;
 }
        /// <summary> Adds a new citation element to the end of the current elements in this field set </summary>
        /// <param name="NewElement"> New citation element to add </param>
        /// <remarks> If an element exists with the same MetadataTerm, it is removed first. </remarks>
        public void Append_Element(CitationElement NewElement)
        {
            // Ensure the dictionary is built (i.e., not null)
            if (elementsDictionary == null) elementsDictionary = new Dictionary<string, CitationElement>(StringComparer.OrdinalIgnoreCase);

            // Check that the count in the dictionary seems right
            if (elementsDictionary.Count != Elements.Count)
            {
                foreach (CitationElement thisElement in Elements)
                    elementsDictionary[thisElement.MetadataTerm] = thisElement;
            }

            // If this element already exists, remove it
            if (elementsDictionary.ContainsKey(NewElement.MetadataTerm))
            {
                CitationElement existing = elementsDictionary[NewElement.MetadataTerm];
                Elements.Remove(existing);
            }

            // Append the new one
            Elements.Add(NewElement);
            elementsDictionary[NewElement.MetadataTerm] = NewElement;
        }
        /// <summary> Adds a new citation element before an existing elements in this field set </summary>
        /// <param name="NewElement"> New citation element to add </param>
        /// <param name="RelativeElementID"> MetadataTerm for the element before which the new citation element should be inserted </param>
        /// <remarks> If an element exists with the same MetadataTerm, it is removed first. If the ID provided
        /// to add this element after does not exist, this is just appended to the very end. </remarks>
        public void Insert_Element_Before(CitationElement NewElement, string RelativeElementID)
        {
            // Ensure the dictionary is built (i.e., not null)
            if (elementsDictionary == null) elementsDictionary = new Dictionary<string, CitationElement>(StringComparer.OrdinalIgnoreCase);

            // Check that the count in the dictionary seems right
            if (elementsDictionary.Count != Elements.Count)
            {
                foreach (CitationElement thisElement in Elements)
                    elementsDictionary[thisElement.MetadataTerm] = thisElement;
            }

            // Does the relative element id exist?
            if (!elementsDictionary.ContainsKey(RelativeElementID))
            {
                // Relative doesn't exist.. just append
                Append_Element(NewElement);
            }

            // Find the index of the relative element
            int relativeIndex = Elements.IndexOf(elementsDictionary[RelativeElementID]);
            if (relativeIndex < 0)
                Append_Element(NewElement);
            else
            {
                // If this element already exists, remove it
                if (elementsDictionary.ContainsKey(NewElement.MetadataTerm))
                {
                    CitationElement existing = elementsDictionary[NewElement.MetadataTerm];
                    Elements.Remove(existing);
                }

                // Insert at the right spot
                Elements.Insert(relativeIndex, NewElement);
                elementsDictionary[NewElement.MetadataTerm] = NewElement;
            }
        }