"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultApp = exports.DefaultAppImpl = void 0;
const react_1 = __importDefault(require("react"));
const react_dom_1 = __importDefault(require("react-dom"));
const material_1 = require("@mui/material");
const styles_1 = require("@mui/styles");
const css_1 = require("@emotion/css");
const styles_2 = require("@mui/material/styles");
const client_1 = require("../client");
const theme = (0, styles_2.createTheme)({
    palette: {
        mode: 'dark',
    },
});
const duration_timer_1 = require("../components/duration_timer");
class DefaultAppImpl extends react_1.default.Component {
    constructor(props) {
        super(props);
        this.state = {
            width: "auto",
            height: "auto",
        };
        this.s = {
            errorColor: (0, css_1.css) `
      color: ${this.props.theme.palette.error.light} !important;
    `,
            successColor: (0, css_1.css) `
      color: ${this.props.theme.palette.success.light} !important;
    `,
            splitsWrapper: (0, css_1.css) `
      position: absolute;
      overflow: hidden;
    `,
            clearBackground: (0, css_1.css) `
      background-color: rgba(0, 0, 0, 0) !important;
    `,
            headerBackground: (0, css_1.css) `
      background-color: #121212;
      background-image: linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05));
    `
        };
    }
    getUserDefinedDimension(num) {
        if (num.trim() === 'auto' || num.trim() === '') {
            return '100%';
        }
        let isNumber = true;
        for (let i = 0; i < num.length; ++i) {
            const c = num.charAt(i);
            if (!(c >= '0' && c <= '9')) {
                isNumber = false;
                break;
            }
        }
        return `${num}${isNumber ? 'px' : ''}`;
    }
    splitsUpdated(splitsData) {
        this.setState({
            width: this.getUserDefinedDimension(splitsData.pageSettings.width),
            height: this.getUserDefinedDimension(splitsData.pageSettings.height),
            splitsData,
        });
    }
    componentDidMount() {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                this.client = yield (0, client_1.connect)({
                    host: 'localhost',
                    port: '42069',
                    app_name: 'default.html',
                });
                this.client.on('splits-updated', this.splitsUpdated.bind(this));
                this.client.emit('notify-configuration-available', {
                    name: 'default.html',
                    configuration: {
                        show_num_prev_splits: {
                            type: 'number',
                            label: 'Show Next N Splits',
                            helperText: 'The maximum number upcoming splits to show',
                            min: 0,
                            max: 99,
                        },
                        show_num_next_splits: {
                            type: 'number',
                            label: 'Show Previous M Splits',
                            helperText: 'The maximum number previous splits to show',
                            min: 0,
                            max: 99,
                        },
                    },
                }, (err) => {
                    console.log('ERROR?', err);
                });
            }
            catch (err) {
                console.error(err);
                const error = err;
                this.setState({ errorMessage: error.message });
            }
        });
    }
    componentWillUnmount() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.client) {
                this.client.disconnect();
                delete this.client;
            }
        });
    }
    renderSplitDuration(id) {
        if (!this.state.splitsData) {
            return null;
        }
        const splitDuration = this.state.splitsData.attemptDuration.splits[id];
        if (!splitDuration) {
            return;
        }
        return (react_1.default.createElement(material_1.Box, { sx: { pl: 1 } },
            react_1.default.createElement(duration_timer_1.DurationTimer, { milliseconds: splitDuration.milliseconds, activeAt: splitDuration.activeAt })));
    }
    getViewerSettings() {
        const defaultViewerSettings = {
            show_num_next_splits: 2,
            show_num_prev_splits: 4,
        };
        if (!this.state.splitsData) {
            return defaultViewerSettings;
        }
        const { pageSettings } = this.state.splitsData;
        if (!pageSettings.viewerSettings['default.html']) {
            return defaultViewerSettings;
        }
        const { show_num_next_splits, show_num_prev_splits, } = pageSettings.viewerSettings['default.html'];
        if (show_num_next_splits &&
            show_num_next_splits > 0) {
            defaultViewerSettings.show_num_next_splits = show_num_next_splits;
        }
        if (show_num_prev_splits &&
            show_num_prev_splits > 0) {
            defaultViewerSettings.show_num_prev_splits = show_num_prev_splits;
        }
        return defaultViewerSettings;
    }
    renderSplits() {
        if (!this.state.splitsData) {
            return null;
        }
        const { activeSplits } = this.state.splitsData;
        const { show_num_next_splits, show_num_prev_splits } = this.getViewerSettings();
        let indexActive = 0;
        for (let i = 0; i < activeSplits.length; ++i) {
            const split = activeSplits[i];
            if (split.active) {
                indexActive = i;
                break;
            }
        }
        let startingIndex = 0;
        const maxSplitsShown = show_num_next_splits + show_num_prev_splits + 1;
        if (indexActive <= show_num_prev_splits || activeSplits.length <= maxSplitsShown) {
            startingIndex = 0;
        }
        else if (indexActive >= (activeSplits.length - 1) - show_num_next_splits) {
            startingIndex = activeSplits.length - maxSplitsShown;
        }
        else {
            startingIndex = indexActive - show_num_prev_splits;
        }
        const splitsShown = activeSplits.slice(startingIndex, startingIndex + maxSplitsShown);
        let afterCurrentSplit = false;
        return splitsShown.map((split) => {
            const row = this.renderSplitsRow(split, afterCurrentSplit);
            if (!afterCurrentSplit) {
                afterCurrentSplit = split.active;
            }
            return row;
        });
    }
    renderAttemptDuration() {
        if (!this.state.splitsData) {
            return null;
        }
        const attemptDuration = this.state.splitsData.attemptDuration;
        if (attemptDuration.attempt === 0 &&
            attemptDuration.attemptActiveAt === 0) {
            return null;
        }
        return (react_1.default.createElement(material_1.Box, { sx: { pl: 1 } },
            react_1.default.createElement(duration_timer_1.DurationTimer, { milliseconds: attemptDuration.attempt, activeAt: attemptDuration.attemptActiveAt })));
    }
    renderHeaderRow() {
        const { s } = this;
        return (react_1.default.createElement(react_1.default.Fragment, null,
            react_1.default.createElement(material_1.Box, { className: (0, css_1.cx)("head-row-start", s.headerBackground), sx: { zIndex: 1, pl: 1 } },
                react_1.default.createElement(material_1.Box, { sx: { display: 'flex', mr: 1 } },
                    react_1.default.createElement(material_1.Box, { sx: { flexGrow: 1 } }, "Split"))),
            react_1.default.createElement(material_1.Box, { className: s.headerBackground, sx: { zIndex: 1, pl: 1, textAlign: 'right' } }, "Now"),
            react_1.default.createElement(material_1.Box, { className: s.headerBackground, sx: { zIndex: 1, pl: 1, textAlign: 'right' } }, "Diff"),
            react_1.default.createElement(material_1.Box, { className: s.headerBackground, sx: { zIndex: 1, pl: 1 } }, "PB")));
    }
    renderSplitsRow(splitStep, afterCurrentSplit) {
        if (!this.state.splitsData) {
            return null;
        }
        const { id, name, hits_way, hits_boss, pb_hits } = splitStep;
        const { s } = this;
        let color = '';
        if (hits_way + hits_boss !== 0) {
            color = s.errorColor;
        }
        else if (!afterCurrentSplit) {
            color = s.successColor;
        }
        const diff = hits_way + hits_boss - (pb_hits || 0);
        return (react_1.default.createElement(react_1.default.Fragment, { key: `splits_row_fragment_${splitStep.id}` },
            react_1.default.createElement(material_1.Box, { className: `row-start ${color}`, sx: { pl: 1 } },
                react_1.default.createElement(material_1.Box, { sx: { display: 'flex', mr: 1 } },
                    react_1.default.createElement(material_1.Box, { sx: {
                            flexGrow: 1,
                            textOverflow: 'ellipsis',
                            whiteSpace: 'nowrap'
                        } }, name),
                    this.renderSplitDuration(id))),
            react_1.default.createElement(material_1.Box, { className: color, sx: { textAlign: 'right', pl: 1 } }, hits_way + hits_boss),
            react_1.default.createElement(material_1.Box, { className: color, sx: { textAlign: 'right', pl: 1 } }, pb_hits !== null && diff),
            react_1.default.createElement(material_1.Box, { className: color, sx: { pl: 1 } }, (pb_hits || 0))));
    }
    renderFooterRow() {
        if (!this.state.splitsData) {
            return null;
        }
        const { activeSplits } = this.state.splitsData;
        let totalCurrentHits = 0;
        let totalPB = 0;
        for (let i = 0; i < activeSplits.length; ++i) {
            const split = activeSplits[i];
            if (split.pb_hits) {
                totalPB += split.pb_hits;
            }
            if (split.hits_way) {
                totalCurrentHits += split.hits_way;
            }
            if (split.hits_boss) {
                totalCurrentHits += split.hits_boss;
            }
        }
        return (react_1.default.createElement(react_1.default.Fragment, null,
            react_1.default.createElement(material_1.Box, { className: "footer-row", sx: { pl: 1 } },
                react_1.default.createElement(material_1.Box, { sx: { display: 'flex', mr: 1 } },
                    react_1.default.createElement(material_1.Box, { sx: { flexGrow: 1 } }, "Total"),
                    this.renderAttemptDuration())),
            react_1.default.createElement(material_1.Box, { sx: { zIndex: 1, pl: 1, textAlign: 'right' } }, totalCurrentHits),
            react_1.default.createElement(material_1.Box, { sx: { zIndex: 1, pl: 1, textAlign: 'right' } }),
            react_1.default.createElement(material_1.Box, { sx: { zIndex: 1, pl: 1 } }, totalPB)));
    }
    renderTable() {
        if (!this.state.splitsData) {
            return null;
        }
        if (!this.state.splitsData) {
            return;
        }
        const { width, height } = this.state;
        return (react_1.default.createElement(material_1.Box, { sx: {
                position: 'absolute',
                left: 0,
                top: 0,
                width: 1,
                height: 1,
                paddingTop: '10px',
            } },
            react_1.default.createElement(material_1.Box, { className: 'challenge-run-splits-grid', sx: {
                    display: 'grid',
                    gridTemplateColumns: '1fr 1fr 1fr 1fr',
                    gridAutoRows: 'min-content',
                    width,
                    height,
                }, component: material_1.Paper },
                this.renderHeaderRow(),
                this.renderSplits(),
                this.renderFooterRow())));
    }
    renderProgressBar() {
        if (!this.state.splitsData) {
            return null;
        }
        let indexActive = 0;
        const { activeSplits } = this.state.splitsData;
        for (let i = 0; i < activeSplits.length; ++i) {
            const split = activeSplits[i];
            if (split.active) {
                indexActive = i;
                break;
            }
        }
        return (react_1.default.createElement(material_1.Box, { sx: {
                position: 'absolute',
                left: 0,
                top: 0,
                height: '10px',
                width: 1,
                zIndex: 1,
            }, square: true, component: material_1.Paper, elevation: 2 },
            react_1.default.createElement(material_1.Box, { sx: {
                    width: (indexActive + 1) / activeSplits.length,
                    position: 'absolute',
                    left: 0,
                    top: 0,
                    height: 1,
                }, component: material_1.Paper, elevation: 24, square: true })));
    }
    render() {
        if (!this.state.splitsData) {
            return null;
        }
        const { css } = this.state.splitsData.pageSettings;
        const { s } = this;
        return (react_1.default.createElement(material_1.Box, { className: s.splitsWrapper, sx: {
                width: this.state.width,
                height: this.state.height,
            } },
            react_1.default.createElement("style", { dangerouslySetInnerHTML: { __html: css } }),
            this.renderTable(),
            this.renderProgressBar()));
    }
}
exports.DefaultAppImpl = DefaultAppImpl;
exports.DefaultApp = (0, styles_1.withTheme)(DefaultAppImpl);
react_dom_1.default.render(react_1.default.createElement(material_1.ThemeProvider, { theme: theme },
    react_1.default.createElement(material_1.CssBaseline, null),
    react_1.default.createElement(exports.DefaultApp, null)), document.querySelector('#root'));
//# sourceMappingURL=default.js.map