// 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 = {};

  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));
    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)
    );
  }
}