// Copyright 2016 The Vanadium 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 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

class BakuDistro extends StatefulWidget {
  @override
  _BakuDistroState createState() => new _BakuDistroState();
}

class _Device {
  String name, description;

  _Device(this.name, this.description);
}

class _BakuDistroState extends State<BakuDistro> {
  _BakuDistroState() {
    HostMessages.addMessageHandler('deviceOnline', _onDeviceOnline);
    HostMessages.addMessageHandler('deviceOffline', _onDeviceOffline);
    HostMessages.addMessageHandler('castTerminated', _onCastTerminated);
  }

  final Map<String, String> devices = {};
  final Set<String> castTargets = new Set();

  Future<String> _onDeviceOnline(final String json) async {
    final Map<String, dynamic> message = JSON.decode(json);
    setState(() => devices[message['name']] = message['description']);
    return null;
  }

  Future<String> _onDeviceOffline(final String name) async {
    setState(() {
      devices.remove(name);
      castTargets.remove(name);
    }devices.remove(name));
    if (castTargetName == name) {
      terminateCast();
    }
    return null;
  }

  InputValue _data = InputValue.empty;

  InputValue get data => _data;

  void set data(final InputValue value) {
    if (_data != value) {
      final InputValue oldData = _data;
      setState(() => _data = value);

      if (castTargetName != null && oldData.text != value.text ) {
        HostMessages.sendToHost('updateCast', getCastData())
            .catchError(_handleCastError);
      }
    }
  }

  String getCastData() {
    return JSON.encode({
      'name': castTargetName,
      'data': data.text
    });
  }

  String _castTargetName;

  String get castTargetName => _castTargetName;

  void set castTargetName(final String value) {
    if (_castTargetName != value) {
      initiateCast(value);
    }
  }

  void initiateCast(final String target) {
    terminateCast();
    if (target != null) {
      setState(() => _castTargetName = target);
      HostMessages.sendToHost('initiateCast', getCastData())
          .catchError(_handleCastError);
    }
  }

  void terminateCast() {
    if (_castTargetName != null) {
      HostMessages.sendToHost('terminateCast', _castTargetName);
      setState(() => _castTargetName = null);
    }
  }

  Future<String> _onCastTerminated(final String name) async {
    if (castTargetName == name) {
      terminateCast();
    }
    return null;
  }

  void _handleCastError(final Object e) {
    terminateCast();
    Scaffold.of(context).showSnackBar(
        new SnackBar(content: new Text(e.toString())));
  }

  @override
  Widget build(final BuildContext context) {
    final List<_Device> sortedDevices = devices.keys.map((name) =>
    new _Device(name, devices[name])).toList(growable: false);
    sortedDevices.sort((a, b) => a.description.compareTo(b.description));

    final List<Widget> layout = [];

    if (castTargetName == null) {
      final TextStyle style = Theme.of(context).textTheme.display1;

      layout.add(new Padding(
        padding: new EdgeInsets.all(8.0),
        child: data.text.isEmpty?
        new Text('No content', style:
        style.copyWith(color: Theme.of(context).disabledColor)) :
        new Text(data.text, style: style)
      ));
    }

    layout.add(new Input(
      value: data,
      labelText: 'Text content',
      onChanged: (value) => data = value
    ));

    if (castTargetName == null) {
      layout.add(new MaterialList(
        type: MaterialListType.oneLine,
        children: sortedDevices.map((d) => new ListItem(
          title: new Text(d.description),
          onTap: () => castTargetName = d.name
        ))
      ));
    } else {
      layout.add(new RaisedButton(
        child: new Text('Recall'),
        onPressed: terminateCast
      ));
    }

    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Baku Distro Example')
      ),
      body: new Column(children: layout)
    );
  }
}