<!--
 * Copyright (C) 2023 WYATT GROUP
 * Please see the AUTHORS file for details.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
-->

# Flutter - Wyatt I18n

<p align="left">
  <a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis"><img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" /></a>
  <img src="https://img.shields.io/badge/SDK-Flutter-blue?style=flat-square" alt="SDK: Flutter" />
</p>

This package aims to facilitate and improve the internationalization of your applications. It allows, among other things, to load translation files on the fly during the execution of the application.

## Features

* Load translation files
  + [x] Load translation files from assets
  + [x] Load translation files from the network
  + [ ] Load translation files from the file system
  + [ ] Load translation files from multiple sources

* Supports multiple formats
  + [x] Supports JSON format
  + [x] Supports YAML format
  + [x] Supports ARB formats
  + [ ] Supports CSV format
  + [x] Supports custom formats parsers (see Parser class)

* Usage
  + [x] Detects the current locale
  + [x] Act as a LocalizationDelegate
  + [x] Act as a DataSource (in the sense of the Wyatt Architecture)

* Other
  + [ ] Generate translation constants from fallback translation files

## Usage

You can use this package as a LocalizationDelegate or as a DataSource.

### As a LocalizationDelegate

It is recommended to use this package as a LocalizationDelegate. This allows you to use the `context.i18n` method to translate your strings. It follows the standard of the `flutter_localizations` package and you can use it in the MaterialApp widget as follows:

```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        I18nDelegate(
          dataSource: NetworkI18nDataSourceImpl(
            baseUri: 'https://i18n.wyatt-studio.fr/apps/flutter_demo',
          ),
          localeTransformer: (locale) => locale.languageCode,
        ),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      supportedLocales: [
        Locale('en'),
        Locale('fr'),
      ],
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
```

And in your widgets:

```dart
Text(context.i18n('youHavePushed', {'count': 42})),
// => 'You have pushed the button this many times: 42' in English
// => 'Vous avez appuyé sur le bouton ce nombre de fois: 42' in French
```

### As a DataSource

This gives you more control over the internationalization of your application. You can handle the loading of the translation files yourself.

For example, if you want to create a Repository that will handle the loading of the translation files, you can do it.

Provide DataSource with GetIt:

```dart
// Initialize i18n
final I18nDataSource i18nDataSource =
    await AssetsI18nDataSourceImpl.withSystemLocale(
  basePath: 'l10n',
  baseName: 'intl',
  localeTransformer: (locale) => locale.languageCode,
);

// Initialize real sources/services
GetIt.I.registerLazySingleton<I18nDataSource>(
  () => i18nDataSource,
);
```

Create a Repository:

```dart
class I18nRepository {
  I18nRepository({
    required this.dataSource,
  });
  
  final I18nDataSource dataSource;

  Future<I18n> load() async {
    final i18n = await dataSource.load();
    return i18n;
  }
}
```

And use it in your cubit:

```dart
class MyCubit extends Cubit<MyState> {
  MyCubit({
    required this.i18nRepository,
  }) : super(MyState());

  final I18nRepository i18nRepository;

  Future<void> loadI18n() async {
    final i18n = await i18nRepository.load();
    emit(state.copyWith(i18n: i18n));
  }
}
```

> Note: you should create a cache system to avoid reloading the translation files every time.
