// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as m from 'mithril';

export const Sidebar: m.Component<{}, {expanded: boolean[]}> = {
  oninit() {
    this.expanded = [true, false, false, false];
  },
  view() {
    return m(
        'nav.sidebar',
        m('header', 'Perfetto'),
        m(`section${this.expanded[0] ? '.expanded' : ''}`,
          {onclick: () => this.expanded[0] = !this.expanded[0]},
          m('h1', 'Traces'),
          m('h2', 'Open or record a trace'),
          m('.section-content',
            m('ul',
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'folder_open'),
                  'Open Trace File')),
              m('li',
                m('a[href=/viewer]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'art_track'),
                  'View Trace')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'fiber_smart_record'),
                  'Record new trace')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'share'),
                  'Share current trace'))))),
        m(`section${this.expanded[1] ? '.expanded' : ''}`,
          {onclick: () => this.expanded[1] = !this.expanded[1]},
          m('h1', 'Workspaces'),
          m('h2', 'Custom and pre-arranged views'),
          m('.section-content',
            m('ul',
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'art_track'),
                  'Big Picture')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'apps'),
                  'Apps and process')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'storage'),
                  'Storage and I/O')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'library_add'),
                  'Add custom...'))))),
        m(`section${this.expanded[2] ? '.expanded' : ''}`,
          {onclick: () => this.expanded[2] = !this.expanded[2]},
          m('h1', 'Tracks and Views'),
          m('h2', 'Add new tracks to the workspace'),
          m('.section-content',
            m('ul',
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'touch_app'),
                  'User interactions')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'perm_device_information'),
                  'Device info')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'blur_linear'),
                  'Scheduler trace')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'equalizer'),
                  'Process list')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'battery_alert'),
                  'Battern & power'))))),
        m(`section${this.expanded[3] ? '.expanded' : ''}`,
          {onclick: () => this.expanded[3] = !this.expanded[3]},
          m('h1', 'Metrics and Auditors'),
          m('h2', 'Summary analysis of the trace'),
          m('.section-content',
            m('ul',
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'table_chart'),
                  'CPU usage breakdown')),
              m('li',
                m('a[href=/]',
                  {oncreate: m.route.link},
                  m('i.material-icons', 'memory'),
                  'Memory breakdown'))))));
  }
};