import imgNote from "./noteSmall.png";
import imgWatch from "./watch.png";
import digitalFont from "./digital-font.ttf";
import { Plant } from "../Plant";
import { RaisedEvent } from "@/statecharts/runtime_types";

type DigitalWatchState = {
  light: boolean;
  h: number;
  m: number;
  s: number;
  alarm: boolean;
}

type DigitalWatchProps = DigitalWatchState & {
  callbacks: {
    onTopLeftPressed: () => void;
    onTopRightPressed: () => void;
    onBottomRightPressed: () => void;
    onBottomLeftPressed: () => void;
    onTopLeftReleased: () => void;
    onTopRightReleased: () => void;
    onBottomRightReleased: () => void;
    onBottomLeftReleased: () => void;
  },
}

export function DigitalWatch({light, h, m, s, alarm, callbacks}: DigitalWatchProps) {
  const twoDigits = (n: number) => n < 0 ? "  " : ("0"+n.toString()).slice(-2);
  const hhmmss = `${twoDigits(h)}:${twoDigits(m)}:${twoDigits(s)}`;

  return <>
    <style>{`
      @font-face{
        font-family: 'digital-font';
        src: url(${digitalFont});
      }
    `}</style>
    <svg version="1.1" width="222" height="236" style={{userSelect: 'none'}}>
      <image width="222" height="236" xlinkHref={imgWatch}/>

      {light &&
        <rect x={52} y={98} width={120} height={52} fill="#deeaffff" rx={5} ry={5} />}

      <text x="111" y="126" dominantBaseline="middle" textAnchor="middle" fontFamily="digital-font" fontSize={28} style={{whiteSpace:'preserve'}}>{hhmmss}</text>
    
      <rect x="0" y="59" width="16" height="16" fill="#fff" fillOpacity="0" 
        onMouseDown={() => callbacks.onTopLeftPressed()}
        onMouseUp={() => callbacks.onTopLeftReleased()}
      />
      <rect x="206" y="57" width="16" height="16" fill="#fff" fillOpacity="0"
        onMouseDown={() => callbacks.onTopRightPressed()}
        onMouseUp={() => callbacks.onTopRightReleased()}
      />
      <rect x="0" y="158" width="16" height="16" fill="#fff" fillOpacity="0"
        onMouseDown={() => callbacks.onBottomLeftPressed()}
        onMouseUp={() => callbacks.onBottomLeftReleased()}
      />
      <rect x="208" y="158" width="16" height="16" fill="#fff" fillOpacity="0"
        onMouseDown={() => callbacks.onBottomRightPressed()}
        onMouseUp={() => callbacks.onBottomRightReleased()}
      />

      {alarm &&
        <image x="54" y="98" xlinkHref={imgNote} />
      }
    </svg>
  </>;
}

export const DigitalWatchPlant: Plant<DigitalWatchProps> = {
  inputEvents: [
    { kind: "event", event: "setH", paramName: 'h' },
    { kind: "event", event: "setM", paramName: 'm' },
    { kind: "event", event: "setS", paramName: 's' },
    { kind: "event", event: "setLight", paramName: 'lightOn'},
    { kind: "event", event: "setAlarm", paramName: 'alarmOn'},
  ],
  outputEvents: [
    { kind: "event", event: "topLeftPressed" },
    { kind: "event", event: "topRightPressed" },
    { kind: "event", event: "bottomRightPressed" },
    { kind: "event", event: "bottomLeftPressed" },
    { kind: "event", event: "topLeftReleased" },
    { kind: "event", event: "topRightReleased" },
    { kind: "event", event: "bottomRightReleased" },
    { kind: "event", event: "bottomLeftReleased" },
  ],
  initial: (raise: (event: RaisedEvent) => void) => ({
    light: false,
    alarm: false,
    h: 12,
    m: 0,
    s: 0,
    callbacks: {
      onTopLeftPressed: () => raise({ name: "topLeftPressed" }),
      onTopRightPressed: () => raise({ name: "topRightPressed" }),
      onBottomRightPressed: () => raise({ name: "bottomRightPressed" }),
      onBottomLeftPressed: () => raise({ name: "bottomLeftPressed" }),
      onTopLeftReleased: () => raise({ name: "topLeftReleased" }),
      onTopRightReleased: () => raise({ name: "topRightReleased" }),
      onBottomRightReleased: () => raise({ name: "bottomRightReleased" }),
      onBottomLeftReleased: () => raise({ name: "bottomLeftReleased" }),
    },
  }),
  reducer: (inputEvent: RaisedEvent, state: DigitalWatchProps) => {
    if (inputEvent.name === "setH") {
      return { ...state, h: inputEvent.param };
    }
    if (inputEvent.name === "setM") {
      return { ...state, m: inputEvent.param };
    }
    if (inputEvent.name === "setS") {
      return { ...state, s: inputEvent.param };
    }
    if (inputEvent.name === "lightOn") {
      return { ...state, light: true };
    }
    if (inputEvent.name === "lightOff") {
      return { ...state, light: false };
    }
    if (inputEvent.name === "setAlarm") {
      return { ...state, alarm: true };
    }
    if (inputEvent.name === "unsetAlarm") {
      return { ...state, alarm: false };
    }
    return state; // unknown event - ignore it
  },
  render: DigitalWatch,
}
