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

// TODO(goderbauer): Restructure the examples to avoid this ignore, https://github.com/flutter/flutter/issues/110208.
// ignore_for_file: avoid_implementing_value_types

import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;
import '../shared/markdown_demo_widget.dart';

// ignore_for_file: public_member_api_docs

// Markdown source data showing the use of subscript tags.
const String _data = '''
## Subscript Syntax

NaOH + Al_2O_3 = NaAlO_2 + H_2O

C_4H_10 = C_2H_6 + C_2H_4
''';

const String _notes = """
# Subscript Syntax Demo
---

## Overview

This is an example of how to create an inline syntax parser with an
associated element builder. This example defines an inline syntax parser that
matches instances of an underscore character "**_**" followed by a integer
numerical value. When the parser finds a match for this syntax sequence,
a '**sub**' element is inserted into the abstract syntac tree. The supplied
builder for the '**sub**' element, SubscriptBuilder, is then called to create
an appropriate RichText widget for the formatted output.

## Usage

To support a new custom inline Markdown tag, an inline syntax object needs to be
defined for the Markdown parser and an element builder which is deligated the
task of building the appropriate Flutter widgets for the resulting Markdown
output. Instances of these objects need to be provided to the Markdown widget.

```
  Markdown(
    data: _data,
    builders: {
      'sub': SubscriptBuilder(),
    },
    extensionSet: md.ExtensionSet([], [SubscriptSyntax()]),
  );
```

### Inline Syntax Class

```
class SubscriptSyntax extends md.InlineSyntax {
  static final _pattern = r'_([0-9]+)';

  SubscriptSyntax() : super(_pattern);

  @override
  bool onMatch(md.InlineParser parser, Match match) {
    parser.addNode(md.Element.text('sub', match[1]));
    return true;
  }
```

### Markdown Element Builder

```
class SubscriptBuilder extends MarkdownElementBuilder {
  static const List<String> _subscripts = [
    '₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉'
  ];

  @override
  Widget visitElementAfter(md.Element element, TextStyle preferredStyle) {
    String textContent = element.textContent;
    String text = '';
    for (int i = 0; i < textContent.length; i++) {
      text += _subscripts[int.parse(textContent[i])];
    }
    return SelectableText.rich(TextSpan(text: text));
  }
}
```
""";

/// The subscript syntax demo provides an example of creating an inline syntax
/// object which defines the syntax for the Markdown inline parser and an
/// accompanying Markdown element builder object to handle subscript tags.
class SubscriptSyntaxDemo extends StatelessWidget
    implements MarkdownDemoWidget {
  const SubscriptSyntaxDemo({Key? key}) : super(key: key);

  static const String _title = 'Subscript Syntax Demo';

  @override
  String get title => SubscriptSyntaxDemo._title;

  @override
  String get description => 'An example of how to create a custom inline '
      'syntax parser and element builder for numerical subscripts.';

  @override
  Future<String> get data => Future<String>.value(_data);

  @override
  Future<String> get notes => Future<String>.value(_notes);

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: data,
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return Markdown(
            data: snapshot.data!,
            builders: <String, MarkdownElementBuilder>{
              'sub': SubscriptBuilder(),
            },
            extensionSet: md.ExtensionSet(
                <md.BlockSyntax>[], <md.InlineSyntax>[SubscriptSyntax()]),
          );
        } else {
          return const CircularProgressIndicator();
        }
      },
    );
  }
}

class SubscriptBuilder extends MarkdownElementBuilder {
  static const List<String> _subscripts = <String>[
    '₀',
    '₁',
    '₂',
    '₃',
    '₄',
    '₅',
    '₆',
    '₇',
    '₈',
    '₉'
  ];

  @override
  Widget visitElementAfter(md.Element element, TextStyle? preferredStyle) {
    // We don't currently have a way to control the vertical alignment of text spans.
    // See https://github.com/flutter/flutter/issues/10906#issuecomment-385723664
    final String textContent = element.textContent;
    String text = '';
    for (int i = 0; i < textContent.length; i++) {
      text += _subscripts[int.parse(textContent[i])];
    }
    return SelectableText.rich(TextSpan(text: text));
  }
}

class SubscriptSyntax extends md.InlineSyntax {
  SubscriptSyntax() : super(_pattern);

  static const String _pattern = r'_([0-9]+)';

  @override
  bool onMatch(md.InlineParser parser, Match match) {
    parser.addNode(md.Element.text('sub', match[1]!));
    return true;
  }
}
