<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.PhoneShell"
             x:DataType="vm:MainWindowViewModel"
             Background="{StaticResource Canvas}">

  <!--
    The phone's single view, and the counterpart of the desktop head's MainWindow — except that this one has
    no window, no nav rail, no titlebar and no status bar.

    It switches on ShellState, which is the same six states the desktop has because both heads share one
    state machine. What differs is only what each one draws.

    The nav rail's eight destinations become four in a bottom bar. That is not a reflow: the plan says five
    characters was a desktop constraint and the phone can use words, and it also says a phone cannot carry
    eight. What is here is what the decided scope needs — the keychain and a terminal — and the destinations
    behind the other four are reachable from those two rather than being hidden.
  -->

  <Panel>

    <!-- ============ getting in ============ -->
    <views:PendingScreen IsVisible="{Binding IsStarting}"
                         Heading="OPENING THE KEYCHAIN"
                         Detail="Reading this phone's local cache to find out whether it is enrolled." />

    <views:ServerScreen IsVisible="{Binding IsNeedingServer}" />
    <views:EnrollScreen IsVisible="{Binding IsNeedingEnrollment}" />
    <views:RecoveryCodeScreen IsVisible="{Binding IsShowingRecoveryCode}" />
    <views:LockedScreen IsVisible="{Binding IsLocked}" />

    <!-- ============ unlocked ============ -->
    <Grid IsVisible="{Binding IsUnlocked}" RowDefinitions="Auto,*,Auto,Auto">

      <!-- The header: which vault, and whether it is synced. -->
      <Border Grid.Row="0" Background="{StaticResource Chrome}" BorderBrush="{StaticResource Border}"
              BorderThickness="0,0,0,1" Padding="16,0" Height="52">
        <Grid ColumnDefinitions="Auto,*,Auto">
          <Border Grid.Column="0" Width="20" Height="20" BorderBrush="{StaticResource Accent}"
                  BorderThickness="1" VerticalAlignment="Center">
            <TextBlock Text="&gt;_" Foreground="{StaticResource Accent}"
                       FontFamily="{StaticResource MonoFont}" FontSize="9" FontWeight="SemiBold"
                       HorizontalAlignment="Center" VerticalAlignment="Center" />
          </Border>

          <StackPanel Grid.Column="1" Margin="10,0,0,0" VerticalAlignment="Center" Spacing="1">
            <TextBlock Classes="mono" FontSize="12" FontWeight="SemiBold"
                       Text="{Binding Vault.VaultName}" TextTrimming="CharacterEllipsis" />
            <StackPanel Orientation="Horizontal" Spacing="5">
              <Ellipse Classes="dot" Classes.live="{Binding IsFullySynced}" Width="5" Height="5"
                       VerticalAlignment="Center" />
              <TextBlock Classes="label" FontSize="8" Text="{Binding SyncLabel}" />
            </StackPanel>
          </StackPanel>

          <Button Grid.Column="2" Classes="row" Width="44" MinHeight="44" Padding="0"
                  HorizontalContentAlignment="Center" Command="{Binding LockCommand}">
            <TextBlock Text="LOCK" Classes="label" FontSize="8.5" Foreground="{StaticResource TextDim}" />
          </Button>
        </Grid>
      </Border>

      <!-- The screens. Only one draws; which one is the shell's business. -->
      <Panel Grid.Row="1">
        <!--
          Wrapped rather than bound directly, and the desktop head's MainWindow carries the same note for
          the same reason: this element's visibility is the shell's business and its data context is the
          vault, and putting both on one element resolves IsVisible against the vault — where
          IsHostsShowing does not exist. It is a compile error here rather than a silent blank screen only
          because compiled bindings are on.
        -->
        <Panel IsVisible="{Binding IsHostsShowing}">
          <views:HostsScreen DataContext="{Binding Vault}" />
        </Panel>
        <Panel IsVisible="{Binding IsVaultShowing}">
          <views:KeychainScreen DataContext="{Binding Vault}" />
        </Panel>
        <!--
          IsTerminalSurface rather than IsTerminalShowing: a tab exists from the moment connecting starts and
          its session does not, so this screen has to be on show while there is nothing to render — it is
          what says which machine is being connected to. Which of the two things inside it draws is decided
          in the screen itself. See TerminalTabViewModel.
        -->
        <views:TerminalScreen IsVisible="{Binding IsTerminalSurface}" />

        <views:PendingScreen IsVisible="{Binding IsPreferencesShowing}"
                             Heading="PREFERENCES"
                             Detail="Registering this phone's device key, and signing out, are on the unlock screen for now. Importing an ~/.ssh/config has no meaning here — scoped storage means there is no such file to read." />
      </Panel>

      <!--
        ◆ The two host-key decisions, over everything. Outside the screen Panel deliberately: file transfer
        makes its own trust decision on the desktop, and when the phone grows that screen this must already
        be somewhere both can reach rather than nested inside one of them.
      -->
      <Panel Grid.Row="1">
        <views:HostKeySheet DataContext="{Binding Vault}" />
      </Panel>

      <!--
        The shells strip. The design puts it above the nav on every screen, and that is the single most
        desktop-shaped idea in the product — it is what makes a terminal a surface you switch to rather than
        a screen you navigate away from. Kept, because losing it would make an open shell invisible from the
        host list, which is where you are when you open the next one.
      -->
      <Border Grid.Row="2" IsVisible="{Binding HasTabs}" Background="{StaticResource Sidebar}"
              BorderBrush="{StaticResource Border}" BorderThickness="0,1,0,0" Height="46">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
          <StackPanel Orientation="Horizontal" Spacing="8" Margin="12,0" VerticalAlignment="Center">
            <TextBlock Classes="label" FontSize="8" Text="SHELLS" VerticalAlignment="Center" />
            <ItemsControl ItemsSource="{Binding Tabs}">
              <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate><StackPanel Orientation="Horizontal" Spacing="6" /></ItemsPanelTemplate>
              </ItemsControl.ItemsPanel>
              <ItemsControl.ItemTemplate>
                <DataTemplate x:DataType="vm:TerminalTabViewModel">
                  <Button Classes="row" MinHeight="32" Padding="10,6" CornerRadius="5"
                          Background="{StaticResource Field}"
                          Command="{Binding $parent[views:PhoneShell].((vm:MainWindowViewModel)DataContext).SelectTabCommand}"
                          CommandParameter="{Binding}">
                    <StackPanel Orientation="Horizontal" Spacing="6">
                      <!--
                        Green only while there is a shell behind the tab. It used to be lit unconditionally,
                        which was true when a tab could not exist without a session; one can now — connecting
                        opens the tab first — and a dot that was green before anything had answered would be
                        the one thing on this strip claiming something untrue.
                      -->
                      <Ellipse Classes="dot" Classes.live="{Binding IsLive}" Width="5" Height="5"
                               VerticalAlignment="Center" />
                      <TextBlock Classes="mono" FontSize="10" Text="{Binding Label}" />
                    </StackPanel>
                  </Button>
                </DataTemplate>
              </ItemsControl.ItemTemplate>
            </ItemsControl>
          </StackPanel>
        </ScrollViewer>
      </Border>

      <!-- ============ navigation ============ -->
      <Border Grid.Row="3" Background="{StaticResource Chrome}" BorderBrush="{StaticResource Border}"
              BorderThickness="0,1,0,0" Height="58">
        <Grid ColumnDefinitions="*,*,*,*">

          <views:NavButton Grid.Column="0" Label="HOSTS" IsCurrent="{Binding IsHostsShowing}"
                           Command="{Binding ShowScreenCommand}"
                           CommandParameter="{x:Static vm:ShellScreen.Hosts}" />

          <views:NavButton Grid.Column="1" Label="KEYCHAIN" IsCurrent="{Binding IsVaultShowing}"
                           Command="{Binding ShowScreenCommand}"
                           CommandParameter="{x:Static vm:ShellScreen.Vault}" />

          <!--
            The terminal is a surface rather than a page — see ShellSurface — so this one does not go
            through ShowScreen. Its own command is on the shell.
          -->
          <views:NavButton Grid.Column="2" Label="TERMINAL" IsCurrent="{Binding IsTerminalSurface}"
                           Command="{Binding ShowTerminalCommand}" />

          <views:NavButton Grid.Column="3" Label="MORE" IsCurrent="{Binding IsPreferencesShowing}"
                           Command="{Binding ShowScreenCommand}"
                           CommandParameter="{x:Static vm:ShellScreen.Preferences}" />

        </Grid>
      </Border>

    </Grid>

  </Panel>

</UserControl>
