/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.dtd.core.internal.emf.util;

import java.util.Collection;
import java.util.Iterator;

import org.eclipse.wst.dtd.core.internal.emf.DTDAttribute;
import org.eclipse.wst.dtd.core.internal.emf.DTDElement;
import org.eclipse.wst.dtd.core.internal.emf.DTDElementContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDElementReferenceContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDEntity;
import org.eclipse.wst.dtd.core.internal.emf.DTDEntityReferenceContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDFile;
import org.eclipse.wst.dtd.core.internal.emf.DTDGroupContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDGroupKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDNotation;
import org.eclipse.wst.dtd.core.internal.emf.DTDObject;
import org.eclipse.wst.dtd.core.internal.emf.DTDOccurrenceType;
import org.eclipse.wst.dtd.core.internal.emf.DTDPCDataContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDParameterEntityReference;
import org.eclipse.wst.dtd.core.internal.emf.DTDRepeatableContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDSourceOffset;


public class DTDPrinter extends DTDVisitor {
	StringBuffer sb = new StringBuffer();
	boolean updateOffset = true;

	public DTDPrinter(boolean updateOffset) {
		this.updateOffset = updateOffset;
	}

	public StringBuffer getBuffer() {
		return sb;
	}

	public void visitDTDFile(DTDFile file) {
		super.visitDTDFile(file);
	}

	public void visitDTDNotation(DTDNotation notation) {
		generateComment(notation);
		updateStartOffset(notation, sb.length());
		sb.append("<!NOTATION ");
		sb.append(notation.getName()).append(" ");

		String publicID = notation.getPublicID();
		String systemID = notation.getSystemID();
		if (publicID == null || publicID.equals("")) {
			sb.append("SYSTEM ");
		}
		else {
			sb.append("PUBLIC \"").append(publicID).append("\" ");
		}

		if (systemID == null) {
			sb.append("\"\"");
		}
		else {
			sb.append("\"").append(systemID).append("\"");
		}
		endTag();
		updateEndOffset(notation, sb.length() - 1); // -1 for the newline char
		super.visitDTDNotation(notation);
	}

	public void visitDTDEntity(DTDEntity entity) {
		generateComment(entity);
		updateStartOffset(entity, sb.length());
		sb.append("<!ENTITY ");

		if (entity.isParameterEntity())
			sb.append("% ");

		sb.append(entity.getName()).append(" ");
		sb.append(entity.getContent().unparse());

		endTag();
		updateEndOffset(entity, sb.length() - 1); // -1 for the newline char
		super.visitDTDEntity(entity);
	}

	public void visitDTDElement(DTDElement element) {
		generateComment(element);
		updateStartOffset(element, sb.length());
		sb.append("<!ELEMENT " + element.getName());
		DTDElementContent content = element.getContent();
		if (content instanceof DTDPCDataContent || content instanceof DTDElementReferenceContent) {
			sb.append(" (");
			super.visitDTDElement(element);
			sb.append(")");
		} // end of if ()
		else {
			sb.append(" ");
			super.visitDTDElement(element);
		} // end of else
		endTag();
		updateEndOffset(element, sb.length() - 1); // -1 for the newline char
		visitAttributes(element);
	}

	public void visitDTDParameterEntityReference(DTDParameterEntityReference parmEntity) {
		generateComment(parmEntity);
		updateStartOffset(parmEntity, sb.length());
		sb.append("%" + parmEntity.getName() + ";\n");
		updateEndOffset(parmEntity, sb.length() - 1); // -1 for the newline
														// char
	}

