package com.chenyang.druid.sql.ast.expr;

import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLExprImpl;
import com.chenyang.druid.sql.ast.SQLObject;
import com.chenyang.druid.sql.ast.SQLReplaceable;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;

public class SQLMatchAgainstExpr extends SQLExprImpl implements SQLReplaceable {
   private List<SQLExpr> columns = new ArrayList();
   private SQLExpr against;
   private SearchModifier searchModifier;

   public SQLMatchAgainstExpr clone() {
      SQLMatchAgainstExpr x = new SQLMatchAgainstExpr();

      for(SQLExpr column : this.columns) {
         SQLExpr column2 = column.clone();
         column2.setParent(x);
         x.columns.add(column2);
      }

      if (this.against != null) {
         x.setAgainst(this.against.clone());
      }

      x.searchModifier = this.searchModifier;
      return x;
   }

   public boolean replace(SQLExpr expr, SQLExpr target) {
      if (this.against == expr) {
         this.setAgainst(target);
         return true;
      } else {
         for(int i = 0; i < this.columns.size(); ++i) {
            if (this.columns.get(i) == expr) {
               target.setParent(this);
               this.columns.set(i, target);
               return true;
            }
         }

         return false;
      }
   }

   public List<SQLExpr> getColumns() {
      return this.columns;
   }

   public void setColumns(List<SQLExpr> columns) {
      this.columns = columns;
   }

   public SQLExpr getAgainst() {
      return this.against;
   }

   public void setAgainst(SQLExpr against) {
      if (against != null) {
         against.setParent(this);
      }

      this.against = against;
   }

   public SearchModifier getSearchModifier() {
      return this.searchModifier;
   }

   public void setSearchModifier(SearchModifier searchModifier) {
      this.searchModifier = searchModifier;
   }

   protected void accept0(SQLASTVisitor v) {
      if (v.visit(this)) {
         if (this.columns != null) {
            for(SQLExpr column : this.columns) {
               if (column != null) {
                  column.accept(v);
               }
            }
         }

         if (this.against != null) {
            this.against.accept(v);
         }
      }

      v.endVisit(this);
   }

   public List getChildren() {
      List<SQLObject> children = new ArrayList();
      children.addAll(this.columns);
      children.add(this.against);
      return children;
   }

   public int hashCode() {
      int prime = 31;
      int result = 1;
      result = 31 * result + (this.against == null ? 0 : this.against.hashCode());
      result = 31 * result + (this.columns == null ? 0 : this.columns.hashCode());
      result = 31 * result + (this.searchModifier == null ? 0 : this.searchModifier.hashCode());
      return result;
   }

   public boolean equals(Object obj) {
      if (this == obj) {
         return true;
      } else if (obj == null) {
         return false;
      } else if (this.getClass() != obj.getClass()) {
         return false;
      } else {
         SQLMatchAgainstExpr other = (SQLMatchAgainstExpr)obj;
         if (this.against == null) {
            if (other.against != null) {
               return false;
            }
         } else if (!this.against.equals(other.against)) {
            return false;
         }

         if (this.columns == null) {
            if (other.columns != null) {
               return false;
            }
         } else if (!this.columns.equals(other.columns)) {
            return false;
         }

         return this.searchModifier == other.searchModifier;
      }
   }

   public static enum SearchModifier {
      IN_BOOLEAN_MODE("IN BOOLEAN MODE"),
      IN_NATURAL_LANGUAGE_MODE("IN NATURAL LANGUAGE MODE"),
      IN_NATURAL_LANGUAGE_MODE_WITH_QUERY_EXPANSION("IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION"),
      WITH_QUERY_EXPANSION("WITH QUERY EXPANSION");

      public final String name;
      public final String name_lcase;

      private SearchModifier() {
         this(null);
      }

      private SearchModifier(String name) {
         this.name = name;
         this.name_lcase = name.toLowerCase();
      }
   }
}
