/**
  *
  *                      OOAS Compiler
  *
  *       Copyright 2015, AIT Austrian Institute of Technology.
  * This code is based on the C# Version of the OOAS Compiler, which is
  * copyright 2015 by the Institute of Software Technology, Graz University
  * of Technology with portions copyright by the AIT Austrian Institute of
  * Technology. All rights reserved.
  *
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
  *
  * If you modify the file please update the list of contributors below to in-
  * clude your name. Please also stick to the coding convention of using TABs
  * to do the basic (block-level) indentation and spaces for anything after
  * that. (Enable the display of special chars and it should be pretty obvious
  * what this means.) Also, remove all trailing whitespace.
  *
  * Contributors:
  *               Willibald Krenn (AIT)
  *               Stephan Zimmerer (AIT)
  *               Markus Demetz (AIT)
  *               Christoph Czurda (AIT)
  *
  */


package org.momut.ooas.codegen.prologsymbolic;

import java.util.Date;

import org.momut.ooas.ast.identifiers.MainModule;
import org.momut.ooas.codegen.prolog.OoaPrologIdentifier;
import org.momut.ooas.codegen.prolog.OoaPrologVisitor;
import org.momut.ooas.parser.ParserState;

public final class OoaPrologSymbolicVisitor extends OoaPrologVisitor
{
	@Override
	public  void visit(MainModule mainModule)
	{
		m_emitter.AppendLine("% OOAS Compiler Generated");
//		m_emitter.AppendLine("%" + Mogentes.Program.GetProgramVersion().ToString().Replace(Environment.NewLine, Environment.NewLine + "%")));
		m_emitter.AppendLine("% Code-Gen Version: 0.3 symbolic");
		m_emitter.Append("%        Generated: "); m_emitter.AppendLine(new Date().toString());
		m_emitter.AppendLine("%------------------------------------------------------------------------");
		m_emitter.AppendLine("");
		m_emitter.AppendLine(String.format(":- module(%s, [var/2, input/1, searchDepth/1, qspace/2]).", m_nameSpace));
		m_emitter.AppendLine(":- use_module(library(file_systems)).");
		m_emitter.AppendLine(":- use_module(library(process)).");
		m_emitter.AppendLine(":- use_module(library(clpfd)).");
		m_emitter.AppendLine(":- use_module(library(clpb)).");
		m_emitter.AppendLine(":- use_module(library(lists)).");
		m_emitter.AppendLine(":- use_module(library(avl)).");
		m_emitter.AppendLine(":- use_module(library(ordsets)).");
		m_emitter.AppendLine(":- use_module(library(system)).");
//		m_emitter.AppendLine(":- use_module(library(gauge)).");
		m_emitter.AppendLine(":- use_module(library(terms)).");
		m_emitter.AppendLine(":- use_module(library(sets)).");
		m_emitter.AppendLine(":- use_module(library(random)).");

		m_emitter.AppendLine(":- public(as/0).");
		m_emitter.AppendLine(":- dynamic(as/0).");
		m_emitter.AppendLine(":- dynamic(qstate_init/1).");
		m_emitter.AppendLine(":- dynamic(qstate_constraints/1).");
		m_emitter.AppendLine(":- public(qstate_init/1).");
		m_emitter.AppendLine(":- public(qstate_constraints/1).");
		m_emitter.AppendLine(":- dynamic(type/2).");

		/*definition of search depth*/
		m_emitter.AppendLine("");
		m_emitter.AppendLine("% maximal search depth (change at will)");
		m_emitter.AppendLine(String.format("searchDepth(%s).", m_maxSearchDepth));
		m_emitter.AppendLine("");

		/*definition of types*/
		ExportTypes(mainModule);
		/* variable definition */
		ExportVariables(mainModule);

		/* state definition */
		ExportState(mainModule);
		/* initial state */
		ExportInitialState(mainModule);
		/* input actions (controllables) */
		ExportControllableActions(mainModule);
		/* output actions (observables) */
		ExportObservableActions(mainModule);
		/* named actions */
		ExportMethodsAndActions(mainModule);

		/* all types */
		m_emitter.AppendLine("%definition of types");
		m_emitter.AppendLine(m_scratchbook.typeDefinitions().toString());
		m_emitter.AppendLine(createTypeVisitor().GetInternalTypeDefinitions());
	}


	public OoaPrologSymbolicVisitor(ParserState aState, int maxSearchDepth, String nameSpace )
	{
		super(aState,
			maxSearchDepth,
			nameSpace,
			new OoaPrologSymbolicExpression.Factory(),
			new OoaPrologIdentifier.Factory(),
			new OoaPrologSymbolicStatement.Factory(),
			new OoaPrologSymbolicType.Factory());
	}
}