	public void visitDTDElementContent(DTDElementContent content) {
		updateStartOffset(content, sb.length());
		String trailingChars = "";
		if (content instanceof DTDRepeatableContent) {
			DTDRepeatableContent repeatContent = (DTDRepeatableContent) content;
			DTDOccurrenceType occurrenceType = repeatContent.getOccurrence();
			// Integer occurrence = repeatContent.getOccurrence();
			if (occurrenceType != null) {
				int occurType = occurrenceType.getValue();
				if (occurType != DTDOccurrenceType.ONE) {
					if (repeatContent instanceof DTDEntityReferenceContent) {
						sb.append("(");
						trailingChars = ")";
					}
					trailingChars += (char) occurType;
				}
			} // end of if ()
		} // end of if ()

		if (content instanceof DTDGroupContent) {
			super.visitDTDElementContent(content);
		} // end of if ()
		else if (content instanceof DTDElementReferenceContent || content instanceof DTDEntityReferenceContent) {
			sb.append(((DTDRepeatableContent) content).unparseRepeatableContent());
		} // end of if ()
		else {
			// handle DTDPCDataContent, DTDAnyContent and DTDEmptyContent here
			sb.append(content.getContentName());
		} // end of else
		sb.append(trailingChars);
		updateEndOffset(content, sb.length());
	}

	public void visitDTDGroupContent(DTDGroupContent group) {
		sb.append("(");
		DTDGroupKind kind = group.getGroupKind();
		// MOF2EMF Port
		// Integer groupKind = group.getGroupKind();
		if (kind == null) {
			group.setGroupKind(DTDGroupKind.get(DTDGroupKind.SEQUENCE));
		} // end of if ()

		String con = group.getGroupKind().getValue() == DTDGroupKind.CHOICE ? " | " : ", ";

		// Loop thru the children of the current group
		Collection content = group.getContent();
		if (content != null) {
			boolean firstContent = true;
			for (Iterator i = content.iterator(); i.hasNext();) {
				if (!firstContent) {
					sb.append(con);
				} // end of if ()
				else {
					firstContent = false;
				} // end of else
				visitDTDElementContent((DTDElementContent) i.next());
			}
		}

		sb.append(")");
	}

	private void visitAttributes(DTDElement elem) {
		Collection attrs = elem.getDTDAttribute();
		Iterator i = attrs.iterator();
		if (attrs != null && i.hasNext()) {
			DTDAttribute attrib = (DTDAttribute) i.next();
			String comment = attrib.getComment();
			if (comment != null && comment.length() > 0)
				sb.append("<!--\n ").append(comment).append("\n-->\n");
			sb.append("<!ATTLIST " + elem.getName() + "\n");
			sb.append(" ");
			updateStartOffset(attrib, sb.length());
			sb.append(attrib.unparse());
			updateEndOffset(attrib, sb.length());
			sb.append("\n");
			for (; i.hasNext();) {
				attrib = (DTDAttribute) i.next();
				comment = attrib.getComment();
				if (comment != null && comment.length() > 0) {
					sb.append(">\n");
					if (comment != null && comment.length() > 0)
						sb.append("<!--\n ").append(comment).append("\n-->\n");
					sb.append("<!ATTLIST " + elem.getName() + "\n");
				}
				sb.append(" ");
				updateStartOffset(attrib, sb.length());
				sb.append(attrib.unparse());
				updateEndOffset(attrib, sb.length());
				sb.append("\n");
			}
			sb.append(">\n");
		}
	}

	private void endTag() {
		sb.append(">\n");
	}

	private void updateStartOffset(DTDSourceOffset o, int offset) {
		if (updateOffset) {
			o.setStartOffset(offset);
		} // end of if ()
	}

	private void updateEndOffset(DTDSourceOffset o, int offset) {
		if (updateOffset) {
			o.setEndOffset(offset);
		} // end of if ()
	}

	private void generateComment(DTDObject dtdObject) {
		String commentString = null;

		if (dtdObject instanceof DTDElement)
			commentString = ((DTDElement) dtdObject).getComment();
		else if (dtdObject instanceof DTDEntity)
			commentString = ((DTDEntity) dtdObject).getComment();
		else if (dtdObject instanceof DTDNotation)
			commentString = ((DTDNotation) dtdObject).getComment();

		if (commentString != null && commentString.length() > 0) {
			sb.append("<!--").append(commentString).append("-->\n");
		}
	}


