package com.chenyang.druid.sql.ast;

import com.chenyang.druid.sql.visitor.SQLASTVisitor;

public class SQLAnnIndex extends SQLObjectImpl {
   private int indexType;
   private int rtIndexType;
   private Distance distance;

   public SQLAnnIndex clone() {
      SQLAnnIndex x = new SQLAnnIndex();
      x.indexType = this.indexType;
      x.rtIndexType = this.rtIndexType;
      x.distance = this.distance;
      return x;
   }

   protected void accept0(SQLASTVisitor v) {
      if (v.visit(this)) {
      }

      v.endVisit(this);
   }

   public void setIndexType(String type) {
      this.indexType = IndexType.of(type);
   }

   public void setIndexType(IndexType indexType, boolean state) {
      if (state) {
         this.indexType |= indexType.mask;
      } else {
         this.indexType &= ~indexType.mask;
      }

   }

   public void setRtIndexType(IndexType indexType, boolean state) {
      if (state) {
         this.rtIndexType |= indexType.mask;
      } else {
         this.rtIndexType &= ~indexType.mask;
      }

   }

   public void setRtIndexType(String type) {
      this.rtIndexType = IndexType.of(type);
   }

   public int getIndexType() {
      return this.indexType;
   }

   public int getRtIndexType() {
      return this.rtIndexType;
   }

   public Distance getDistance() {
      return this.distance;
   }

   public void setDistance(Distance distance) {
      this.distance = distance;
   }

   public void setDistance(String distance) {
      if (distance == null) {
         this.distance = null;
      } else {
         if (distance.equalsIgnoreCase("Hamming")) {
            this.distance = Distance.Hamming;
         } else if (distance.equalsIgnoreCase("SquaredEuclidean")) {
            this.distance = Distance.SquaredEuclidean;
         } else if (distance.equalsIgnoreCase("DotProduct")) {
            this.distance = Distance.DotProduct;
         }

      }
   }

   public static enum IndexType {
      Flat(1),
      FastIndex(2);

      public final int mask;

      private IndexType(int ordinal) {
         this.mask = 1 << ordinal;
      }

      private static int of(String type) {
         if (type != null && type.length() != 0) {
            int v = 0;
            String[] items = type.split(",");

            for(String item : items) {
               if (item.trim().equalsIgnoreCase("Flat")) {
                  v |= Flat.mask;
               } else if (item.trim().equalsIgnoreCase("FastIndex") || item.trim().equalsIgnoreCase("FAST_INDEX")) {
                  v |= FastIndex.mask;
               }
            }

            return v;
         } else {
            return 0;
         }
      }
   }

   public static enum Distance {
      Hamming,
      SquaredEuclidean,
      DotProduct;
   }
}
