// Copyright (c) 2025 Robin Davies
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import React from 'react';
import { Theme } from '@mui/material/styles';

import ToobFrequencyResponseView, { FREQUENCY_RESPONSE_VECTOR_URI } from './ToobFrequencyResponseView';
import WithStyles from './WithStyles';
import { createStyles } from './WithStyles';
import SvgPathBuilder from './SvgPathBuilder';
import CircleUpIcon from './svg/expand_circle_up_24dp.svg?react';
import CircleDownIcon from './svg/expand_circle_down_24dp.svg?react';
import { withStyles } from "tss-react/mui";
import DialogEx from './DialogEx';
import DialogContent from '@mui/material/DialogContent';

import IControlViewFactory from './IControlViewFactory';
import { PiPedalModelFactory, PiPedalModel, State } from "./PiPedalModel";
import { PedalboardItem } from './Pedalboard';
import PluginControlView, { ICustomizationHost, ControlGroup, ControlViewCustomization } from './PluginControlView';
import { UiPlugin } from './Lv2Plugin';
import Typography from '@mui/material/Typography';
import IconButton from '@mui/material/IconButton/IconButton';
import { css } from '@emotion/react';




const styles = (theme: Theme) => createStyles({
    menuIcon: css({
        fill: (theme.palette.text.primary + "!important"), //theme.palette.text.primary,
        opacity: 0.6
    }),
    upIcon: css({
        fill: (theme.palette.text.primary + "!important"), //theme.palette.text.primary,
        opacity: 0.6,
        alignSelf: "flex-start"
    }),
});

interface Point { x: number, y: number };


function offsetFromEnd(pt0: Point, pt1: Point, distance: number) {
    let dx = pt1.x - pt0.x;
    let dy = pt1.y - pt0.y;
    let mag = Math.sqrt(dx * dx + dy * dy);
    let normX = dx / mag;
    let normY = dy / mag;
    return {
        x: pt1.x - normX * distance,
        y: pt1.y - normY * distance
    }
}


const getWindowSize = () => {
    return {
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight,
    };
};


interface UnpackedControls {
    eq: React.ReactNode;
    filters_loCut: React.ReactNode;
    filters_hiCut: React.ReactNode;
    low_level: React.ReactNode;
    low_freq: React.ReactNode;
    lmf_level: React.ReactNode;
    lmf_freq: React.ReactNode;
    lmf_q: React.ReactNode;
    hmf_level: React.ReactNode;
    hmf_freq: React.ReactNode;
    hmf_q: React.ReactNode;
    hi_level: React.ReactNode;
    hi_freq: React.ReactNode;
    gain: React.ReactNode;
}

interface ToobParametricEqViewProps extends WithStyles<typeof styles> {
    instanceId: number;
    item: PedalboardItem;

}
interface ToobParametricEqViewState {
    windowSize: { width: number, height: number };
    maximized: boolean;

}

