+import React from 'react';
+import { Helmet } from 'react-helmet';
+
+import ZeldaIcon from '../components/common/ZeldaIcon';
+
+const DUNGEONS = [
+ 'hc',
+ 'ct',
+ 'ep',
+ 'dp',
+ 'th',
+ 'pd',
+ 'sp',
+ 'sw',
+ 'tt',
+ 'ip',
+ 'mm',
+ 'tr',
+ 'gt',
+];
+
+const ITEMS = [
+ 'compass',
+ 'map',
+ 'big-key',
+ 'bow',
+ 'hookshot',
+ 'fire-rod',
+ 'lamp',
+ 'hammer',
+ 'somaria',
+ 'fighter-sword',
+ 'boots',
+ 'glove',
+ 'flippers',
+];
+
+const ITEM_CLASSES = {
+ 'compass': 'dungeon-item',
+ 'map': 'dungeon-item',
+ 'big-key': 'dungeon-item',
+ 'bow': 'item',
+ 'hookshot': 'item',
+ 'fire-rod': 'item',
+ 'lamp': 'item',
+ 'hammer': 'item',
+ 'somaria': 'item',
+ 'fighter-sword': 'item',
+ 'boots': 'item',
+ 'glove': 'item',
+ 'flippers': 'item',
+};
+
+const nextCSwitch = cur => {
+ switch (cur) {
+ case 'blue':
+ return 'red';
+ case 'red':
+ return '';
+ default:
+ return 'blue';
+ }
+};
+
+const prevCSwitch = cur => nextCSwitch(nextCSwitch(cur));
+
+const DoorsTracker = () => {
+ const [state, setState] = React.useState(DUNGEONS.reduce((state, dungeon) => ({
+ ...state,
+ [dungeon]: ITEMS.reduce((items, item) => ({
+ ...items,
+ [item]: false,
+ }), {
+ boss: true,
+ cswitch: '',
+ keys: 1,
+ }),
+ }), {}));
+
+ const handleItemClick = React.useCallback((dungeon, item) => e => {
+ setState(state => ({
+ ...state,
+ [dungeon]: {
+ ...state[dungeon],
+ [item]: !state[dungeon][item],
+ },
+ }));
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ const handleCSwitchClick = React.useCallback(dungeon => e => {
+ setState(state => ({
+ ...state,
+ [dungeon]: {
+ ...state[dungeon],
+ cswitch: nextCSwitch(state[dungeon].cswitch),
+ },
+ }));
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ const handleCSwitchRightClick = React.useCallback(dungeon => e => {
+ setState(state => ({
+ ...state,
+ [dungeon]: {
+ ...state[dungeon],
+ cswitch: prevCSwitch(state[dungeon].cswitch),
+ },
+ }));
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ const handleKeysClick = React.useCallback(dungeon => e => {
+ setState(state => ({
+ ...state,
+ [dungeon]: {
+ ...state[dungeon],
+ keys: state[dungeon].keys + 1,
+ },
+ }));
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ const handleKeysRightClick = React.useCallback(dungeon => e => {
+ setState(state => ({
+ ...state,
+ [dungeon]: {
+ ...state[dungeon],
+ keys: Math.max(state[dungeon].keys - 1, 0),
+ },
+ }));
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ return <>
+ <Helmet>
+ <title>Doors Tracker</title>
+ <meta name="description" content="Doors Tracker" />
+ </Helmet>
+ <div className="doors-tracker d-flex flex-column">
+ {DUNGEONS.map(dungeon =>
+ <div className="d-flex flex-row" key={dungeon}>
+ <div
+ className={`cell ${state[dungeon].boss ? 'on' : 'off'} dungeon`}
+ onClick={handleItemClick(dungeon, 'boss')}
+ >
+ <ZeldaIcon name={`dungeon-${dungeon}`} />
+ </div>
+ <div
+ className={`cell ${state[dungeon].keys ? 'on' : 'off'} keys`}
+ onClick={handleKeysClick(dungeon)}
+ onContextMenu={handleKeysRightClick(dungeon)}
+ >
+ {state[dungeon].keys}
+ </div>
+ <div
+ className={`cell ${state[dungeon].cswitch ? 'on' : 'off'} cswitch`}
+ onClick={handleCSwitchClick(dungeon)}
+ onContextMenu={handleCSwitchRightClick(dungeon)}
+ >
+ <ZeldaIcon name={state[dungeon].cswitch
+ ? `crystal-switch-${state[dungeon].cswitch}`
+ : 'crystal-switch'
+ } />
+ </div>
+ {ITEMS.map(item =>
+ <div
+ className={
+ `cell ${state[dungeon][item] ? 'on' : 'off'} ${ITEM_CLASSES[item]}`
+ }
+ key={item}
+ onClick={handleItemClick(dungeon, item)}
+ >
+ <ZeldaIcon name={item} />
+ </div>
+ )}
+ </div>
+ )}
+ </div>
+ </>;
+};
+
+export default DoorsTracker;