	// /**
	// * @generated
	// */
	// protected StringBuffer getBufferGen() {
	//
	// return sb;
	// }
	// /**
	// * @generated
	// */
	// protected void visitDTDFileGen(DTDFile file) {
	//
	// super.visitDTDFile(file);
	// }
	// /**
	// * @generated
	// */
	// protected void visitDTDNotationGen(DTDNotation notation) {
	//
	// generateComment(notation);
	// updateStartOffset(notation, sb.length());
	// sb.append("<!NOTATION ");
	// sb.append(notation.getName()).append(" ");
	//
	//
	// String publicID = notation.getPublicID();
	// String systemID = notation.getSystemID();
	// if (publicID == null || publicID.equals(""))
	// {
	// sb.append("SYSTEM ");
	// }
	// else
	// {
	// sb.append("PUBLIC \"").append(publicID).append("\" ");
	// }
	//
	//
	// if (systemID==null)
	// {
	// sb.append("\"\"");
	// }
	// else
	// {
	// sb.append("\"").append(systemID).append("\"");
	// }
	// endTag();
	// updateEndOffset(notation, sb.length() - 1); // -1 for the newline char
	// super.visitDTDNotation(notation);
	// }
	// /**
	// * @generated
	// */
	// protected void visitDTDEntityGen(DTDEntity entity) {
	//
	// generateComment(entity);
	// updateStartOffset(entity, sb.length());
	// sb.append("<!ENTITY ");
	//
	//
	// if (entity.isParameterEntity())
	// sb.append("% ");
	//
	//
	// sb.append(entity.getName()).append(" ");
	// sb.append(entity.getContent().unparse());
	//
	//
	// endTag();
	// updateEndOffset(entity, sb.length() - 1); // -1 for the newline char
	// super.visitDTDEntity(entity);
	// }
	// /**
	// * @generated
	// */
	// protected void visitDTDElementGen(DTDElement element) {
	//
	// generateComment(element);
	// updateStartOffset(element, sb.length());
	// sb.append("<!ELEMENT " + element.getName());
	// DTDElementContent content = element.getContent();
	// if (content instanceof DTDPCDataContent ||
	// content instanceof DTDElementReferenceContent)
	// {
	// sb.append(" (");
	// super.visitDTDElement(element);
	// sb.append(")");
	// } // end of if ()
	// else
	// {
	// sb.append(" ");
	// super.visitDTDElement(element);
	// } // end of else
	// endTag();
	// updateEndOffset(element, sb.length() - 1); // -1 for the newline char
	// visitAttributes(element);
	// }
	// /**
	// * @generated
	// */
	// protected void
	// visitDTDParameterEntityReferenceGen(DTDParameterEntityReference
	// parmEntity) {
	//
	// generateComment(parmEntity);
	// updateStartOffset(parmEntity, sb.length());
	// sb.append("%" + parmEntity.getName() + ";\n");
	// updateEndOffset(parmEntity, sb.length() - 1); // -1 for the newline
	// char
	// }
	// /**
	// * @generated
	// */
	// protected void visitDTDElementContentGen(DTDElementContent content) {
	//
	// updateStartOffset(content, sb.length());
	// String trailingChars = "";
	// if (content instanceof DTDRepeatableContent )
	// {
	// DTDRepeatableContent repeatContent = (DTDRepeatableContent) content;
	// Integer occurrence = repeatContent.getOccurrence();
	// if (occurrence != null)
	// {
	// int occurType = occurrence.intValue();
	// if (occurType != DTDOccurrenceType.ONE)
	// {
	// if (repeatContent instanceof DTDEntityReferenceContent)
	// {
	// sb.append("(");
	// trailingChars = ")";
	// }
	// trailingChars += (char) occurType;
	// }
	// } // end of if ()
	// } // end of if ()
	//    
	// if (content instanceof DTDGroupContent)
	// {
	// super.visitDTDElementContent(content);
	// } // end of if ()
	// else if (content instanceof DTDElementReferenceContent ||
	// content instanceof DTDEntityReferenceContent)
	// {
	// sb.append(((DTDRepeatableContent)content).unparseRepeatableContent());
	// } // end of if ()
	// else
	// {
	// // handle DTDPCDataContent, DTDAnyContent and DTDEmptyContent here
	// sb.append(content.getContentName());
	// } // end of else
	// sb.append(trailingChars);
	// updateEndOffset(content, sb.length());
	// }
	// /**
	// * @generated
	// */
	// protected void visitDTDGroupContentGen(DTDGroupContent group) {
	//
	// sb.append("(");
	//    
	// Integer groupKind = group.getGroupKind();
	// if (groupKind == null)
	// {
	// group.setGroupKind(DTDGroupKind.SEQUENCE);
	// } // end of if ()
	//    
	// String con = group.getGroupKind().intValue() == DTDGroupKind.CHOICE ? "
	// | " : ", ";
	//
	//
	// // Loop thru the children of the current group
	// Collection content = group.getContent();
	// if (content != null)
	// {
	// boolean firstContent = true;
	// for (Iterator i = content.iterator(); i.hasNext(); )
	// {
	// if (!firstContent)
	// {
	// sb.append(con);
	// } // end of if ()
	// else
	// {
	// firstContent = false;
	// } // end of else
	// visitDTDElementContent((DTDElementContent) i.next());
	// }
	// }
	//
	//
	// sb.append(")");
	// }
	// /**
	// * @generated
	// */
	// protected void visitAttributesGen(DTDElement elem) {
	//
	// Collection attrs = elem.getDTDAttribute();
	// Iterator i = attrs.iterator();
	// if (attrs != null && i.hasNext())
	// {
	// DTDAttribute attrib = (DTDAttribute) i.next();
	// String comment = attrib.getComment();
	// if (comment!=null && comment.length()>0)
	// sb.append("<!--\n ").append(comment).append("\n-->\n");
	// sb.append("<!ATTLIST " + elem.getName() + "\n");
	// sb.append(" ");
	// updateStartOffset(attrib, sb.length());
	// sb.append(attrib.unparse());
	// updateEndOffset(attrib, sb.length());
	// sb.append("\n");
	// for (; i.hasNext(); )
	// {
	// attrib = (DTDAttribute) i.next();
	// comment = attrib.getComment();
	// if (comment!=null && comment.length()>0)
	// {
	// sb.append(">\n");
	// if (comment!=null && comment.length()>0)
	// sb.append("<!--\n ").append(comment).append("\n-->\n");
	// sb.append("<!ATTLIST " + elem.getName() + "\n");
	// }
	// sb.append(" ");
	// updateStartOffset(attrib, sb.length());
	// sb.append(attrib.unparse());
	// updateEndOffset(attrib, sb.length());
	// sb.append("\n");
	// }
	// sb.append(">\n");
	// }
	// }
	// /**
	// * @generated
	// */
	// protected void endTagGen() {
	//
	// sb.append(">\n");
	// }
	// /**
	// * @generated
	// */
	// protected void updateStartOffsetGen(DTDSourceOffset o, int offset) {
	//
	// if (updateOffset)
	// {
	// o.setStartOffset(offset);
	// } // end of if ()
	// }
	// /**
	// * @generated
	// */
	// protected void updateEndOffsetGen(DTDSourceOffset o, int offset) {
	//
	// if (updateOffset)
	// {
	// o.setEndOffset(offset);
	// } // end of if ()
	// }
	// /**
	// * @generated
	// */
	// protected void generateCommentGen(DTDObject dtdObject) {
	//
	// String commentString = null;
	//
	//
	// if (dtdObject instanceof DTDElement)
	// commentString = ((DTDElement)dtdObject).getComment();
	// else if (dtdObject instanceof DTDEntity)
	// commentString = ((DTDEntity)dtdObject).getComment();
	// else if (dtdObject instanceof DTDNotation)
	// commentString = ((DTDNotation)dtdObject).getComment();
	//
	//
	// if ( commentString!=null && commentString.length()>0)
	// {
	// sb.append("<!--").append(commentString).append("-->\n");
	// }
	// }
}// DTDPrinter
