
import uk.ac.ic.doc.automed.*;
import uk.ac.ic.doc.automed.reps.*;
import java.sql.SQLException;
import java.io.IOException;


/**
	An application that defines the graphical representation of the SQL92 model. The
	application re-defines the SQL92 model if it doesn't exist.
	model: "sql92"
	constructs: "table", "field", "primary_key", "foreign_key" 
*/
public class DefineSQL92GraphicalRepresentation implements Constants
{
  private static boolean minimal=true;
  private static String modelName="sql92";
  private static String tableConstructName="table";
  private static String fieldConstructName="field";
  private static String primaryKeyConstructName="primary_key";
  private static String foreignKeyConstructName="foreign_key";
  private static String indexConstructName="index";
 
	public static void createSQL92inMDR()
		throws AutoMedException, SQLException, IOException, InconsistentException
	{
	// Zap any existing model called modelName
    if (Model.exists(modelName)) {
      System.out.println("Removed old "+modelName+" modelling language");
      Model.getModel(modelName).retract();
    }

    Model rel=Model.createModel(modelName); 

    // TABLE
    Construct table=
      rel.createConstruct(tableConstructName,
			  Construct.CLASS_NODAL,
			  true);
    table.addNodeNameScheme();
			       
    // FIELD
    Construct field=
      rel.createConstruct(fieldConstructName,
			  Construct.CLASS_LINK_NODAL,
			  true);
    field.addReferenceScheme(table);
    field.addEdgeNameScheme();
    if (!minimal) {
      field.addLabelScheme(); // To hold null or notnull
      field.addLabelScheme(); // To hold datatype: int,string,...
      field.addLabelScheme(); // To hold datatype size:  length of string,...
      field.addLabelScheme(); // To hold position in table: 1,2,3,...
    }

    // PRIMARY KEY
    Construct primary_key=
      rel.createConstruct(primaryKeyConstructName,
			  Construct.CLASS_CONSTRAINT,
			  true);
    primary_key.addLabelScheme(1, 1, true);
    primary_key.addReferenceScheme(table, 1, 1, true);
    primary_key.addReferenceScheme(field, 1, 0, true);

    // INDEX
    if (!minimal) {
      Construct index=
	rel.createConstruct(indexConstructName,
			    Construct.CLASS_CONSTRAINT,
			    true);
      index.addLabelScheme(1, 1, true); // Name of index
      index.addLabelScheme(1, 1, true); // unique or non_unique
      index.addLabelScheme(1, 1, true); // asc or desc
      index.addReferenceScheme(field, 1, 0, true);
    }

    // FOREIGN KEY
    Construct foreign_key=
      rel.createConstruct(foreignKeyConstructName,
			  Construct.CLASS_CONSTRAINT,
			  true);
    foreign_key.addLabelScheme(1, 1, true);
    foreign_key.addReferenceScheme(table, 1, 1, true);
    foreign_key.addReferenceScheme(field, 1, 0, true);
    foreign_key.addReferenceScheme(table, 1, 1, true);
    foreign_key.addReferenceScheme(field, 1, 0, true);
	}