const ToobParametricEqView =
    withStyles(
        class extends React.Component<ToobParametricEqViewProps, ToobParametricEqViewState>
            implements ControlViewCustomization {
            model: PiPedalModel;

            customizationId: number = 943;

            constructor(props: ToobParametricEqViewProps) {
                super(props);

                this.handleResize = this.handleResize.bind(this);
                this.handleConnectionStateChanged = this.handleConnectionStateChanged.bind(this);

                this.model = PiPedalModelFactory.getInstance();
                this.state = {
                    windowSize: getWindowSize(),
                    maximized: false
                }
                let pluginInfo: UiPlugin | null = this.model.getUiPlugin(this.props.item.uri);
                if (pluginInfo === null) {
                    throw new Error("Plugin not fouund.");
                }
            }

            fullScreen() {
                return true;
            }

            horizontalScrollControls(host: ICustomizationHost, controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] {
                // Implement horizontal scrolling behavior for tiny horizontal screens
                controls[0] = (
                    <div id="fixedGraph_xxx" key="fixedGraph" style={{ position: "absolute", top: 0, left: 0, padding: 5, background: "#F88" }}>
                        {controls[0] as React.ReactNode}
                    </div>
                );
                return controls;
            }

            unpackControls(host: ICustomizationHost, controls: (React.ReactNode | ControlGroup)[]): UnpackedControls {
                return {
                    eq: controls[0] as React.ReactNode,
                    filters_loCut: (controls[1] as ControlGroup).controls[0],
                    filters_hiCut: (controls[1] as ControlGroup).controls[1],
                    low_level: (controls[2] as ControlGroup).controls[0],
                    low_freq: (controls[2] as ControlGroup).controls[1],
                    lmf_level: (controls[3] as ControlGroup).controls[0],
                    lmf_freq: (controls[3] as ControlGroup).controls[1],
                    lmf_q: (controls[3] as ControlGroup).controls[2],
                    hmf_level: (controls[4] as ControlGroup).controls[0],
                    hmf_freq: (controls[4] as ControlGroup).controls[1],
                    hmf_q: (controls[4] as ControlGroup).controls[2],
                    hi_level: (controls[5] as ControlGroup).controls[0],
                    hi_freq: (controls[5] as ControlGroup).controls[1],
                    gain: controls[6] as React.ReactNode
                };
            }
            absolutePosition(x: number, y: number, el: React.ReactNode) {
                return (<div style={{ position: "absolute", left: x, top: y }}>{el}</div>);
            }
            private ROW_HEIGHT = 140;
            private BORDER_HEIGHT = 350;
            private DIAL_WIDTH = 63;
            private GRAPH_WIDTH = this.DIAL_WIDTH * 2;

            private smoothPath(pt0: Point, pt1: Point, pt2: Point, pt3: Point, curveRadius: number): string {
                let pathBuilder = new SvgPathBuilder();


                let ctl01 = offsetFromEnd(pt0, pt1, curveRadius);
                let ctl02 = offsetFromEnd(pt0, pt1, curveRadius / 3);
                let ctl03 = offsetFromEnd(pt2, pt1, curveRadius / 3);
                let ctl04 = offsetFromEnd(pt2, pt1, curveRadius);

                let ctl11 = offsetFromEnd(pt1, pt2, curveRadius);
                let ctl12 = offsetFromEnd(pt1, pt2, curveRadius / 3);
                let ctl13 = offsetFromEnd(pt3, pt2, curveRadius / 3);
                let ctl14 = offsetFromEnd(pt3, pt2, curveRadius);

                pathBuilder.moveTo(pt0.x, pt0.y);
                pathBuilder.lineTo(ctl01.x, ctl01.y);
                pathBuilder.bezierTo(
                    ctl02.x, ctl02.y,
                    ctl03.x, ctl03.y,
                    ctl04.x, ctl04.y
                );
                pathBuilder.lineTo(ctl11.x, ctl11.y);
                pathBuilder.bezierTo(
                    ctl12.x, ctl12.y,
                    ctl13.x, ctl13.y,
                    ctl14.x, ctl14.y
                );
                pathBuilder.lineTo(pt3.x, pt3.y);
                return pathBuilder.toString();
            }
            horizontalCompactControls(host: ICustomizationHost, controls: UnpackedControls) {
                let height = this.BORDER_HEIGHT;
                let row0 = height / 2 - this.ROW_HEIGHT;
                let row1 = row0 + this.ROW_HEIGHT;

                let borderTop = 0;
                let borderBottom = height - 8;

                let labelTop = row0 - 30;
                let labelBottom = row1 + this.ROW_HEIGHT - 5;

                let colPos = (group: number, col: number) => this.DIAL_WIDTH * (0.3 * group + col);
                let cpos0 = (group: number, col: number, el: React.ReactNode) => this.absolutePosition(colPos(group, col), row0, el);
                let cpos1 = (group: number, col: number, el: React.ReactNode) => this.absolutePosition(colPos(group, col) + this.DIAL_WIDTH / 2, row1, el);


                let label1 = (y: number, group: number, col0: number, col1: number, text: string, align: "left" | "center" | "right") => {
                    let left = colPos(group, col0);
                    let right = colPos(group, col1);
                    return (
                        <Typography variant="body1" noWrap style={{
                            fontSize: "0.85em", fontWeight: 700,
                            top: y, paddingLeft: 0, paddingRight: 0,
                            position: "absolute", left: left + 8, width: right - left,
                            opacity: 0.4, textAlign: align
                        }}>{text}</Typography>
                    );
                };
                let divider = (group: number, col0: number, y0: number, col1: number, y1: number) => {
                    let x0 = colPos(group, col0);
                    let x1 = colPos(group, col1);
                    return (
                        <svg width={x1 - x0 + 4} height={y1 - y0 + 4} style={{ position: "absolute", left: x0 - 2, top: y0 - 2 }}>
                            <line x1={2} y1={2} x2={2 + x1 - x0} y2={2 + y1 - y0} stroke="#888" strokeWidth={4} />
                        </svg>
                    );
                };
                let leftDivider = (group: number, col0: number, y0: number, col1: number, y1: number) => {
                    let x0 = colPos(group, col0);
                    let x1 = colPos(group, col1);
                    let xOrg = Math.min(x0, x1) - 2;
                    let yOrg = Math.min(y0, y1) - 2;
                    let width = Math.abs(x1 - x0) + 4;
                    let height = Math.abs(y1 - y0) + 4;

                    let bezierLength = 10;
                    let pt0 = { x: x0, y: y0 };
                    let pt1 = { x: x0, y: row1 - 18 };
                    let pt2 = { x: x1, y: row1 + 3 };
                    let pt3 = { x: x1, y: y1 };

                    let path = this.smoothPath(pt0, pt1, pt2, pt3, bezierLength);

                    return (
                        <svg width={width} height={height} style={{ position: "absolute", left: xOrg - 1, top: yOrg }}
                            viewBox={`${xOrg} ${yOrg} ${width} ${height}`}
                        >
                            <path d={path} fill="none" stroke="#888" strokeWidth="4px" />
                        </svg>
                    );
                };
                let graph = (
                    <ToobFrequencyResponseView width={this.GRAPH_WIDTH}
                        propertyName={FREQUENCY_RESPONSE_VECTOR_URI}
                        instanceId={this.props.instanceId} />
                );

                return [(<div style={{
                    width: "100%", height: "100%",
                    position: "relative", display: "flex", flexFlow: "column nowrap",
                    alignItems: "center", justifyContent: "center"
                }}>
                    <div style={{ flex: "1 1 0px", }} />
                    <div style={{
                        flex: "0 0 auto", border: "4px #888 solid", borderRadius: "8px 8px 8px 8px", position: "relative",
                        width: colPos(6, 8.5), height: height,
                    }}>
                        {label1(labelBottom, 1, 2, 3.0, "Lo Shelf", "center")}
                        {label1(labelTop, 2, 3, 5, "Low Mid", "center")}
                        {label1(labelBottom, 3, 4.5, 6.5, "High Mid", "center")}
                        {label1(labelTop, 4, 6.5, 7.5, "Hi Shelf", "center")}
                        {divider(1, 2.0, borderTop, 2.0, borderBottom)}
                        {divider(5, 7.5, borderTop, 7.5, borderBottom)}
                        {leftDivider(2, 3.0, borderTop, 3.0, borderBottom)}
                        {leftDivider(3, 5.0, borderTop, 4.5, borderBottom)}
                        {leftDivider(4, 6.5, borderTop, 6.5, borderBottom)}

                        {this.absolutePosition(0, row0, graph)}
                        {this.absolutePosition(colPos(0, 0), row1, controls.filters_loCut)}
                        {this.absolutePosition(colPos(0, 1), row1, controls.filters_hiCut)}

                        {cpos0(1, 2, controls.low_level)}
                        {cpos1(1, 2 - 0.5, controls.low_freq)}

                        {cpos0(2, 3.0, controls.lmf_q)}
                        {cpos1(2, 2.75, controls.lmf_freq)}
                        {cpos0(2, 4, controls.lmf_level)}

                        {cpos1(3, 4, controls.hmf_freq)}
                        {cpos0(3, 5.25, controls.hmf_level)}
                        {cpos1(3, 5, controls.hmf_q)}

                        {cpos0(4, 6.5, controls.hi_level)}
                        {cpos1(4, 6, controls.hi_freq)}

                        {cpos0(5, 7.5, controls.gain)}
                    </div>
                    <div style={{ flex: "5 5 0px", }} />

                </div>)];
            }
            verticalCompactControls(host: ICustomizationHost, controls: UnpackedControls) {
                let width = 380;

                let graph = (
                    <ToobFrequencyResponseView width={344}
                        propertyName={FREQUENCY_RESPONSE_VECTOR_URI}
                        instanceId={this.props.instanceId} />
                );
                let divider = () => {
                    return (
                        <div style={{ width: "100%", height: 1, background: "#8888" }} />
                    );
                }
                let vDivider = () => {
                    return (
                        <div style={{ width: 1, minWidth: 1, height: 164, background: "#888" }} />
                    );
                }
                let panel = (label: string, controls: React.ReactNode[]) => {
                    return (
                        <div style={{ display: "flex", flexFlow: "column nowrap", alignItems: "center", marginRight: 8, marginLeft: 8 }}>
                            <div style={{
                                width: controls.length * this.DIAL_WIDTH, height: 130, position: "relative",
                                overflow: "hidden", marginRight: 8
                            }}>
                                {controls.map((ctl, i) => {
                                    return (
                                        <div key={i} style={{ width: this.DIAL_WIDTH, position: "absolute", left: i * this.DIAL_WIDTH, top: 8 }}>
                                            {ctl}
                                        </div>
                                    );
                                })}
                            </div>
                            <Typography variant="body1" noWrap style={{
                                fontSize: "0.85em", fontWeight: 700, width: label !== "" ? 100 : 5, paddingTop: 4, paddingBottom: 8,
                                opacity: 0.4, textAlign: "center"
                            }}>{label}</Typography>
                        </div>
                    );
                }

                return [(<div key="tpq_cv" style={{
                    width: "100%", height: "100%",
                    position: "relative", display: "flex", flexFlow: "column nowrap",
                    alignItems: "center", justifyContent: "center"
                }}>
                    <div style={{ flex: "1 1 0px" }} />
                    <div style={{
                        display: "flex", flexFlow: "row wrap", alignItems: "center", width: width, justifyContent: "space-between",
                        flex: "0 0 auto", border: "4px #888 solid", borderRadius: "8px 8px 8px 8px", position: "relative",
                    }}>

                        {graph}
                        {(<div style={{ width: "100%", height: 16 }} />)}
                        {panel("", [
                            controls.filters_loCut,
                            controls.filters_hiCut,
                        ])}
                        {panel("", [
                            controls.gain
                        ])}
                        {divider()}
                        {panel("Low",
                            [controls.low_level,
                            controls.low_freq
                            ])
                        }
                        {vDivider()}
                        {panel("Low Mid",

                            [
                                controls.lmf_level,
                                controls.lmf_freq,
                                controls.lmf_q,
                            ])
                        }
                        {divider()}
                        {panel("High Mid",

                            [
                                controls.hmf_level,
                                controls.hmf_freq,
                                controls.hmf_q,
                            ])
                        }
                        {vDivider()}
                        {panel("High",
                            [controls.hi_level,
                            controls.hi_freq
                            ])
                        }
                    </div>
                    <div style={{ flex: "5 5 0px", }} />

                </div>)];
            }

            tinyControls(host: ICustomizationHost, controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] {
                const classes = withStyles.getClasses(this.props);
                let isLandscape = host.isLandscapeGrid();
                let panelControls: React.ReactNode[] = [];

                let filterGroup = controls[1] as ControlGroup;
                let miscGroup: ControlGroup = {
                    name: "",
                    indexes: [],
                    controls: [
                        filterGroup.controls[0],
                        filterGroup.controls[1],
                        controls[controls.length - 1] as React.ReactNode
                    ]
                };
                panelControls.push(host.renderControlGroup(miscGroup, "vtc_miscGroup"));
                if (!isLandscape) {
                    panelControls.push(
                        (
                            <div key="ctlx_div" style={{ width: "100%", height: 0 }} />
                        )
                    );
                }

                for (let i = 2; i < controls.length - 1; ++i) {
                    let c = controls[i];
                    if (c instanceof ControlGroup) {
                        panelControls.push(
                            host.
                                renderControlGroup(c as ControlGroup, "vtc_cg" + i)
                        );
                    } else {
                        panelControls.push(c as React.ReactNode);
                    }
                }
                let panelStyle: React.CSSProperties;
                let scrollStyle: React.CSSProperties;
                let frameStyle: React.CSSProperties;

                if (isLandscape) {
                    panelStyle = { display: "flex", flexDirection: "row", alignItems: "stretch", width: "100%" };
                    scrollStyle = { flex: "1 1 auto", overflowX: "auto", overflowY: "hidden", whiteSpace: "nowrap" };
                    frameStyle = { display: "flex", flexFlow: "row nowrap", alignItems: "center", paddingTop: 8 };
                } else {
                    panelStyle = { display: "flex", flexDirection: "column", alignItems: "stretch", height: "100%" };
                    scrollStyle = { flex: "1 1 auto", overflowX: "hidden", overflowY: "auto", whiteSpace: "nowrap" };
                    frameStyle = { display: "flex", flexFlow: "row wrap", alignItems: "left", justifyContent: "left", gap: 12, paddingTop: 24, paddingBottom: 48 };
                }

                return [(
                    <div key={"vtc_container"} style={panelStyle}>
                        {host.isLandscapeGrid() ? (
                            <div key={"vtc_panel"} style={{ flex: " 0 0 auto", paddingBottom: 8, display: "flex", alignItems: "center", flexFlow: "row nowrap" }}>
                                <div style={{ alignSelf: "flex-start", marginTop: 8 }}>
                                    <IconButton 
                                        style={{marginTop: 24}}
                                        onClick={(e) => {
                                        e.stopPropagation();
                                        this.setState({ maximized: true });
                                    }}>
                                        <CircleUpIcon className={classes.upIcon} />
                                    </IconButton>
                                </div>
                                {controls[0] as React.ReactNode}
                            </div>
                        ) : (
                            <div key={"vtc_panel"} style={{ flex: " 0 0 auto", paddingBottom: 8, display: "flex", alignItems: "center", flexFlow: "row nowrap" }}>
                                {controls[0] as React.ReactNode}
                                <div style={{ alignSelf: "flex-start", marginTop: 8 }}>
                                    <IconButton onClick={(e) => {
                                        e.stopPropagation();
                                        this.setState({ maximized: true });
                                    }}>
                                        <CircleUpIcon className={classes.upIcon} />
                                    </IconButton>
                                </div>
                            </div>
                        )}
                        <div style={scrollStyle}>
                            <div style={frameStyle}>
                                {panelControls}
                            </div>
                        </div>
                    </div>
                )];
            }
            private dialogRef: HTMLDivElement | null = null;
            private panelRef: HTMLDivElement | null = null;

            dlgTickInAnimation(yOffset: number, startTime: number) {
                let elapsed = Date.now() - startTime;
                let pct = elapsed / 200;
                if (pct > 1) pct = 1;
                if (!this.dialogRef) {
                    return;
                }
                this.dialogRef.style.opacity = `${pct}`;
                this.dialogRef.style.transform = `translateY(${(1 - pct) * yOffset}px)`;
                if (pct >= 1) {
                    return;
                }
                window.requestAnimationFrame(() => {
                    this.dlgTickInAnimation(yOffset, startTime);
                });
            }
            dlgTickOutAnimation(yOffset: number, startTime: number) {
                if (!this.dialogRef || !this.panelRef) {
                    this.setState({ maximized: false });
                    return;
                }
                let elapsed = Date.now() - startTime;
                let pct = elapsed / 200;
                if (pct > 1) pct = 1;
                if (!this.dialogRef) {
                    return;
                }
                this.dialogRef.style.transform = `translateY(${(pct) * yOffset}px)`;
                this.dialogRef.style.opacity = `${1 - pct}`;
                if (pct >= 1) {
                    this.setState({ maximized: false });
                    return;
                }
                window.requestAnimationFrame(() => {
                    this.dlgTickOutAnimation(yOffset, startTime);
                });
            }
            dlgSlideInAnimation(yOffset: number) {
                if (!this.animateDialog) {
                    return;
                }
                this.animateDialog = false;
                window.requestAnimationFrame(() => {
                    if (this.dialogRef) {
                        let startTime = Date.now();
                        this.dlgTickInAnimation(yOffset, startTime);
                    }
                });
            }
            dlgSlideOutAnimation(yOffset: number) {
                if (!this.animateDialog) {
                    return;
                }
                this.animateDialog = false;

                window.requestAnimationFrame(() => {
                    if (this.dialogRef) {
                        let startTime = Date.now();
                        this.dlgTickInAnimation(yOffset, startTime);
                    }
                });
            }
            startSlideOutAnimation() {
                if (this.panelRef && this.dialogRef) {
                    let yOffset = this.panelRef.getBoundingClientRect().top;

                    window.requestAnimationFrame(() => {
                        if (this.dialogRef && this.dialogRef) {
                            let startTime = Date.now();
                            this.dlgTickOutAnimation(yOffset, startTime);
                        }
                    });
                } else {
                    this.setState({ maximized: false });
                }
            }
            checkTransitionStart() {
                if (this.dialogRef && this.panelRef) {
                    let panelRect = this.panelRef.getBoundingClientRect();
                    this.dlgSlideInAnimation(panelRect.top);
                }
            }
            setDialogRef(ref: HTMLDivElement | null) {
                this.dialogRef = ref;
                this.checkTransitionStart();
            };
            setPanelRef(ref: HTMLDivElement | null) {
                this.panelRef = ref;
                this.checkTransitionStart();
            }
            modifyControls(host: ICustomizationHost, controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] {
                const classes = withStyles.getClasses(this.props);
                let unpackedControls = this.unpackControls(host, controls);

                if (this.state.maximized) {
                    return [(
                        <div ref={(instance: HTMLDivElement | null): void => { this.setPanelRef(instance); }}
                            style={{ position: "absolute", top: 0, left: 0, right: 0, bottom: 0 }}>
                            <DialogEx key="peq_dialog"
                                open={this.state.maximized}
                                onEnterKey={() => this.setState({ maximized: false })}
                                onClose={() => this.setState({ maximized: false })}
                                fullScreen={true}
                                tag="peq_dialog"

                                dlgRef={(instance: HTMLDivElement | null): void => {
                                    this.setDialogRef(instance);
                                }}
                            >

                                <DialogContent>
                                    {this.state.windowSize.width > this.state.windowSize.height ? (
                                        <div style={{
                                            width: "100%", height: "100%",
                                            display: "flex", flexFlow: "row nowrap"
                                        }}
                                        >
                                            <div>
                                                <IconButton onClick={(e) => {
                                                    e.stopPropagation();
                                                    this.startSlideOutAnimation();
                                                }} style={{ paddingTop: 48, paddingLeft: 8, paddingRight: 8 }}>
                                                    <CircleDownIcon className={classes.menuIcon} />
                                                </IconButton>
                                            </div>
                                            <div style={{ flex: "1 1 auto", height: "100%", position: "relative" }}>
                                                {this.horizontalCompactControls(host, unpackedControls)}
                                            </div>
                                        </div>

                                    ) : (
                                        <div style={{
                                            width: "100%", height: "100%",
                                            display: "flex", flexFlow: "column nowrap"
                                        }}
                                        >
                                            <div>
                                                <IconButton onClick={(e) => {
                                                    e.stopPropagation();
                                                    this.startSlideOutAnimation();
                                                }} style={{ paddingLeft: 8, paddingTop: 8, paddingBottom: 8 }}>
                                                    <CircleDownIcon className={classes.menuIcon} />
                                                </IconButton>
                                            </div>
                                            <div style={{ flex: "1 1 auto", width: "100%", position: "relative" }}>
                                                {this.verticalCompactControls(host, unpackedControls)}
                                            </div>
                                        </div>

                                    )
                                    }
                                </DialogContent>
                            </DialogEx>
                        </div>

                    )];
                }


                if (this.state.windowSize.width > 750 && this.state.windowSize.height > 600) {
                    return this.horizontalCompactControls(host, unpackedControls);
                }
                return this.tinyControls(host, controls);
            }

            private handleConnectionStateChanged(state: State) {
                if (state === State.Ready) {
                    this.unsubscribe();
                    this.subscribe();
                }
            }

            private handleResize() {
                this.setState({ windowSize: getWindowSize() });
            }

            subscribe() {
                this.subscribedId = this.props.instanceId;
            }
            unsubscribe() {
            }

            componentDidMount() {
                if (super.componentDidMount) {
                    super.componentDidMount();
                }
                this.subscribe();
                this.model.state.addOnChangedHandler(this.handleConnectionStateChanged);
                window.addEventListener("resize", this.handleResize);

            }
            componentWillUnmount() {
                this.unsubscribe();
                if (super.componentWillUnmount) {
                    super.componentWillUnmount();
                }
                this.model.state.removeOnChangedHandler(this.handleConnectionStateChanged);
                window.removeEventListener("resize", this.handleResize);

            }

            private subscribedId: number | null = null;
            private animateDialog: boolean = false;
            componentDidUpdate(oldProps: ToobParametricEqViewProps, oldState: ToobParametricEqViewState) {
                if (this.props.instanceId !== this.subscribedId) {
                    this.unsubscribe();
                    this.subscribe();
                }
                this.animateDialog = this.state.maximized != oldState.maximized;

            }


            render() {
                return (<PluginControlView
                    instanceId={this.props.instanceId}
                    item={this.props.item}
                    customization={this}
                    customizationId={this.customizationId}
                    showModGui={false}
                    onSetShowModGui={(instanceId: number, showModGui: boolean) => { }}

                />);
            }
        },
        styles
    );



class ToobParametricEqViewFactory implements IControlViewFactory {
    uri: string = "http://two-play.com/plugins/toob-parametric-eq";

    Create(model: PiPedalModel, pedalboardItem: PedalboardItem): React.ReactNode {
        return (<ToobParametricEqView instanceId={pedalboardItem.instanceId} item={pedalboardItem} />);
    }


};
export default ToobParametricEqViewFactory;

class ToobParametricEqViewFactoryStereo implements IControlViewFactory {
    uri: string = "http://two-play.com/plugins/toob-parametric-eq-stereo";

    Create(model: PiPedalModel, pedalboardItem: PedalboardItem): React.ReactNode {
        return (<ToobParametricEqView instanceId={pedalboardItem.instanceId} item={pedalboardItem} />);
    }


};

export { ToobParametricEqViewFactoryStereo };


