ui <- bslib::page_sidebar(
  shinyjs::useShinyjs(),
  title = 'praatpicture: Praat-style plots of acoustic data in R',
  sidebar = bslib::sidebar(
    bslib::accordion(
      bslib::accordion_panel(
        'File uploads',
        fileInput('sound', 'Upload a sound file'),
        shinyjs::hidden(fileInput('tg_file', 'Upload a TextGrid file')),
      ),
      bslib::accordion_panel(
        'General appearance',
        numericInput('start', 'Start time (s)', 0, min = 0),
        numericInput('end', 'End time (s; 0 = entire file)', 0, min = 0),
        checkboxInput('tfrom0', 'Should time run from 0 on the x-axis?', TRUE),
        selectInput('tUnit', 'What should be the unit of time on the x-axis?',
                    choices = c('seconds' = 's', 'milliseconds' = 'ms')),
        selectInput('frames', 'Which frames should be plotted?',
                    choices = c('sound', 'spectrogram', 'TextGrid', 'pitch',
                                'formant', 'intensity'),
                    selected = c('sound', 'spectrogram'),
                    multiple = TRUE),
        textInput('proportion',
                  'Relative proportion of frames (comma-delimited)',
                  '0'),
        textInput('mainTitle', 'Title'),
        numericInput('mainTitleAlignment', 'Title alignment',
                     0, min = 0, max = 1),
        checkboxInput('start_end_only',
                      'Should only start and end times be shown on the x-axis?',
                      TRUE),
        checkboxInput('min_max_only',
                      'Should only minima and maxima be shown on the y-axis?',
                      TRUE),
        numericInput('speckleSize', 'Point size of speckled plot components',
                     1, min = 0),
        numericInput('drawSize', 'Line width of drawn plot components',
                     1, min = 0),
        textInput('time_axisLabel', 'x-axis label', 'Time (s)'),
        numericInput('fontSize', 'Font size', 12),
        selectInput('fontFace', 'Font face',
                    choices = c('Default' = 1,
                                'Bold' = 2,
                                'Italic' = 3,
                                'Bold italic' = 4)),
        textInput('fontFamily', 'Font family', 'sans'),
        textInput('globalColor', 'Global color scheme', 'black'),
        textInput('bgColor', 'Background color', 'white'),
        numericInput('figWidth', 'Width (cm)', 15),
        numericInput('figHeight', 'Height (cm)', 10),
        numericInput('figDPI', 'Resolution (DPI)', 300)
      ),
      bslib::accordion_panel('Waveform',
                             shinyjs::hidden(textInput('wave_color',
                                                       'Color',
                                                       'black')),
                             shinyjs::hidden(textInput('wave_channels',
                                                       paste('Which channels should be plotted?',
                                                             '(comma-delimited)'),
                                                       'all')),
                             shinyjs::hidden(checkboxInput('wave_channelNames',
                                                           paste('Should channel names be writted next',
                                                                 'to waveform channels?'),
                                                           FALSE)),
                             shinyjs::hidden(textInput('wave_channelNamesStr',
                                                       'Custom channel names (comma-delimited)',
                                                       NA)),
                             shinyjs::hidden(numericInput('wave_lineWidth',
                                                          'Line width',
                                                          1))
      ),
      bslib::accordion_panel(
        'Spectrogram',
        shinyjs::hidden(numericInput('spec_freqRangeMin',
                                     'Minimum frequency (Hz)',
                                     0)),
        shinyjs::hidden(numericInput('spec_freqRangeMax',
                                     'Maximum frequency (Hz)',
                                     5000)),
        shinyjs::hidden(numericInput('spec_channel',
                                     'Channel used to derive spectrogram',
                                     NA)),
        shinyjs::hidden(numericInput('spec_windowLength',
                                     'Length of analysis window (s)',
                                     0.005)),
        shinyjs::hidden(numericInput('spec_dynamicRange',
                                     'Dynamic range (dB)',
                                     50)),
        shinyjs::hidden(numericInput('spec_timeStep',
                                     'Number of time steps / frames',
                                     1000)),
        shinyjs::hidden(selectInput('spec_windowShape', 'Window shape',
                                    choices = c('Gaussian', 'Hamming', 'Hanning',
                                                'Bartlett', 'square', 'Blackman'),
                                    selected = 'Gaussian')),
        shinyjs::hidden(textInput('spec_colors', 'Colors (comma-delimited)',
                                  'white,black'),
                        textInput('spec_axisLabel', 'y-axis label',
                                  'Frequency (Hz)')),
        shinyjs::hidden(checkboxInput('pitch_plotOnSpec',
                                      'Pitch overlay',
                                      FALSE)),
        shinyjs::hidden(checkboxInput('formant_plotOnSpec',
                                      'Formant overlay',
                                      FALSE)),
        shinyjs::hidden(checkboxInput('intensity_plotOnSpec',
                                      'Intensity overlay',
                                      FALSE))
      ),
      bslib::accordion_panel(
        'TextGrid',
        shinyjs::hidden(textInput('tg_tiers',
                                  paste('Which tiers should be shown?',
                                        '(comma-delimited)'),
                                  'all')),
        shinyjs::hidden(textInput('tg_focusTier',
                                  paste('Which tier(s) are in focus?',
                                        '(comma-delimited)'),
                                  'all')),
        shinyjs::hidden(textInput('tg_focusTierColor',
                                  paste('Which color(s) should be used for the',
                                        'focus tier(s)? (comma-delimited)'),
                                  'black')),
        shinyjs::hidden(textInput('tg_focusTierLineType',
                                  paste('Which line type(s) should be used for the',
                                        'focus tier(s)? (comma-delimited)'),
                                  'dotted')),
        shinyjs::hidden(checkboxInput('tg_tierNames',
                                      'Should tier names be printed along the x-axis?',
                                      TRUE)),
        shinyjs::hidden(textInput('tg_alignment',
                                  paste('How should text in the tier(s) be aligned?',
                                        '(comma-delimited)'),
                                  'central')),
        shinyjs::hidden(checkboxInput('tg_specialChar',
                                      'Should Praat-style special typesetting be used?',
                                      FALSE)),
        shinyjs::hidden(textInput('tg_color',
                                  paste('Which color(s) should be used for text in the',
                                        'tier(s)?'),
                                  'black'))
      ),
      bslib::accordion_panel(
        'Pitch',
        shinyjs::hidden(selectizeInput('pitch_plotType',
                                       'Plot type',
                                       choices = c('draw', 'speckle'),
                                       selected = 'draw',
                                       multiple = TRUE,
                                       options = list(create = TRUE))),
        shinyjs::hidden(selectInput('pitch_scale',
                                    'Frequency scale',
                                    choices = c('hz', 'logarithmic', 'semitones',
                                                'erb', 'mel'),
                                    selected = 'hz')),
        shinyjs::hidden(numericInput('pitch_semitonesRe',
                                     'Reference frequency for semitone conversion (Hz)',
                                     100)),
        shinyjs::hidden(numericInput('pitch_freqRangeMin',
                                     'Minimum frequency to show (scale-dependent)',
                                     50)),
        shinyjs::hidden(numericInput('pitch_freqRangeMax',
                                     'Maximum frequency to show (scale-dependent)',
                                     500)),
        shinyjs::hidden(numericInput('pitch_timeStep',
                                     'Time step / frame shift (s)',
                                     0.01)),
        shinyjs::hidden(numericInput('pitch_floor',
                                     'Floor frequency (Hz)',
                                     75)),
        shinyjs::hidden(numericInput('pitch_ceiling',
                                     'Ceiling frequency (Hz)',
                                     600)),
        shinyjs::hidden(textInput('pitch_color',
                                  'Color',
                                  'black')),
        shinyjs::hidden(textInput('pitch_axisLabel',
                                  'y-axis label',
                                  'Frequency (Hz)'))
      ),
      bslib::accordion_panel(
        'Formants',
        shinyjs::hidden(selectizeInput('formant_plotType',
                                       'Plot type',
                                       choices = c('draw', 'speckle'),
                                       selected = 'speckle',
                                       multiple = TRUE,
                                       options = list(create = TRUE))),
        shinyjs::hidden(numericInput('formant_freqRangeMin',
                                     'Minimum frequency to show (Hz)',
                                     0)),
        shinyjs::hidden(numericInput('formant_freqRangeMax',
                                     'Maximum frequency to show (Hz)',
                                     5500)),
        shinyjs::hidden(numericInput('formant_dynamicRange',
                                     'Dynamic range (dB)',
                                     30)),
        shinyjs::hidden(numericInput('formant_timeStep',
                                     'Time step / window shift (s)',
                                     0.00625)),
        shinyjs::hidden(numericInput('formant_windowLength',
                                     'Length of analysis window (s)',
                                     0.025)),
        shinyjs::hidden(numericInput('formant_maxN',
                                     'Maximum number of formants to estimate',
                                     5)),
        shinyjs::hidden(numericInput('formant_number',
                                     'Number of formants to plot',
                                     5)),
        shinyjs::hidden(textInput('formant_color',
                                  'Colors (comma-separated)',
                                  'black')),
        shinyjs::hidden(textInput('formant_axisLabel',
                                  'y-axis label',
                                  'Frequency (Hz)'))
      ),
      bslib::accordion_panel(
        'Intensity',
        shinyjs::hidden(numericInput('intensity_rangeMin',
                                     'Minimum amplitude (dB)',
                                     NA)),
        shinyjs::hidden(numericInput('intensity_rangeMax',
                                     'Maximum amplitude (dB)',
                                     NA)),
        shinyjs::hidden(numericInput('intensity_minPitch',
                                     'Minimum pitch (Hz)',
                                     100)),
        shinyjs::hidden(textInput('intensity_color',
                                  'Color',
                                  'black')),
        shinyjs::hidden(textInput('intensity_axisLabel',
                                  'Axis label',
                                  'Intensity (dB)'))
      ),
      bslib::accordion_panel(
        'Highlighting',
        checkboxInput('highlightBool',
                      'Differential highlighting of parts of signals?',
                      FALSE),
        shinyjs::hidden(selectInput('highlightComp',
                                    'Which signal to highlight',
                                    choices = c('all', 'wave', 'spectrogram',
                                                'pitch', 'formant', 'intensity'),
                                    selected = 'all')),
        shinyjs::hidden(textInput('highlightStart',
                                  'Start time(s) (comma-separated)',
                                  '0')),
        shinyjs::hidden(textInput('highlightEnd',
                                  'End time(s) (comma-separated)',
                                  '0.1')),
        shinyjs::hidden(checkboxInput('highlightTGbool',
                                      'Use TextGrid information?',
                                      FALSE)),
        shinyjs::hidden(textInput('highlightTier',
                                  'TextGrid tier')),
        shinyjs::hidden(textInput('highlightLabel',
                                  'Label(s) to match in TextGrid tier')),
        shinyjs::hidden(textInput('highlightCol',
                                  'Color(s) (comma-separated)',
                                  'black')),
        shinyjs::hidden(textInput('highlightBG',
                                  'Background color',
                                  'white')),
        shinyjs::hidden(textInput('highlightDrawSize',
                                  'Draw size')),
        shinyjs::hidden(textInput('highlightSpeckleSize',
                                  'Speckle size')),
        checkboxInput('arrowBool', 'Add arrow(s)?'),
        shinyjs::hidden(textInput('arrowComp',
                                  paste('Which plot component(s) should arrow(s) be',
                                        'drawn on? (comma-separated)'),
                                  'sound')),
        shinyjs::hidden(textInput('arrowx0',
                                  paste('Where should the arrow(s) start on the',
                                        'x-axis? (comma-separated)'),
                                  '0')),
        shinyjs::hidden(textInput('arrowx1',
                                  paste('Where should the arrow(s) end on the',
                                        'x-axis? (comma-separated)'),
                                  '0.5')),
        shinyjs::hidden(textInput('arrowy0',
                                  paste('Where should the arrow(s) start on the',
                                        'y-axis? (comma-separated)'),
                                  '0')),
        shinyjs::hidden(textInput('arrowy1',
                                  paste('Where should the arrow(s) end on the',
                                        'y-axis? (comma-separated)'),
                                  '0.1')),
        shinyjs::hidden(textInput('arrowLength',
                                  paste('What should be the length of the arrow',
                                        'head(s) (in inches)?'),
                                  '0.25')),
        shinyjs::hidden(textInput('arrowAngle',
                                  paste('What should be the angle of the arrow',
                                        'head(s) (in degrees)?'),
                                  '30')),
        shinyjs::hidden(textInput('arrowColor',
                                  'Color(s) (comma-separated)',
                                  'black')),
        shinyjs::hidden(textInput('arrowLineType',
                                  'Line type(s) (comma-separated)',
                                  'solid')),
        shinyjs::hidden(textInput('arrowLineWidth',
                                  'Line width(s) (comma-separated)',
                                  '1')),
        checkboxInput('rectBool', 'Add rectangle(s)?', FALSE),
        shinyjs::hidden(textInput('rectComp',
                                  paste('Which plot component(s) should rectangle(s) be',
                                        'drawn on? (comma-separated)'),
                                  'sound')),
        shinyjs::hidden(textInput('rectxleft',
                                  paste('Where should the left side be on the x-axis?',
                                        '(comma-separated)'),
                                  '0')),
        shinyjs::hidden(textInput('rectybottom',
                                  paste('Where should the lower side be on the y-axis?',
                                        '(comma-separated)'),
                                  '-0.05')),
        shinyjs::hidden(textInput('rectxright',
                                  paste('Where should the right side be on the x-axis?',
                                        'y-axis? (comma-separated)'),
                                  '0.5')),
        shinyjs::hidden(textInput('rectytop',
                                  paste('Where should the top side be on the y-axis',
                                        '(comma-separated)'),
                                  '0.05')),
        shinyjs::hidden(textInput('rectFill',
                                  'Fill color(s) (comma-separated)',
                                  NA)),
        shinyjs::hidden(textInput('rectColor',
                                  'Line color(s) (comma-separated)',
                                  'black')),
        shinyjs::hidden(textInput('rectLineType',
                                  'Line type(s) (comma-separated)',
                                  'solid')),
        shinyjs::hidden(textInput('rectLineWidth',
                                  'Line width(s) (comma-separated)',
                                  '1')),
        checkboxInput('annotBool', 'Add annotation(s)?', FALSE),
        shinyjs::hidden(textInput('annotComp',
                                  paste('Which plot component(s) should be annotated?',
                                        '(comma-separated)'),
                                  'sound')),
        shinyjs::hidden(textInput('annotLabel',
                                  'Label(s) (semicolon-separated)',
                                  'TEXT')),
        shinyjs::hidden(textInput('annotx',
                                  'Position(s) on the x-axis (comma-separated)',
                                  0)),
        shinyjs::hidden(textInput('annoty',
                                  'Position(s) on the y-axis (comma-separated)',
                                  0.1)),
        shinyjs::hidden(textInput('annotColor',
                                  'Color(s) (comma-separated)',
                                  'black')),
        shinyjs::hidden(textInput('annotFace',
                                  'Font face(s) (comma-separated)',
                                  '1')),
        shinyjs::hidden(textInput('annotSize',
                                  'Font size(s) (comma-separated)',
                                  '1'))
      )
    )
  ),
  downloadButton('download'),
  imageOutput('plot')
)
