import java.io.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;

public class League2 {

  /* If no XML-Document with teams is found this method is used to create a completely
  new Document. Therefore a list of teams is read from the Systems input stream. */
  public static Document createTeams() throws IOException {
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("Enter teams or nothing to end input...");       
    Vector usedNames = new Vector();
    
    // create the root element
    Element root = new Element("LEAGUE");   
    while (true) {
      String teamName = input.readLine();

      if (teamName.equals("")) break; // end of input
      
      // each team must have a unique name
      if (usedNames.contains(teamName)) {
        System.out.println("This team has allready been entered.");
      } else {    
          usedNames.add(teamName);
          root.addContent(new Element("POSITION")
                .addContent(new Element("TEAM").setText(teamName))
                .addContent(new Element("POINTS").setText("0"))
                .addContent(new Element("GOALS").setText("0"))
                .addContent(new Element("AGAINSTS").setText("0"))
                .addContent(new Element("RECORD")
                  .addAttribute("WINS","0")
                  .addAttribute("LOSSES","0")
                  .addAttribute("DRAWS","0"))           
          );
      }                
    }
    return new Document(root);
  }

  /* This method is used in order to perform the changes on a POSITION Element after a game. */
  public static void processResult(Element e, int gls, int ags) throws DataConversionException {   
    // draw
    if (gls == ags) {
      // update points
      Element points = e.getChild("POINTS");
      points.setText( Integer.toString(Integer.parseInt(points.getText()) + 1) );     
    
      // update record
      Attribute record = e.getChild("RECORD").getAttribute("DRAWS");
      record.setValue( Integer.toString(record.getIntValue()+1) );
       
    } else if (gls > ags) {  // win
      Element points = e.getChild("POINTS");
      points.setText( Integer.toString(Integer.parseInt(points.getText()) + 3) );         
      
      // update record
      Attribute record = e.getChild("RECORD").getAttribute("WINS");
      record.setValue( Integer.toString(record.getIntValue()+1) );
    } else { // lose
      // update record
      Attribute record = e.getChild("RECORD").getAttribute("LOSSES");
      record.setValue( Integer.toString(record.getIntValue()+1) );    
    }
    
    // update goals
    Element goals = e.getChild("GOALS");
    goals.setText( Integer.toString(Integer.parseInt(goals.getText()) + gls) );
    Element againsts = e.getChild("AGAINSTS");
    againsts.setText( Integer.toString(Integer.parseInt(againsts.getText()) + ags) );
  }
  
  public static void main(String[] args) {  
    // commandline ok?
    if (args.length != 1) {
      System.out.println("Usage: java League2 XML-File");
      System.exit(1);
    }
    
    SAXBuilder builder = new SAXBuilder(false);
     
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    
    Document doc = null;
    try {   
      // parse document
      doc = builder.build(new File(args[0]));
    }
    catch (JDOMException e) {
      System.out.println("Specified file not found. Please enter teams.");
      try { // let the user input teams
        doc = createTeams();
      }
      catch (Exception ex) {
        System.out.println("Unrecoverable error occured. Exiting...");
        System.exit(1);
      }
    }
    
    // get reference to root element
    Element root = doc.getRootElement();
 
    // read in the results for every team 
    List teams = root.getChildren("POSITION");
    for (int i=0; i<teams.size(); ++i) {
      Element curTeam = (Element) teams.get(i);
 
      while (true) {
        System.out.println("Enter result for "+curTeam.getChild("TEAM").getText());
        try {
          int goals = Integer.parseInt(input.readLine());
          int againsts = Integer.parseInt(input.readLine());
          
          // update the data for this team
          processResult(curTeam, goals, againsts);
          break;
        }
/*        catch (DataConversionException d) {
          System.out.println("The file is corrupted...");
          System.exit(1);
        } */
        catch (Exception e) {
          System.out.println("Input example for 2-0 win: \"2<ENTER>0<ENTER>\"");
        }
      }
    }
    
    // sort the list using Comparator defined below
    Collections.sort(teams, new LigaComparator());
    root.setChildren(teams);
    
    // write back
    try {
      FileOutputStream out = new FileOutputStream(args[0]);
      XMLOutputter serializer = new XMLOutputter();
      serializer.output(doc,out);
      out.flush();
      out.close();
    }
    catch (IOException e) {  
      System.err.println(e);
    }
  }
}


// this class is used for the sorting of the elements
class LigaComparator implements Comparator {
  public int compare(Object o1, Object o2) {
    Element team1 = (Element) o1;
    Element team2 = (Element) o2;
    
    int pointsTeam1 = Integer.parseInt( team1.getChild("POINTS").getText() );
    int pointsTeam2 = Integer.parseInt( team2.getChild("POINTS").getText() );

    if (pointsTeam1 - pointsTeam2 != 0) {
      return pointsTeam2 - pointsTeam1;
    } else { // if points are equal look at the goals
      int goalDiffTeam1 = Integer.parseInt( team1.getChild("GOALS").getText() ) -
                          Integer.parseInt( team1.getChild("AGAINSTS").getText() );
                          
      int goalDiffTeam2 = Integer.parseInt( team2.getChild("GOALS").getText() ) -
                          Integer.parseInt( team2.getChild("AGAINSTS").getText() );
                          
      return goalDiffTeam2 - goalDiffTeam1;
    }
  }
  
  public boolean equals(Object o) {
    return o.equals(this);
  } 
}

