package gov.nih.nci.ncicb.cadsr.loader.parser;

import gov.nih.nci.ncicb.cadsr.loader.event.*;
import gov.nih.nci.ncicb.cadsr.loader.defaults.UMLDefaults;

import org.apache.log4j.Logger;

import gov.nih.nci.ncicb.cadsr.loader.util.PropertyAccessor;
import gov.nih.nci.ncicb.cadsr.loader.util.StringUtil;
import gov.nih.nci.ncicb.cadsr.loader.util.RunMode;

import gov.nih.nci.ncicb.cadsr.loader.validator.*;

import gov.nih.nci.ncicb.cadsr.loader.UserSelections;

import gov.nih.nci.ncicb.xmiinout.handler.*;
import gov.nih.nci.ncicb.xmiinout.domain.*;


import java.io.*;

import java.util.*;

public class PreParser implements Parser {

  private UMLHandler listener;

  private ProgressListener progressListener = null;
  private String packageName = "";

  private Logger logger = Logger.getLogger(PreParser.class.getName());

  public void setEventHandler(LoaderHandler handler) 
  {
    this.listener = (UMLHandler) handler;
//     if (progressListener != null) {
//       listener.addProgressListener(progressListener);
//     }
  }

  /**
   * main parse method.
   *
   * @param filename a <code>String</code> value
   */
  public void parse(String filename) throws ParserException 
  {
    try {
      
      long start = System.currentTimeMillis();
      
      listener.beginParsing();
        
      XmiInOutHandler handler = XmiHandlerFactory.getXmiHandler(HandlerEnum.EADefault);

      String s = filename.replaceAll("\\ ", "%20");

      // Some file systems use absolute URIs that do 
      // not start with '/'. 
      if(!s.startsWith("/"))
        s = "/" + s;    
      java.net.URI uri = new java.net.URI("file://" + s);
      logger.debug("pre parsing ...");
      handler.load(uri);
      logger.debug("done pre parsing.");

      UMLModel model = handler.getModel("EA Model");

      // save in memory for fast-save
      UserSelections.getInstance().setProperty("XMI_HANDLER", handler);

      for(UMLPackage pkg : model.getPackages()) {
        doPackage(pkg);
      }

    } catch (Exception e) {
      throw new ParserException(e);
    } // end of try-catch

  }

  private void doPackage(UMLPackage pack) 
  {
    UMLDefaults defaults = UMLDefaults.getInstance();
    
    if (packageName.length() == 0) {
      packageName = pack.getName();
    }
    else {
      packageName += ("." + pack.getName());
    }

    listener.newPackage(new NewPackageEvent(packageName));

    for(UMLPackage subPkg : pack.getPackages()) {
      String oldPackage = packageName;
      doPackage(subPkg);
      packageName = oldPackage;
    }

    for(UMLClass clazz : pack.getClasses()) {
      doClass(clazz);
    }

    packageName = "";
  }

  private void doClass(UMLClass clazz) 
  {
    String pName = getPackageName(clazz.getPackage());

    String className = clazz.getName();

//     if (pName != null) {
//       className = pName + "." + className;
//     }

    NewClassEvent event = new NewClassEvent(className.trim());
    event.setPackageName(pName);

    listener.newClass(event);
  }



  private String getPackageName(UMLPackage pkg) {
    StringBuffer pack = new StringBuffer();
    String s = null;
    do {
      s = null;
      if(pkg != null) {
        s = pkg.getName(); 
        if(s.indexOf(" ") == -1) {
          if(pack.length() > 0)
            pack.insert(0, '.');
          pack.insert(0, s);
        }
        pkg = pkg.getParent();
      }
    } while (s != null);
    
    return pack.toString();
  }

  public void addProgressListener(ProgressListener listener) 
  {

  }

  private void fireProgressEvent(ProgressEvent evt) {
    if(progressListener != null)
      progressListener.newProgressEvent(evt);
  }


}


@@ -1305,146 +1305,185 @@
    %0A
+%0A
       
-XmiInOutHandler handler = XmiHandlerFactory.getXmiHandler(HandlerEnum.EADefault);%0A%0A      String s = filename.replaceAll(%22%5C%5C %22, %22%2520%22
+String s = filename.replaceAll(%22%5C%5C %22, %22%2520%22);%0A%0A      String ext = null;%0A      if(filename.indexOf(%22.%22) %3E 0)%0A        ext = filename.substring(filename.lastIndexOf(%22.%22) + 1
 );%0A%0A
@@ -1674,24 +1674,303 @@
 e://%22 + s);%0A
+%0A%0A      HandlerEnum handlerEnum = null;%0A      if(ext != null && ext.equals(%22uml%22)) %0A        handlerEnum = HandlerEnum.ArgoUMLDefault;%0A      else%0A        handlerEnum = HandlerEnum.EADefault;%0A%0A      XmiInOutHandler handler = XmiHandlerFactory.getXmiHandler(HandlerEnum.EADefault);%0A
       logger
@@ -2059,24 +2059,25 @@
 arsing.%22);%0A%0A
+%0A
       UMLMod
@@ -2108,131 +2108,519 @@
 del(
-%22EA Model%22);%0A%0A      // save in memory for fast-save%0A      UserSelections.getInstance().setProperty(%22XMI_HANDLER%22, handler);
+);%0A%0A      if(model == null) %7B%0A        throw new Exception(%22Can't open file. Unknown format.%22);%0A      %7D %0A%0A      // save in memory for fast-save%0A      UserSelections userSelections = UserSelections.getInstance();%0A      userSelections.getInstance().setProperty(%22XMI_HANDLER%22, handler);%0A      if(handlerEnum == HandlerEnum.ArgoUMLDefault) %7B%0A        userSelections.setProperty(%22FILE_TYPE%22, %22ARGO%22);%0A      %7D else if(handlerEnum == HandlerEnum.EADefault)%7B%0A        userSelections.setProperty(%22FILE_TYPE%22, %22EA%22);%0A      %7D
 %0A%0A  

support for Argo