<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="using:DodoSSH.Client.Shell.ViewModels"
             xmlns:views="using:DodoSSH.Client.Android.Views"
             x:Class="DodoSSH.Client.Android.Views.TerminalScreen"
             x:DataType="vm:MainWindowViewModel"
             Background="{StaticResource Canvas}">

  <!--
    Design 03 — TERMINAL.

    One WebView for every session, exactly as on the desktop and for the same reason: each session is a pane
    inside the one page, so switching tabs is a single frame rather than a second browser. On a phone the
    argument is stronger — a WebView per tab would be several hundred megabytes on a device that will
    reclaim them.

    The tab strip is horizontal-scrolling rather than wrapping. Wrapping would reflow the terminal every
    time a tab opened, which is the one thing a terminal must not do while output is arriving.
  -->

  <Grid RowDefinitions="Auto,Auto,*,Auto">

    <!-- ============ tabs ============ -->
    <Border Grid.Row="0" Background="{StaticResource Chrome}" BorderBrush="{StaticResource Border}"
            BorderThickness="0,0,0,1">
      <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
        <StackPanel Orientation="Horizontal" Height="44">
          <ItemsControl ItemsSource="{Binding Tabs}">
            <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate><StackPanel Orientation="Horizontal" /></ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
              <DataTemplate x:DataType="vm:TerminalTabViewModel">
                <Grid ColumnDefinitions="Auto,Auto">
                  <Button Grid.Column="0" Classes="row" MinHeight="44" Padding="12,0"
                          Command="{Binding $parent[views:TerminalScreen].((vm:MainWindowViewModel)DataContext).SelectTabCommand}"
                          CommandParameter="{Binding}">
                    <StackPanel Orientation="Horizontal" Spacing="7" VerticalAlignment="Center">
                      <!-- Green only while there is a shell behind it; see the same dot in PhoneShell. -->
                      <Ellipse Classes="dot" Classes.live="{Binding IsLive}" Width="5" Height="5"
                               VerticalAlignment="Center" />
                      <TextBlock Classes="mono" FontSize="11" Text="{Binding Label}" />
                    </StackPanel>
                  </Button>
                  <!--
                    The close cross is inside the tab, which the plan calls out: a strip-level close would
                    act on whichever tab happened to be selected, and on a phone that is a mis-tap away from
                    killing the wrong shell.
                  -->
                  <Button Grid.Column="1" Classes="row" MinHeight="44" Width="34" Padding="0"
                          HorizontalContentAlignment="Center"
                          Command="{Binding $parent[views:TerminalScreen].((vm:MainWindowViewModel)DataContext).CloseTabCommand}"
                          CommandParameter="{Binding}">
                    <TextBlock Text="×" Foreground="{StaticResource TextFaint}" FontSize="14" />
                  </Button>
                </Grid>
              </DataTemplate>
            </ItemsControl.ItemTemplate>
          </ItemsControl>
        </StackPanel>
      </ScrollViewer>
    </Border>

    <!-- ============ the connection line ============ -->
    <Border Grid.Row="1" Background="{StaticResource Panel}" BorderBrush="{StaticResource BorderSubtle}"
            BorderThickness="0,0,0,1" Padding="14,5"
            IsVisible="{Binding SelectedTab, Converter={x:Static ObjectConverters.IsNotNull}}">
      <TextBlock Classes="detail" FontSize="9.5" TextTrimming="CharacterEllipsis"
                 Text="{Binding SelectedTab.Address}" />
    </Border>

    <!-- ============ the renderer ============ -->
    <Panel Grid.Row="2">

      <!--
        The empty state, and it says what the surface is for rather than that it is empty. A phone opens
        here on a cold start, so this is the first thing a new user reads.
      -->
      <StackPanel IsVisible="{Binding !HasTabs}" VerticalAlignment="Center" Margin="24" Spacing="10">
        <TextBlock Classes="title" FontSize="13" Text="NO SHELL OPEN" />
        <TextBlock Classes="body"
                   Text="Choose a host and press CONNECT. A shell opened here keeps running while the app is in the background, and keeps running after the keychain is locked — a notification says so for as long as one is alive." />
      </StackPanel>

      <!--
        A tab with no pane behind it: one still connecting, or one that was refused. The desktop head draws
        the same thing in its own ConnectingCard, and it exists for the same reason — connecting does not
        hold the application still any more, so there is a stretch in which a tab is selected and there is
        nothing yet to render in it. A phone needs it more than a desktop does: mobile links are slower, and
        the alternative is a black rectangle.
      -->
      <StackPanel IsVisible="{Binding IsConnectingShowing}" VerticalAlignment="Center" Margin="24"
                  Spacing="10">
        <TextBlock Classes="title" FontSize="13" Text="{Binding SelectedTab.Label}" />
        <TextBlock Classes="body" Text="{Binding SelectedTab.Status}" />
        <Button Classes="row" MinHeight="44" Padding="14,0" HorizontalAlignment="Left"
                Command="{Binding CloseTabCommand}" CommandParameter="{Binding SelectedTab}">
          <TextBlock Classes="label" FontSize="9" Text="CLOSE THIS TAB" />
        </Button>
      </StackPanel>

      <!--
        Collapsed rather than merely covered when there is no pane to show. On Windows this control is a
        native child window that composites above everything Avalonia draws, which is why the desktop head
        hides it explicitly; whether Android's WebView does the same is recorded as unverified in
        docs/android-port.md. Hiding it either way costs nothing and is correct under both answers.

        IsTerminalShowing rather than HasTabs, which are no longer the same question: a tab that is still
        connecting has no pane, and showing the renderer for it would show the previous session's output
        under the name of a machine nothing has connected to yet.
      -->
      <NativeWebView x:Name="Renderer" IsVisible="{Binding IsTerminalShowing, FallbackValue=False}" />
    </Panel>

    <!-- ============ accessory keys ============ -->
    <!--
      The row every Android SSH client ships, and the reason is not preference: a software keyboard has no
      Ctrl, no Esc, no Tab and no arrows, and without them a phone cannot interrupt a process, complete a
      path, or reach the previous command. Ctrl and Alt latch — pressed once they apply to the next key and
      then release, because holding a modifier while typing is not possible one-thumbed.
    -->
    <!-- Only with a pane to type into: the keys send bytes at a session, and a connecting tab has none. -->
    <Border Grid.Row="3" Background="{StaticResource Chrome}" BorderBrush="{StaticResource Border}"
            BorderThickness="0,1,0,0" IsVisible="{Binding IsTerminalShowing}">
      <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
        <StackPanel x:Name="AccessoryKeys" Orientation="Horizontal" Height="44" Spacing="4"
                    Margin="6,5" />
      </ScrollViewer>
    </Border>

  </Grid>

</UserControl>
