import java.awt.*;
import java.awt.image.*;
import java.net.*;

/** Document - repręsenterer en webside i HTML0, i form af rekursiv
 *	datastruktur
 */

public class Document {
    
    public String title;
    public HTMLSTAR htmls;
    
    
    Document (HTMLSTAR htmls, String title) {
		this.title = title;
		this.htmls = htmls;
    }
    
    public void show(BrowserDisplay d) { 
		if ( htmls == null ) d.word("** empty/unreadable document**");
		else htmls.show(d);
    }
    
    public static class HTMLSTAR {
		HTML html;
		HTMLSTAR rest;
		
		HTMLSTAR(HTML html, HTMLSTAR rest) {
		    this.html = html;
		    this.rest = rest;
		}
		
		/** show Udskriver html til BrowserDisplay vha. html's
		 * 	egen show metode
		 */
		public void show(BrowserDisplay d) {
		    HTMLSTAR h = this;
		    while(h != null) {
				h.html.show(d);
				h = h.rest;
		    }
		}
    }
    
    public static abstract class HTML {
		public abstract void show(BrowserDisplay d);
	    }
	    
	public static class HTMLword extends HTML {
		
		private String word;
		
		public HTMLword(String word) { this.word = word; }
		
		/** show bruger word metoden i BrowserDisplay */
		public void show(BrowserDisplay d) { d.word(word); }
    }
    
    public static class HTMLanchor extends HTML {
		
		URL url;
		HTMLSTAR html;
	
		public HTMLanchor(URL url, HTMLSTAR html) {
		    this.url = url;
		    this.html = html;
		}
		
		/** show Udskriver html til BrowserDisplay vha. html's
		 *	egen show metode
		 */
		public void show(BrowserDisplay d) {
		    d.anchorMode(url);
		    if (html != null) {	html.show(d); }
		    d.normalMode();
		}
    }
    
    public static class HTMLbold extends HTML {
		HTMLSTAR html;
	
		public HTMLbold(HTMLSTAR html) { this.html = html; }
		
		/** show Udskriver html til BrowserDisplay vha. html's
		 *	egen show metode		 
		 */
		public void show(BrowserDisplay d) {
		    d.pushBoldFont();
		    html.show(d);
	    	d.popFont();
		}
    }
    
    public static class HTMLitalics extends HTML {
		private HTMLSTAR html;
	
		public HTMLitalics(HTMLSTAR html) { this.html = html; }
	
		/** show Udskriver html til BrowserDisplay vha. html's
		 *	egen show metode
		 */
		public void show(BrowserDisplay d) {
	    	d.pushItalicFont();
		    html.show(d);
		    d.popFont();
		}
    }
    
    public static class HTMLheader extends HTML {
		HTMLSTAR html;
	
		public HTMLheader(HTMLSTAR html) { this.html = html; }
		
		/** show Udskriver html til BrowserDisplay vha. html's
		 *	egen show metode
		 */
		public void show(BrowserDisplay d) {
	    	d.newLine();
	    	d.pushHeaderFont();
		    html.show(d);
		    d.popFont();
	    	d.paragraph();
		}
    }
    
    public static class HTMLparagraph extends HTML {
		
		/** show Kalder paragraph i BrowserDisplay */
		public void show(BrowserDisplay d) { d.paragraph(); }
    }
    
    public static class HTMLbreak extends HTML {
	
		/** show Kalder newLine i BrowserDisplay */
		public void show(BrowserDisplay d) { d.newLine(); }
    }
    
    public static class HTMLrule extends HTML {
	
		/** show Kalder rule i BrowserDisplay */
		public void show(BrowserDisplay d) { d.rule(); }
    }
    
    public static class HTMLimage extends HTML {
		URL url;
	
		public HTMLimage(URL url) { this.url = url; }
	
		/** show Kalder image i BrowserDisplay */
		public void show(BrowserDisplay d) { d.image(url); }
    }
    
    public static class HTMLlist extends HTML {
		ITEMSTAR item;
	
		public HTMLlist(ITEMSTAR item) { this.item = item; }
	
		/** show Kalder item's show-metode */
		public void show(BrowserDisplay d) { item.show(d); }
    
	}
    
    public static class HTMLspace extends HTML {
		
		/** show Kalder space i BrowserDisplay */
		public void show(BrowserDisplay d) { d.space(); }
	
    }
    
    public static class ITEMSTAR {
		ITEM item;
		ITEMSTAR rest;
		
		public ITEMSTAR(ITEM item, ITEMSTAR rest) { 
		    this.item = item;
		    this.rest = rest;
		}
		
		/** show Kalder item's show-metode */
		public void show(BrowserDisplay d) {
		    ITEMSTAR i = this;
		    while(i != null) {
				i.item.show(d);
				i = i.rest;
		    }
			d.newLine();
		}
    }
    
    public static class ITEM {
		HTMLSTAR html;
		int nesting; 
		
		public ITEM(HTMLSTAR html, int nesting) { 
		    this.html = html;
		    this.nesting = nesting;
		}
		
		/** show Kalder hhv. black og white-Dot alt efter
		 *	om det er et lige eller ulige trin
		 */
		public void show(BrowserDisplay d) {
		    d.newLine();
		    
		    if  ( nesting % 2 != 0 ) 
				{ d.blackDot(); }
		    else
				{ d.whiteDot(); }
		
		    d.incMargin();
		    html.show(d);
		    d.decMargin();
		}
    }
}
