// Copyright 2019 The Flutter team. 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/gestures.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

import 'package:gallery/l10n/gallery_localizations.dart';

void showAboutDialog({
  @required BuildContext context,
}) {
  assert(context != null);
  showDialog<void>(
    context: context,
    builder: (context) {
      return _AboutDialog();
    },
  );
}

class _AboutDialog extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;
    final textTheme = Theme.of(context).textTheme;
    final bodyTextStyle = textTheme.body2.apply(color: colorScheme.onPrimary);

    final name = 'Flutter Gallery'; // Don't need to localize.
    final legalese = '© 2019 The Flutter team'; // Don't need to localize.
    final samplesRepo =
        GalleryLocalizations.of(context).aboutFlutterSamplesRepo;
    // TODO: Determine why this doesn't work consistently.
    // Certain versions of iOS/macOS aren't rendering the raw string correctly.
    final seeSource =
        GalleryLocalizations.of(context).aboutDialogDescription(samplesRepo);
    final samplesRepoIndex = seeSource.indexOf(samplesRepo);
    final samplesRepoIndexEnd = samplesRepoIndex + samplesRepo.length;
    String seeSourceFirst;
    String seeSourceSecond;
    if (samplesRepoIndex > -1 && samplesRepoIndex > -1) {
      seeSourceFirst = seeSource.substring(0, samplesRepoIndex);
      seeSourceSecond = seeSource.substring(samplesRepoIndexEnd);
    } else {
      seeSourceFirst = 'To see the source code for this app, please visit the ';
      seeSourceSecond = '.';
    }

    return AlertDialog(
      backgroundColor: colorScheme.background,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
      content: Container(
        constraints: BoxConstraints(maxWidth: 400),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: [
            Center(
              child: Text(
                '$name',
                style: textTheme.display1.apply(color: colorScheme.onPrimary),
              ),
            ),
            SizedBox(height: 24),
            RichText(
              text: TextSpan(
                children: [
                  TextSpan(
                    style: bodyTextStyle,
                    text: seeSourceFirst,
                  ),
                  TextSpan(
                    style: bodyTextStyle.copyWith(
                      color: colorScheme.primary,
                    ),
                    text: samplesRepo,
                    recognizer: TapGestureRecognizer()
                      ..onTap = () async {
                        final url = 'https://github.com/flutter/samples/';
                        if (await canLaunch(url)) {
                          await launch(
                            url,
                            forceSafariVC: false,
                          );
                        }
                      },
                  ),
                  TextSpan(
                    style: bodyTextStyle,
                    text: seeSourceSecond,
                  ),
                ],
              ),
            ),
            SizedBox(height: 18),
            Text(
              legalese,
              style: bodyTextStyle,
            ),
          ],
        ),
      ),
      actions: [
        FlatButton(
          textColor: colorScheme.primary,
          child: Text(
            MaterialLocalizations.of(context).viewLicensesButtonLabel,
          ),
          onPressed: () {
            Navigator.of(context).push(MaterialPageRoute<void>(
              builder: (context) => Theme(
                data: Theme.of(context).copyWith(
                  textTheme:
                      Typography(platform: Theme.of(context).platform).black,
                  scaffoldBackgroundColor: Colors.white,
                ),
                child: LicensePage(
                  applicationName: name,
                  applicationLegalese: legalese,
                ),
              ),
            ));
          },
        ),
        FlatButton(
          textColor: colorScheme.primary,
          child: Text(MaterialLocalizations.of(context).closeButtonLabel),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ],
    );
  }
}
