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

/** BrowserModel - Indeholder metoder som gør det muligt at styre
 *	displayet
 *	@author Søren S Munk (u001614)
 */
public class BrowserModel {
  
    /** den faste hjemmeside */
    private URL homeURL;

    /** det dokument med tilhørende url som for tiden vises */
    private Document currentDocument;
    private URL currentURL;
    
    /** diverse datastrukturer:
     * 	backStack    til brug for back-funktion
     * 	forwardStack til brug for forward-funktion
     * 	links         alle de links der kan klikkes på lige nu
     * 	visited      tidligere besøgte url'er
     */
    private Stack backStack;
    private Stack forwardStack;
    private HyperLinkSet links;
    private Set visited;

    /** BrowserModel initialiserer datastrukturerne
     * 	@param u hjemmesidens url
     */
    public BrowserModel(URL u) {
	backStack = new Stack();
	forwardStack = new Stack();
	links = new HyperLinkSet();
	visited = new Set();
	homeURL = u;
	setNewURL( homeURL );
    }
    
    /** generateDocument sørger for at currentDocument bliver udskrevet
     * 	@param d display hvor udskrift skal ske */
    public void generateDocument(BrowserDisplay d) {
		currentDocument.show(d);
    }
    
    /** addLink husker et anker
     * 	@param x1,y1 øverste venstre hjørne
     * 	@param x2,y2 nederste højre hjørne
     * 	@param url ankrets URL
     */
    public void addLink(int x1, int y1, int x2, int y2, URL url) {
	if ( url != null )
	    { links.add(x1, y1, x2, y2, url); }
    }
     
    /** getLink finder ud af om et punkt svarer til et anker
     * 	@param x x-koor
     * 	@param y y-koor
     * 	@return null hvis intet anker i punktet ellers den
     * 			tilhørende url
     */
    public URL getLink(int x, int y) {
		return( links.get(x, y) );
    }
        
    /** clearLinks sletter alle ankre */
    public void clearLinks() {
		links.clear();
    }
    
    /** seenURL url URL
     *	@return true hvis url tidligere har været åbnet af browseren
     *			ellers false
	 */
    public boolean seenURL(URL url) {
		return( visited.member( url ) );
    }

    //INSERT xtra public metoder til kommunikation med controlleren
    
    
    /** getUrl henter den aktuelle URL
     * 	@return currentURL */
    public URL getURL(){
    	return( currentURL );
    }
	
	
    /** home henter hjemmesiden (startsiden) */
    public void home() {
		setNewURL( homeURL );		
    }

    /** getTitle henter titlen for currentDocument 
     *	@return titlen for currentDocument
	 */
    public String getTitle() {
		return( currentDocument.title );
    }
    
    /** setNewURL sørger for at currentURL bliver sendt i backStack
	 *	og at der bliver lavet en ny forwardStack, samt tilføjer den
	 *	ny side til visited og sender så siden til parseren
	 */
    public void setNewURL(URL u) {
		backStack.push( currentURL );
		forwardStack = new Stack();
		currentURL = u;
		visited.add( currentURL );
		currentDocument = Parser.parseDocument( currentURL );
	}

    public void SF()
    {
	if ( !forwardStack.empty() ) 
	    {
		URL u = (URL) forwardStack.pop();
		try { System.out.println( u.toString() ); }
		catch ( java.lang.NullPointerException n) {}
		forwardStack.push( u );
	    }
	else
	    { System.out.println( "No more pages in stack" ); }
    }
    
    /** back returnerer true hvis det er muligt at gå tilbage,
     *  desuden hentes den sidste URL til parseren. Er det ikke
     *  muligt at gå tilbage returneres false.
     *  @return sandhedsværdi af om det er muligt at gå tilbage
	 */
    public boolean back() {
        if ( !backStack.empty() ) 
	    {
		forwardStack.push(currentURL);
		currentURL = (URL) backStack.pop();
		currentDocument = Parser.parseDocument(currentURL);
		return true;
	    }
	return false;
    }

    /**	forward returnerer true hvis det er muligt at gå frem,
	 *	desuden hentes den næste URL til parseren. Er det ikke
	 *	muligt at gå frem returneres false.
     *	@return sandhedsværdi af om det er muligt at gå frem
     */
    public boolean forward() {
        if ( !forwardStack.empty() )
	    {
            	backStack.push(currentURL);
            	currentURL = (URL)forwardStack.pop();
		currentDocument = Parser.parseDocument(currentURL);
		return true;
	    }
	return false;
    }

}