	public static void createSQL92inSMR()
		throws AutoMedException, SchemaModelingRepositoryException
	{
		// create modeling statements
		ModelingStatement this_getValue = new ModelingStatement("this.getValue");
		ModelingStatement this_getLocation = new ModelingStatement("this.getLocation");
		ModelingStatement this_getManager = new ModelingStatement("this.getManager");
		ModelingStatement getLocation = new ModelingStatement("getLocation");
		ModelingStatement getGraphics = new ModelingStatement("getGraphics");
		ModelingStatement setGraphics = new ModelingStatement("setGraphics");
		ModelingStatement setShapeLocation = new ModelingStatement("setShapeLocation");
		ModelingStatement setText = new ModelingStatement("setText");
		ModelingStatement this_setShape = new ModelingStatement("this.setShape");
		ModelingStatement draw = new ModelingStatement("draw");
		ModelingStatement box = new ModelingStatement("uk.ac.ic.doc.automed.gui.SchemaManager.createBox");
		ModelingStatement line = new ModelingStatement("uk.ac.ic.doc.automed.gui.SchemaManager.createLine");
		ModelingStatement line_n = new ModelingStatement("uk.ac.ic.doc.automed.gui.SchemaManager.createLine -n");
		ModelingStatement rhombus = new ModelingStatement("uk.ac.ic.doc.automed.gui.SchemaManager.createRhombus");
		ModelingStatement this_getReferencedConstruct = new ModelingStatement("this.getReferencedConstruct");	
		ModelingStatement this_getReferencedConstructs= new ModelingStatement("this.getReferencedConstructs");	

		ModelingStatement this_getReferencedTable = new ModelingStatement("this.getReferencedTable");
		ModelingStatement this_getReferencedField = new ModelingStatement("this.getReferencedField");
		ModelingStatement getGraphicObject = new ModelingStatement("getGraphicObject");	
		ModelingStatement getGraphicObject_n = new ModelingStatement("getGraphicObject -n");	
		ModelingStatement getEdgePosition_n = new ModelingStatement("getEdgePosition -n");	
		ModelingStatement getShape = new ModelingStatement("getShape");
		ModelingStatement this_getShape = new ModelingStatement("this.getShape");
		ModelingStatement setPoint1 = new ModelingStatement("setPoint1");
		ModelingStatement setPoint1_n = new ModelingStatement("setPoint1 -n");
		ModelingStatement setPoint2 = new ModelingStatement("setPoint2");
		ModelingStatement setPoint2_n = new ModelingStatement("setPoint2 -n");
		ModelingStatement this_getSpecialConstructs = new ModelingStatement("this.getSpecialConstructs");
		ModelingStatement getGenEdgePosition = new ModelingStatement("getGenEdgePosition");
		ModelingStatement getEdgePosition = new ModelingStatement("getEdgePosition");
		ModelingStatement getSpecEdgePosition = new ModelingStatement("getSpecEdgePosition");

		ModelingStatement createArc = new ModelingStatement("uk.ac.ic.doc.automed.gui.SchemaManager.createArc");


		//create modeling programs for each relational construct
		ModelingProgram tableModeling = new ModelingProgram();
		tableModeling.add(this_getValue);
		tableModeling.add(this_getLocation);
		tableModeling.add(this_getManager);
		tableModeling.add(getGraphics);
		tableModeling.add(box);
		tableModeling.add(setGraphics);
		tableModeling.add(setShapeLocation);
		tableModeling.add(setText);
		tableModeling.add(this_setShape);
		tableModeling.add(draw);
		
		ModelingProgram fieldModeling = new ModelingProgram();
		fieldModeling.add(this_getValue);
		fieldModeling.add(this_getLocation);
		fieldModeling.add(this_getManager);
		fieldModeling.add(getGraphics);
		fieldModeling.add(createArc);
		fieldModeling.add(setGraphics);
		fieldModeling.add(setShapeLocation);
		fieldModeling.add(setText);
		fieldModeling.add(this_setShape);
		fieldModeling.add(this_getLocation);
		fieldModeling.add(this_getReferencedConstruct);
		fieldModeling.add(this_getManager);
		fieldModeling.add(getGraphicObject);
		fieldModeling.add(getShape);
		fieldModeling.add(getEdgePosition);
		fieldModeling.add(this_getLocation);
		fieldModeling.add(this_getReferencedConstruct);
		fieldModeling.add(this_getManager);
		fieldModeling.add(getGraphicObject);
		fieldModeling.add(getShape);
		fieldModeling.add(getEdgePosition);
		fieldModeling.add(this_getShape);
		fieldModeling.add(getEdgePosition);
		fieldModeling.add(this_getShape);
		fieldModeling.add(draw);
		fieldModeling.add(this_getManager);
		fieldModeling.add(getGraphics);
		fieldModeling.add(line);
		fieldModeling.add(setGraphics);
		fieldModeling.add(setPoint1);
		fieldModeling.add(setPoint2);
		fieldModeling.add(draw);
		
		ModelingProgram fkModeling = new ModelingProgram();
		fkModeling.add(new ModelingStatement("this.isPrimaryKeyForeignKey"));
		fkModeling.add(this_getManager);
		fkModeling.add(new ModelingStatement("getExtend"));
		fkModeling.add(this_getValue);
		fkModeling.add(this_getLocation);
		fkModeling.add(this_getManager);
		fkModeling.add(getGraphics);
		fkModeling.add(rhombus);
		fkModeling.add(setGraphics);
		fkModeling.add(setShapeLocation);
		fkModeling.add(setText);
		fkModeling.add(new ModelingStatement("setExtend"));
		fkModeling.add(this_setShape);
		fkModeling.add(draw);
	
		fkModeling.add(this_getShape);
		fkModeling.add(getGenEdgePosition);
		fkModeling.add(new ModelingStatement("this.getTableForeignKeyPoints"));
		fkModeling.add(this_getManager);
		fkModeling.add(getGraphicObject);
		fkModeling.add(getShape);
		fkModeling.add(getEdgePosition);
		fkModeling.add(this_getShape);
		fkModeling.add(getGenEdgePosition);
		fkModeling.add(this_getManager);
		fkModeling.add(getGraphics);
		fkModeling.add(line);
		fkModeling.add(setGraphics);
		fkModeling.add(setPoint1);
		fkModeling.add(setPoint2);
		fkModeling.add(draw);
		
		fkModeling.add(this_getShape);
		fkModeling.add(getSpecEdgePosition);
		fkModeling.add(new ModelingStatement("this.getTableWithForeignKey"));
		fkModeling.add(this_getManager);
		fkModeling.add(getGraphicObject);
		fkModeling.add(getShape);
		fkModeling.add(getEdgePosition);
		fkModeling.add(this_getShape);
		fkModeling.add(getSpecEdgePosition);
		fkModeling.add(this_getManager);
		fkModeling.add(getGraphics);
		fkModeling.add(line);
		fkModeling.add(setGraphics);
		fkModeling.add(setPoint1);
		fkModeling.add(setPoint2);
		fkModeling.add(draw);


		ModelingProgram pkModeling = new ModelingProgram();
		pkModeling.add(this_getReferencedField);
		pkModeling.add(this_getManager);
		pkModeling.add(getGraphicObject);
		pkModeling.add(getLocation); //location of field
	
		pkModeling.add(this_getReferencedTable);
		pkModeling.add(this_getManager);
		pkModeling.add(getGraphicObject);
		pkModeling.add(getShape);
		pkModeling.add(getEdgePosition); //edge position of table based on field's position	

		//re-get table's edge pos
		pkModeling.add(this_getReferencedField);
		pkModeling.add(this_getManager);
		pkModeling.add(getGraphicObject);
		pkModeling.add(getLocation); //location of field
	
		pkModeling.add(this_getReferencedTable);
		pkModeling.add(this_getManager);
		pkModeling.add(getGraphicObject);
		pkModeling.add(getShape);
		pkModeling.add(getEdgePosition); //edge position of table based on field's position	

		//and now get edgw pos of field
		pkModeling.add(this_getReferencedField);
		pkModeling.add(this_getManager);
		pkModeling.add(getGraphicObject);
		pkModeling.add(getShape);
		pkModeling.add(getEdgePosition); //edge position of field based on table's edge pos
		
		pkModeling.add(this_getValue);
		pkModeling.add(this_getManager);
		pkModeling.add(getGraphics);
		pkModeling.add(line);
		pkModeling.add(setGraphics);
		pkModeling.add(setText);
		pkModeling.add(setPoint1);
		pkModeling.add(setPoint2);
		pkModeling.add(draw);


		Model rel = Model.getModel(modelName);
		ConstructWithModelingProgram table = (ConstructWithModelingProgram)rel.getConstruct(tableConstructName);
		ConstructWithModelingProgram field = (ConstructWithModelingProgram)rel.getConstruct(fieldConstructName);
		ConstructWithModelingProgram pk = (ConstructWithModelingProgram)rel.getConstruct(primaryKeyConstructName);
		ConstructWithModelingProgram fk = (ConstructWithModelingProgram)rel.getConstruct(foreignKeyConstructName);

		table.removeModelingProgram();
		field.removeModelingProgram();
		pk.removeModelingProgram();
		fk.removeModelingProgram();

		table.setModelingProgram(tableModeling);
		field.setModelingProgram(fieldModeling);
		pk.setModelingProgram(pkModeling);
		fk.setModelingProgram(fkModeling);
	}

	public static void main(String[] args){
		try{
			if(!Model.exists("sql92")){
				System.out.println("Re-defining the SQL92 model...");
				DefineSQL92GraphicalRepresentation.createSQL92inMDR();
			}
			System.out.println("Defining the SQL92 model's graphical representation...");
			DefineSQL92GraphicalRepresentation.createSQL92inSMR();
		}
		catch(InconsistentException aie){
			aie.printStackTrace();
		}	
		catch(Exception e){
			e.printStackTrace();
		}
	}
} 
 
