/**
         * Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
         *
         * @return  <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
         * @throws  DocumentException when a document isn't open yet, or has been closed
         */

        public override bool Add(IElement element)
        {
            if (pause)
            {
                return(false);
            }
            if (open && !element.IsContent())
            {
                throw new DocumentException("The document is open; you can only add Elements with content.");
            }
            switch (element.Type)
            {
            case Element.HEADER:
                try {
                    Header h = (Header)element;
                    if (HtmlTags.STYLESHEET.Equals(h.Name))
                    {
                        WriteLink(h);
                    }
                    else if (HtmlTags.JAVASCRIPT.Equals(h.Name))
                    {
                        WriteJavaScript(h);
                    }
                    else
                    {
                        WriteHeader(h);
                    }
                }
                catch (InvalidCastException) {
                }
                return(true);

            case Element.SUBJECT:
            case Element.KEYWORDS:
            case Element.AUTHOR:
                Meta meta = (Meta)element;
                WriteHeader(meta);
                return(true);

            case Element.TITLE:
                AddTabs(2);
                WriteStart(HtmlTags.TITLE);
                os.WriteByte(GT);
                AddTabs(3);
                Write(HtmlEncoder.Encode(((Meta)element).Content));
                AddTabs(2);
                WriteEnd(HtmlTags.TITLE);
                return(true);

            case Element.CREATOR:
                WriteComment("Creator: " + HtmlEncoder.Encode(((Meta)element).Content));
                return(true);

            case Element.PRODUCER:
                WriteComment("Producer: " + HtmlEncoder.Encode(((Meta)element).Content));
                return(true);

            case Element.CREATIONDATE:
                WriteComment("Creationdate: " + HtmlEncoder.Encode(((Meta)element).Content));
                return(true);

            case Element.MARKED:
                if (element is MarkedSection)
                {
                    MarkedSection ms = (MarkedSection)element;
                    AddTabs(1);
                    WriteStart(HtmlTags.DIV);
                    WriteMarkupAttributes(ms.MarkupAttributes);
                    os.WriteByte(GT);
                    MarkedObject mo = ((MarkedSection)element).Title;
                    if (mo != null)
                    {
                        markup = mo.MarkupAttributes;
                        mo.Process(this);
                    }
                    ms.Process(this);
                    WriteEnd(HtmlTags.DIV);
                    return(true);
                }
                else
                {
                    MarkedObject mo = (MarkedObject)element;
                    markup = mo.MarkupAttributes;
                    return(mo.Process(this));
                }

            default:
                Write(element, 2);
                return(true);
            }
        }
        /**
         * Writes the HTML representation of an element.
         *
         * @param   element     the element
         * @param   indent      the indentation
         */

        protected void Write(IElement element, int indent)
        {
            Properties styleAttributes = null;

            switch (element.Type)
            {
            case Element.MARKED: {
                try {
                    Add(element);
                } catch (DocumentException) {
                }
                return;
            }

            case Element.CHUNK: {
                Chunk chunk = (Chunk)element;
                // if the chunk contains an image, return the image representation
                Image image = chunk.GetImage();
                if (image != null)
                {
                    Write(image, indent);
                    return;
                }

                if (chunk.IsEmpty())
                {
                    return;
                }
                Hashtable attributes = chunk.Attributes;
                if (attributes != null && attributes[Chunk.NEWPAGE] != null)
                {
                    return;
                }
                bool tag = IsOtherFont(chunk.Font) || markup.Count > 0;
                if (tag)
                {
                    // start span tag
                    AddTabs(indent);
                    WriteStart(HtmlTags.SPAN);
                    if (IsOtherFont(chunk.Font))
                    {
                        Write(chunk.Font, null);
                    }
                    WriteMarkupAttributes(markup);
                    os.WriteByte(GT);
                }
                if (attributes != null && attributes[Chunk.SUBSUPSCRIPT] != null)
                {
                    // start sup or sub tag
                    if ((float)attributes[Chunk.SUBSUPSCRIPT] > 0)
                    {
                        WriteStart(HtmlTags.SUP);
                    }
                    else
                    {
                        WriteStart(HtmlTags.SUB);
                    }
                    os.WriteByte(GT);
                }
                // contents
                Write(HtmlEncoder.Encode(chunk.Content));
                if (attributes != null && attributes[Chunk.SUBSUPSCRIPT] != null)
                {
                    // end sup or sub tag
                    os.WriteByte(LT);
                    os.WriteByte(FORWARD);
                    if ((float)attributes[Chunk.SUBSUPSCRIPT] > 0)
                    {
                        Write(HtmlTags.SUP);
                    }
                    else
                    {
                        Write(HtmlTags.SUB);
                    }
                    os.WriteByte(GT);
                }
                if (tag)
                {
                    // end tag
                    WriteEnd(Markup.HTML_TAG_SPAN);
                }
                return;
            }

            case Element.PHRASE: {
                Phrase phrase = (Phrase)element;
                styleAttributes = new Properties();
                if (phrase.HasLeading())
                {
                    styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = phrase.Leading.ToString() + "pt";
                }

                // start tag
                AddTabs(indent);
                WriteStart(Markup.HTML_TAG_SPAN);
                WriteMarkupAttributes(markup);
                Write(phrase.Font, styleAttributes);
                os.WriteByte(GT);
                currentfont.Push(phrase.Font);
                // contents
                foreach (IElement i in phrase)
                {
                    Write(i, indent + 1);
                }
                // end tag
                AddTabs(indent);
                WriteEnd(Markup.HTML_TAG_SPAN);
                currentfont.Pop();
                return;
            }

            case Element.ANCHOR: {
                Anchor anchor = (Anchor)element;
                styleAttributes = new Properties();
                if (anchor.HasLeading())
                {
                    styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = anchor.Leading.ToString() + "pt";
                }

                // start tag
                AddTabs(indent);
                WriteStart(HtmlTags.ANCHOR);
                if (anchor.Name != null)
                {
                    Write(HtmlTags.NAME, anchor.Name);
                }
                if (anchor.Reference != null)
                {
                    Write(HtmlTags.REFERENCE, anchor.Reference);
                }
                WriteMarkupAttributes(markup);
                Write(anchor.Font, styleAttributes);
                os.WriteByte(GT);
                currentfont.Push(anchor.Font);
                // contents
                foreach (IElement i in anchor)
                {
                    Write(i, indent + 1);
                }
                // end tag
                AddTabs(indent);
                WriteEnd(HtmlTags.ANCHOR);
                currentfont.Pop();
                return;
            }

            case Element.PARAGRAPH: {
                Paragraph paragraph = (Paragraph)element;
                styleAttributes = new Properties();
                if (paragraph.HasLeading())
                {
                    styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = paragraph.TotalLeading.ToString() + "pt";
                }

                // start tag
                AddTabs(indent);
                WriteStart(HtmlTags.DIV);
                WriteMarkupAttributes(markup);
                String alignment = HtmlEncoder.GetAlignment(paragraph.Alignment);
                if (!"".Equals(alignment))
                {
                    Write(HtmlTags.ALIGN, alignment);
                }
                Write(paragraph.Font, styleAttributes);
                os.WriteByte(GT);
                currentfont.Push(paragraph.Font);
                // contents
                foreach (IElement i in paragraph)
                {
                    Write(i, indent + 1);
                }
                // end tag
                AddTabs(indent);
                WriteEnd(HtmlTags.DIV);
                currentfont.Pop();
                return;
            }

            case Element.SECTION:
            case Element.CHAPTER: {
                // part of the start tag + contents
                WriteSection((Section)element, indent);
                return;
            }

            case Element.LIST: {
                List list = (List)element;
                // start tag
                AddTabs(indent);
                if (list.Numbered)
                {
                    WriteStart(HtmlTags.ORDEREDLIST);
                }
                else
                {
                    WriteStart(HtmlTags.UNORDEREDLIST);
                }
                WriteMarkupAttributes(markup);
                os.WriteByte(GT);
                // contents
                foreach (IElement i in list.Items)
                {
                    Write(i, indent + 1);
                }
                // end tag
                AddTabs(indent);
                if (list.Numbered)
                {
                    WriteEnd(HtmlTags.ORDEREDLIST);
                }
                else
                {
                    WriteEnd(HtmlTags.UNORDEREDLIST);
                }
                return;
            }

            case Element.LISTITEM: {
                ListItem listItem = (ListItem)element;
                styleAttributes = new Properties();
                if (listItem.HasLeading())
                {
                    styleAttributes[Markup.CSS_KEY_LINEHEIGHT] = listItem.TotalLeading.ToString() + "pt";
                }

                // start tag
                AddTabs(indent);
                WriteStart(HtmlTags.LISTITEM);
                WriteMarkupAttributes(markup);
                Write(listItem.Font, styleAttributes);
                os.WriteByte(GT);
                currentfont.Push(listItem.Font);
                // contents
                foreach (IElement i in listItem)
                {
                    Write(i, indent + 1);
                }
                // end tag
                AddTabs(indent);
                WriteEnd(HtmlTags.LISTITEM);
                currentfont.Pop();
                return;
            }

            case Element.CELL: {
                Cell cell = (Cell)element;

                // start tag
                AddTabs(indent);
                if (cell.Header)
                {
                    WriteStart(HtmlTags.HEADERCELL);
                }
                else
                {
                    WriteStart(HtmlTags.CELL);
                }
                WriteMarkupAttributes(markup);
                if (cell.BorderWidth != Rectangle.UNDEFINED)
                {
                    Write(HtmlTags.BORDERWIDTH, cell.BorderWidth.ToString());
                }
                if (cell.BorderColor != null)
                {
                    Write(HtmlTags.BORDERCOLOR, HtmlEncoder.Encode(cell.BorderColor));
                }
                if (cell.BackgroundColor != null)
                {
                    Write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.Encode(cell.BackgroundColor));
                }
                String alignment = HtmlEncoder.GetAlignment(cell.HorizontalAlignment);
                if (!"".Equals(alignment))
                {
                    Write(HtmlTags.HORIZONTALALIGN, alignment);
                }
                alignment = HtmlEncoder.GetAlignment(cell.VerticalAlignment);
                if (!"".Equals(alignment))
                {
                    Write(HtmlTags.VERTICALALIGN, alignment);
                }
                if (cell.GetWidthAsString() != null)
                {
                    Write(HtmlTags.WIDTH, cell.GetWidthAsString());
                }
                if (cell.Colspan != 1)
                {
                    Write(HtmlTags.COLSPAN, cell.Colspan.ToString());
                }
                if (cell.Rowspan != 1)
                {
                    Write(HtmlTags.ROWSPAN, cell.Rowspan.ToString());
                }
                if (cell.MaxLines == 1)
                {
                    Write(HtmlTags.STYLE, "white-space: nowrap;");
                }
                os.WriteByte(GT);
                // contents
                if (cell.IsEmpty())
                {
                    Write(NBSP);
                }
                else
                {
                    foreach (IElement i in cell.Elements)
                    {
                        Write(i, indent + 1);
                    }
                }
                // end tag
                AddTabs(indent);
                if (cell.Header)
                {
                    WriteEnd(HtmlTags.HEADERCELL);
                }
                else
                {
                    WriteEnd(HtmlTags.CELL);
                }
                return;
            }

            case Element.ROW: {
                Row row = (Row)element;

                // start tag
                AddTabs(indent);
                WriteStart(HtmlTags.ROW);
                WriteMarkupAttributes(markup);
                os.WriteByte(GT);
                // contents
                IElement cell;
                for (int i = 0; i < row.Columns; i++)
                {
                    if ((cell = (IElement)row.GetCell(i)) != null)
                    {
                        Write(cell, indent + 1);
                    }
                }
                // end tag
                AddTabs(indent);
                WriteEnd(HtmlTags.ROW);
                return;
            }

            case Element.TABLE: {
                Table table;
                try {
                    table = (Table)element;
                }
                catch (InvalidCastException) {
                    table = ((SimpleTable)element).CreateTable();
                }
                table.Complete();
                // start tag
                AddTabs(indent);
                WriteStart(HtmlTags.TABLE);
                WriteMarkupAttributes(markup);
                os.WriteByte(SPACE);
                Write(HtmlTags.WIDTH);
                os.WriteByte(EQUALS);
                os.WriteByte(QUOTE);
                Write(table.Width.ToString(System.Globalization.CultureInfo.InvariantCulture));
                if (!table.Locked)
                {
                    Write("%");
                }
                os.WriteByte(QUOTE);
                String alignment = HtmlEncoder.GetAlignment(table.Alignment);
                if (!"".Equals(alignment))
                {
                    Write(HtmlTags.ALIGN, alignment);
                }
                Write(HtmlTags.CELLPADDING, table.Cellpadding.ToString(System.Globalization.CultureInfo.InvariantCulture));
                Write(HtmlTags.CELLSPACING, table.Cellspacing.ToString(System.Globalization.CultureInfo.InvariantCulture));
                if (table.BorderWidth != Rectangle.UNDEFINED)
                {
                    Write(HtmlTags.BORDERWIDTH, table.BorderWidth.ToString(System.Globalization.CultureInfo.InvariantCulture));
                }
                if (table.BorderColor != null)
                {
                    Write(HtmlTags.BORDERCOLOR, HtmlEncoder.Encode(table.BorderColor));
                }
                if (table.BackgroundColor != null)
                {
                    Write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.Encode(table.BackgroundColor));
                }
                os.WriteByte(GT);
                // contents
                foreach (Row row in table)
                {
                    Write(row, indent + 1);
                }
                // end tag
                AddTabs(indent);
                WriteEnd(HtmlTags.TABLE);
                return;
            }

            case Element.ANNOTATION: {
                Annotation annotation = (Annotation)element;
                WriteComment(annotation.Title + ": " + annotation.Content);
                return;
            }

            case Element.IMGRAW:
            case Element.JPEG:
            case Element.JPEG2000:
            case Element.IMGTEMPLATE: {
                Image image = (Image)element;
                if (image.Url == null)
                {
                    return;
                }

                // start tag
                AddTabs(indent);
                WriteStart(HtmlTags.IMAGE);
                String path = image.Url.ToString();
                if (imagepath != null)
                {
                    if (path.IndexOf('/') > 0)
                    {
                        path = imagepath + path.Substring(path.LastIndexOf('/') + 1);
                    }
                    else
                    {
                        path = imagepath + path;
                    }
                }
                Write(HtmlTags.URL, path);
                if ((image.Alignment & Image.RIGHT_ALIGN) > 0)
                {
                    Write(HtmlTags.ALIGN, HtmlTags.ALIGN_RIGHT);
                }
                else if ((image.Alignment & Image.MIDDLE_ALIGN) > 0)
                {
                    Write(HtmlTags.ALIGN, HtmlTags.ALIGN_MIDDLE);
                }
                else
                {
                    Write(HtmlTags.ALIGN, HtmlTags.ALIGN_LEFT);
                }
                if (image.Alt != null)
                {
                    Write(HtmlTags.ALT, image.Alt);
                }
                Write(HtmlTags.PLAINWIDTH, image.ScaledWidth.ToString());
                Write(HtmlTags.PLAINHEIGHT, image.ScaledHeight.ToString());
                WriteMarkupAttributes(markup);
                WriteEnd();
                return;
            }

            default:
                return;
            }
        }
        /**
         * Writes the representation of a <CODE>Font</CODE>.
         *
         * @param font              a <CODE>Font</CODE>
         * @param styleAttributes   the style of the font
         */

        protected void Write(Font font, Properties styleAttributes)
        {
            if (font == null || !IsOtherFont(font) /*|| styleAttributes == null*/)
            {
                return;
            }
            Write(" ");
            Write(HtmlTags.STYLE);
            Write("=\"");
            if (styleAttributes != null)
            {
                foreach (String key in styleAttributes.Keys)
                {
                    WriteCssProperty(key, styleAttributes[key]);
                }
            }
            if (IsOtherFont(font))
            {
                WriteCssProperty(Markup.CSS_KEY_FONTFAMILY, font.Familyname);

                if (font.Size != Font.UNDEFINED)
                {
                    WriteCssProperty(Markup.CSS_KEY_FONTSIZE, font.Size.ToString() + "pt");
                }
                if (font.Color != null)
                {
                    WriteCssProperty(Markup.CSS_KEY_COLOR, HtmlEncoder.Encode(font.Color));
                }

                int      fontstyle = font.Style;
                BaseFont bf        = font.BaseFont;
                if (bf != null)
                {
                    String ps = bf.PostscriptFontName.ToLower(CultureInfo.InvariantCulture);
                    if (ps.IndexOf("bold") >= 0)
                    {
                        if (fontstyle == Font.UNDEFINED)
                        {
                            fontstyle = 0;
                        }
                        fontstyle |= Font.BOLD;
                    }
                    if (ps.IndexOf("italic") >= 0 || ps.IndexOf("oblique") >= 0)
                    {
                        if (fontstyle == Font.UNDEFINED)
                        {
                            fontstyle = 0;
                        }
                        fontstyle |= Font.ITALIC;
                    }
                }
                if (fontstyle != Font.UNDEFINED && fontstyle != Font.NORMAL)
                {
                    switch (fontstyle & Font.BOLDITALIC)
                    {
                    case Font.BOLD:
                        WriteCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD);
                        break;

                    case Font.ITALIC:
                        WriteCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC);
                        break;

                    case Font.BOLDITALIC:
                        WriteCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD);
                        WriteCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC);
                        break;
                    }

                    // CSS only supports one decoration tag so if both are specified
                    // only one of the two will display
                    if ((fontstyle & Font.UNDERLINE) > 0)
                    {
                        WriteCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_UNDERLINE);
                    }
                    if ((fontstyle & Font.STRIKETHRU) > 0)
                    {
                        WriteCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_LINETHROUGH);
                    }
                }
            }
            Write("\"");
        }