/*
 * ChannelDeclChecker.java
 *
 * Created on 1 de Julho de 2005, 09:08
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package net.sourceforge.czt.typecheck.circus.util;

import java.util.List;
import net.sourceforge.czt.typecheck.z.impl.UnknownType;
import net.sourceforge.czt.typecheck.z.impl.UnknownTypeVisitor;
import net.sourceforge.czt.typecheck.z.impl.VariableType;
import net.sourceforge.czt.typecheck.z.impl.VariableTypeVisitor;

import static net.sourceforge.czt.typecheck.circus.util.GlobalDefs.*;

import net.sourceforge.czt.z.ast.DeclName;
import net.sourceforge.czt.z.ast.GenParamType;
import net.sourceforge.czt.z.ast.PowerType;
import net.sourceforge.czt.z.ast.ProdType;
import net.sourceforge.czt.z.ast.GivenType;
import net.sourceforge.czt.z.ast.SchemaType;
import net.sourceforge.czt.z.ast.Type2;
import net.sourceforge.czt.z.visitor.GenParamTypeVisitor;
import net.sourceforge.czt.z.visitor.GivenTypeVisitor;
import net.sourceforge.czt.z.visitor.PowerTypeVisitor;
import net.sourceforge.czt.z.visitor.ProdTypeVisitor;
import net.sourceforge.czt.z.visitor.SchemaTypeVisitor;
import net.sourceforge.czt.z.visitor.Type2Visitor;
import net.sourceforge.czt.typecheck.circus.*;

/**
 * Visitor que irá checar se as declarações de um canal referenciam parâmetros
 * genéricos.
 *
 * @author Manuela
 */
public class ChannelDeclChecker 
  extends Checker
  implements Type2Visitor,
             SchemaTypeVisitor,
             PowerTypeVisitor,
             GivenTypeVisitor,
             GenParamTypeVisitor,
             ProdTypeVisitor,
             VariableTypeVisitor,
             UnknownTypeVisitor
{
  
  /** Creates a new instance of ChannelDeclChecker */
  public ChannelDeclChecker(TypeChecker typeChecker)
  {
    super(typeChecker);
  }

  public Object visitType2(Type2 type){
    return type.accept(channelDeclChecker());
  }
  
  public Object visitSchemaType(SchemaType type){
    return new Boolean(false);
  }

  public Object visitPowerType(PowerType type){
    return type.getType().accept(channelDeclChecker());
  }

  public Object visitGivenType(GivenType type){
    boolean res = false;
    DeclName nameType = type.getName();
    List<DeclName> params = currentGenParams();
    
    for(DeclName paramName : params) {
      if(compareDeclName(paramName, nameType, false)) {
        res = true;
        break;
      }
    }
    
    return new Boolean(res);
  }

  public Object visitGenParamType(GenParamType type){
    boolean res = false;
    DeclName nameType = type.getName();
    List<DeclName> params = currentGenParams();
    
    for(DeclName paramName : params) {
      if(compareDeclName(paramName, nameType, false)) {
        res = true;
        break;
      }
    }
    
    return new Boolean(res);
  }

  public Object visitProdType(ProdType type){
    boolean res = false;
    List<Type2> prodTypes = type.getType();
   
    for(Type2 prodType : prodTypes) {
      if(((Boolean)prodType.accept(channelDeclChecker())).booleanValue()){
        res = true;
        break;
      }
    }
    
    return new Boolean(res);
  }

  public Object visitVariableType(VariableType type){
    return type.getValue().accept(channelDeclChecker());
  }

  public Object visitUnknownType(UnknownType type){
    return new Boolean(false);
  }
}
