package compiler.language.translator.conceptual;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.LinkedList;
import java.util.List;

import compiler.language.ast.topLevel.CompilationUnitAST;
import compiler.language.conceptual.ConceptualException;
import compiler.language.conceptual.NameConflictException;
import compiler.language.conceptual.QName;
import compiler.language.conceptual.Resolvable;
import compiler.language.conceptual.UnresolvableException;
import compiler.language.conceptual.topLevel.ConceptualFile;
import compiler.language.conceptual.topLevel.ConceptualPackage;
import compiler.language.parser.LanguageParser;
import compiler.language.parser.LanguageTokenizer;

/*
 * Created on 14 Nov 2010
 */

/**
 * @author Anthony Bryant
 */
public class ConceptualTranslator
{

  private LanguageParser parser;
  private ConceptualPackage rootPackage;
  private ASTConverter astConverter;
  private NameResolver nameResolver;

  /**
   * Creates a new ConceptualTranslator to parse and convert files to the conceptual hierarchy.
   * @param parser - the LanguageParser to use to parse files
   * @param classpath - the classpath for this translator
   */
  public ConceptualTranslator(LanguageParser parser, List<File> classpath)
  {
    this.parser = parser;
    rootPackage = new ConceptualPackage(this, classpath);
    astConverter = new ASTConverter(rootPackage);
    nameResolver = new NameResolver(astConverter.getConceptualASTNodes());
    nameResolver.buildUniversalBaseClass(rootPackage);
  }

  /**
   * @return the classpath to load source files from, as a List&lt;File&gt;
   */
  public List<File> getClassPath()
  {
    // TODO: get a proper classpath from somewhere
    return new LinkedList<File>();
  }

  /**
   * Translates the files which have been parsed into the conceptual representation.
   * @throws NameConflictException - if a name conflict was detected
   * @throws ConceptualException - if a conceptual problem was detected during the translation
   */
  public void translate() throws NameConflictException, ConceptualException
  {
    nameResolver.resolveParents();
  }

  /**
   * Resolves the specified QName on the root package
   * @param name - the name to resolve
   * @return the Resolvable resolved
   * @throws NameConflictException - if a name conflict was detected
   * @throws UnresolvableException - if the name is not resolvable without more information
   */
  public Resolvable translate(QName name) throws NameConflictException, UnresolvableException
  {
    return rootPackage.resolve(name, false);
  }

  /**
   * Attempts to parse the specified file into a conceptual file. If something fails in the process, an error is printed before returning null.
   * If a file is correctly parsed and converted into a ConceptualFile, it is also added to the NameResolver.
   * @param file - the file to parse
   * @param expectedPackage - the package that the file is expected to be in, which should be checked against the package declaration inside it
   * @return the ConceptualFile parsed, or null if an error occurred
   */
  public ConceptualFile parseFile(File file, ConceptualPackage expectedPackage)
  {
    CompilationUnitAST ast;
    try
    {
      FileReader reader = new FileReader(file);
      LanguageTokenizer tokenizer = new LanguageTokenizer(reader);
      ast = parser.parse(tokenizer);
    }
    catch (FileNotFoundException e)
    {
      e.printStackTrace();
      return null;
    }

    try
    {
      ConceptualFile conceptualFile = astConverter.convert(file, ast, expectedPackage);
      nameResolver.addFile(conceptualFile);
      return conceptualFile;
    }
    catch (ConceptualException e)
    {
      e.printStackTrace();
      return null;
    }
    catch (NameConflictException e)
    {
      e.printStackTrace();
      return null;
    }
  }

}

@@ -133,37 +133,8 @@
 er;%0A
-import java.util.LinkedList;%0A
 impo
@@ -1536,226 +1536,8 @@
  %7D%0A%0A
-  /**%0A   * @return the classpath to load source files from, as a List&lt;File&gt;%0A   */%0A  public List%3CFile%3E getClassPath()%0A  %7B%0A    // TODO: get a proper classpath from somewhere%0A    return new LinkedList%3CFile%3E();%0A  %7D%0A%0A
   /*

Remove old unused method: getClassPath()