// 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> {
  final Map<String, String> devices = {};
  InputValue _data = InputValue.empty;
  String _castTargetName;

  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 get castTargetName => _castTargetName;

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

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

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

  _BakuDistroState() {
    HostMessages.addMessageHandler('deviceOnline', _onDeviceOnline);
    HostMessages.addMessageHandler('deviceOffline', _onDeviceOffline);
  }

  @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) {
      layout.add(new Padding(
        padding: new EdgeInsets.all(8.0),
        child: data.text.isEmpty?
        new Text('No content', style:
        new TextStyle(color: Theme.of(context).disabledColor)) :
        new Text(data.text)
      ));
    }

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

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

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