// Seminarski.java — Spanish Present verb conjugator
// -*- coding: utf-8 -*-
//
// author: Danilo Šegan <mm01142@alas.matf.bg.ac.yu>, <danilo@kvota.net>
// br. indeksa: 142/01, R smer
//
import java.util.*;

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;


/* Conjugation-exception checking class */
class ConjugateExceptions {
    private Hashtable exceptions = new Hashtable();

    ConjugateExceptions() {
	exceptions.put("hacer", new String[] { "hago", "haces", "hace", "hacemos", "haceís", "hacen" });
	exceptions.put("ir", new String[] { "voy", "vas", "va", "vamos", "vaís", "van" });
	exceptions.put("ser", new String[] { "soy", "eres", "es", "somos", "soís", "son" });
	exceptions.put("tener", new String[] { "tengo", "tienes", "tiene", "tenemos", "teneís", "tienen" });
	exceptions.put("ver", new String[] { "veo", "ves", "ve", "vemos", "veis", "ven"});
	exceptions.put("volver", new String[] { "vuelvo", "vuelves", "vuelve", "volvemos", "volveís", "vuelven" });
	// ... add more
    }

    /* Returns conjugation list if a verb doesn't follow any of the 3 rules, otherwise it returns "null" */
    public String[] isException(String verb) {
	String[] result = (String[]) exceptions.get(verb);
	return result;
    }
}

/* Conjugations for -ar, -ir, and -er verbs. */
class ConjugateVerb {
    private String wordroot;
    private String conjugation;
    private String reflexive;
    
    ConjugateVerb(String verb) {

	/* if "se" is appended, it's a reflexive verb */
	if (verb.endsWith("se")) {
	    reflexive = new String("se");
	    verb = verb.substring(0,verb.length()-2);
	} else {
	    reflexive = null;
	}

	wordroot = verb.substring(0,verb.length()-2);
	if (verb.endsWith("ar") || verb.endsWith("er") || verb.endsWith("ir")) {
	    /* get only the suffix */
	    conjugation = verb.substring(verb.length()-2);
	} else {
	    conjugation = new String();
	}
    }


    /* Returns an array of 6 String items representing proper conjugations of instance verb */
    public String[] getPresent() { 
	String[][] all_conj = { {"o", "as", "a", "amos", "áis", "an"}, // -AR conjugation
				{"o", "es", "e", "emos", "éis", "en"}, // -ER conjugation
				{"o", "es", "e", "imos", "ís", "en"}   // -IR conjugation
	}; 
	String[] reflexives = {"me", "te", "se", "nos", "os", "se"};

	String[] conj;

	/* choose conjugation suffixes according to already parsed conjugation */
	conj = all_conj[0];
	if (conjugation.equalsIgnoreCase("ar"))
	    conj = all_conj[0];
	else if (conjugation.equalsIgnoreCase("er"))
	    conj = all_conj[1];
	else if (conjugation.equalsIgnoreCase("ir"))
	    conj = all_conj[2];
	else
	    return null;

	String[] result = new String[6];
	for (int i=0; i<6; i++) {
	    if (reflexive != null)
		result[i] = new String(reflexives[i] + " " + wordroot + conj[i]);
	    else
		result[i] = new String(wordroot + conj[i]);
	}
	return result; 
    }
}

/* Base applet allowing present conjugation of verbs */
public class Seminarski extends Applet implements ActionListener {
    OutputArea framedArea; // subclassed panel for output
    TextField verbInput;   // verb input field

    // List of conjugation exceptions
    ConjugateExceptions conjex = new ConjugateExceptions();

    /* action identifier for "Conjugate" button */
    static final String CONJUGATE = "conjugate";

    public void init() {
        GridBagLayout gridBag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
	
        setLayout(gridBag);

	c.fill = GridBagConstraints.BOTH; // stretch everything

	c.gridwidth = GridBagConstraints.REMAINDER; // separate in this row
	c.weighty = 1.0; // fill up all remaining vertical space with OutputArea
	c.weightx = 1.0; // same for horizontal
	framedArea = new OutputArea(this);
	gridBag.setConstraints(framedArea, c);
	add(framedArea);

	c.weighty = 0.0; // minimum required vertical space
	c.weightx = 1.0; // fill up any remaining horizontal space with this TextField
	c.gridwidth = GridBagConstraints.RELATIVE;
	verbInput = new TextField();
	gridBag.setConstraints(verbInput, c);
	add(verbInput);

	c.weightx = 0.0; // just the bare minimum of horizontal space
	c.gridwidth = GridBagConstraints.REMAINDER; // end this row
	Button button = new Button("Conjugate");
	button.setActionCommand(CONJUGATE);
	button.addActionListener(this);
	gridBag.setConstraints(button, c);
	add(button);
    }

    /* Handle button press event */
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
         
        if (command == CONJUGATE) { // "Conjugate" button is pressed
	    String verb = verbInput.getText();

	    /* if it's an exception (not following a rule), get the data from exceptions table */
	    String[] exception = conjex.isException(verb);
	    String[] rc;
	    if (exception != null) {
		rc = exception;
	    } else {
		ConjugateVerb conj = new ConjugateVerb(verb);
		rc = conj.getPresent();
	    }

	    /* concatenate everything into one string and display in textarea */
	    String result = new String();
	    result = rc[0] + "\n" + rc[1] + "\n" +  rc[2] + "\n" +  rc[3] + "\n" +  rc[4] + "\n" +  rc[5];
	    framedArea.Output.setText(result);
	}
    }
}

/* This class contains a text area for display and draws a frame. */
class OutputArea extends Panel {
    public TextArea Output;
    public OutputArea(Seminarski controller) {
        super();

        /* Set layout to one that makes its contents as big as possible. */
        setLayout(new GridLayout(1,0));
	Output = new TextArea();
	Output.setEditable(false);
        add(Output);
    }

    public Insets getInsets() {
        return new Insets(4,4,5,5);
    }

    /* draw borders */
    public void paint(Graphics g) {
        Dimension d = getSize();
        Color bg = getBackground();
 
        g.setColor(bg);
        g.draw3DRect(1, 1, d.width - 2, d.height - 2, false);
    }
}
