// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/widgets.dart';

import 'constants.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'material.dart';
import 'theme.dart';
import 'typography.dart';

class ToolBar extends StatelessComponent {
  ToolBar({
    Key key,
    this.left,
    this.center,
    this.right,
    this.flexibleSpace,
    this.foregroundOpacity: 1.0,
    this.tabBar,
    this.elevation: 4,
    this.backgroundColor,
    this.textTheme,
    this.padding: EdgeDims.zero
  }) : super(key: key) {
    assert((flexibleSpace != null) ? tabBar == null : true);
    assert((tabBar != null) ? flexibleSpace == null : true);
  }

  final Widget left;
  final Widget center;
  final List<Widget> right;
  final WidgetBuilder flexibleSpace;
  final double foregroundOpacity;
  final Widget tabBar;
  final int elevation;
  final Color backgroundColor;
  final TextTheme textTheme;
  final EdgeDims padding;

  ToolBar copyWith({
    Key key,
    Widget left,
    Widget center,
    List<Widget> right,
    WidgetBuilder flexibleSpace,
    double foregroundOpacity,
    int elevation,
    Color backgroundColor,
    TextTheme textTheme,
    EdgeDims padding
  }) {
    return new ToolBar(
      key: key ?? this.key,
      left: left ?? this.left,
      center: center ?? this.center,
      right: right ?? this.right,
      flexibleSpace: flexibleSpace ?? this.flexibleSpace,
      foregroundOpacity: foregroundOpacity ?? this.foregroundOpacity,
      tabBar: tabBar ?? this.tabBar,
      elevation: elevation ?? this.elevation,
      backgroundColor: backgroundColor ?? this.backgroundColor,
      textTheme: textTheme ?? this.textTheme,
      padding: padding ?? this.padding
    );
  }

  Widget build(BuildContext context) {
    Color color = backgroundColor;
    IconThemeData iconThemeData;
    TextStyle centerStyle = textTheme?.title;
    TextStyle sideStyle = textTheme?.body1;

    if (color == null || iconThemeData == null || textTheme == null) {
      ThemeData themeData = Theme.of(context);
      color ??= themeData.primaryColor;
      iconThemeData ??= themeData.primaryIconTheme;

      TextTheme primaryTextTheme = themeData.primaryTextTheme;
      centerStyle ??= primaryTextTheme.title;
      sideStyle ??= primaryTextTheme.body2;
    }

    if (foregroundOpacity != 1.0) {
      final int alpha = (foregroundOpacity.clamp(0.0, 1.0) * 255.0).round();
      if (centerStyle?.color != null)
        centerStyle = centerStyle.copyWith(color: centerStyle.color.withAlpha(alpha));
      if (sideStyle?.color != null)
        sideStyle = sideStyle.copyWith(color: sideStyle.color.withAlpha(alpha));
      if (iconThemeData != null) {
        iconThemeData = new IconThemeData(
          opacity: foregroundOpacity * iconThemeData.clampedOpacity,
          color: iconThemeData.color
        );
      }
    }

    final List<Widget> toolBarRow = <Widget>[];
    if (left != null)
      toolBarRow.add(left);
    toolBarRow.add(
      new Flexible(
        child: new Padding(
          padding: new EdgeDims.only(left: 24.0),
          child: center != null ? new DefaultTextStyle(style: centerStyle, child: center) : null
        )
      )
    );
    if (right != null)
      toolBarRow.addAll(right);

    EdgeDims combinedPadding = new EdgeDims.symmetric(horizontal: 8.0);
    if (padding != null)
      combinedPadding += padding;

    // If the toolBar's height shrinks below toolBarHeight, it will be clipped and bottom
    // justified. This is so that the toolbar appears to move upwards as its height is reduced.
    final double toolBarHeight = kToolBarHeight + combinedPadding.top + combinedPadding.bottom;
    final Widget toolBar = new ConstrainedBox(
      constraints: new BoxConstraints(maxHeight: toolBarHeight),
      child: new Padding(
        padding: new EdgeDims.only(left: combinedPadding.left, right: combinedPadding.right),
        child: new ClipRect(
          child: new OverflowBox(
            alignment: const FractionalOffset(0.0, 1.0), // bottom justify
            minHeight: toolBarHeight,
            maxHeight: toolBarHeight,
            child: new DefaultTextStyle(
              style: sideStyle,
              child: new Padding(
                padding: new EdgeDims.only(top: combinedPadding.top, bottom: combinedPadding.bottom),
                child: new Row(children: toolBarRow)
              )
            )
          )
        )
      )
    );

    Widget appBar = toolBar;
    if (tabBar != null) {
      appBar = new Column(
        justifyContent: FlexJustifyContent.collapse,
        children: <Widget>[toolBar, tabBar]
      );
    } else if (flexibleSpace != null) {
      appBar = new Stack(
        children: <Widget>[
          flexibleSpace(context),
          new Align(child: toolBar, alignment: const FractionalOffset(0.0, 0.0))
        ]
      );
    }

    Widget contents = new Material(
      color: color,
      elevation: elevation,
      child: appBar
    );

    if (iconThemeData != null)
      contents = new IconTheme(data: iconThemeData, child: contents);

    return contents;
  }

}