import { getHumanReadableName, getSymbol, symbolDict, symbolDictIterator, symbolFunction, symbolList, symbolProduct, symbolSet, symbolSetIterator, symbolSum } from "dope2";

import "./Type.css";

export function Type({type}) {
  const symbol = getSymbol(type);
  switch (symbol) {
    case symbolFunction:
      return <BinaryType type={type} cssClass="functionType" infix="&rarr;" prefix="" suffix=""/>;
    case symbolProduct:
      return <BinaryType type={type} cssClass="productType" infix="&#10799;" prefix="" suffix=""/>;
    case symbolSum:
      return <BinaryType type={type} cssClass="sumType" infix="+" prefix="" suffix=""/>;
    case symbolDict:
      return <BinaryType type={type} cssClass="dictType" infix="&rArr;" prefix="{" suffix="}"/>;
    case symbolSet:
      return <UnaryType type={type} cssClass="setType" prefix="{" suffix="}" />;
    case symbolList:
      return <UnaryType type={type} cssClass="listType" prefix="[" suffix="]" />;
    case symbolSetIterator:
      return <UnaryType type={type} cssClass="setType iteratorType" prefix="{*" suffix="}" />;
    case symbolDictIterator:
      return <BinaryType type={type} cssClass="dictType iteratorType" infix="*&rArr;" prefix="{" suffix="}"/>;
  
    default:
      return <div className="type">{getHumanReadableName(symbol)}</div>
  }
}

function BinaryType({type, cssClass, infix, prefix, suffix}) {
  return <div className={`type ${cssClass}`}>
    {prefix}
    <Type type={type.params[0](type)}/>
    <span className="infix">{infix}</span>
    <Type type={type.params[1](type)}/>
    {suffix}
  </div>
}

function UnaryType({type, cssClass, prefix, suffix}) {
  return <div className={`type ${cssClass}`}>
    {prefix}
    <Type type={type.params[0](type)}/>
    {suffix}
  </div>
}