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

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

typedef void OnProgressListener(double completed, double total);
typedef void OnResultListener(String result);

// An encapsulation of a large amount of synchronous processing.
//
// The choice of JSON parsing here is meant as an example that might surface
// in real-world applications.
class Calculator {
  Calculator({ this.onProgressListener, this.onResultListener, String data })
  // In order to keep the example files smaller, we "cheat" a little and
  // replicate our small json string into a 10,000-element array.
  : _data = _replicateJson(data, 10000) {
    assert(onProgressListener != null);
    assert(onResultListener != null);
  }

  final OnProgressListener onProgressListener;
  final OnResultListener onResultListener;
  final String _data;
  // This example assumes that the number of objects to parse is known in
  // advance. In a real-world situation, this might not be true; in that case,
  // the app might choose to display an indeterminate progress indicator.
  static const int _NUM_ITEMS = 110000;
  static const int _NOTIFY_INTERVAL = 1000;

  // Run the computation associated with this Calculator.
  void run() {
    int i = 0;
    JsonDecoder decoder = new JsonDecoder(
      (dynamic key, dynamic value) {
        if (key is int && i++ % _NOTIFY_INTERVAL == 0)
          onProgressListener(i.toDouble(), _NUM_ITEMS.toDouble());
        return value;
      }
    );
    try {
      List<dynamic> result = decoder.convert(_data);
      int n = result.length;
      onResultListener("Decoded $n results");
    } catch (e, stack) {
      print("Invalid JSON file: $e");
      print(stack);
    }
  }

  static String _replicateJson(String data, int count) {
    StringBuffer buffer = new StringBuffer()..write("[");
    for (int i = 0; i < count; i++) {
      buffer.write(data);
      if (i < count - 1)
        buffer.write(',');
    }
    buffer.write("]");
    return buffer.toString();
  }
}

// The current state of the calculation.
enum CalculationState {
  idle,
  loading,
  calculating
}

// Structured message to initialize the spawned isolate.
class CalculationMessage {
  CalculationMessage(this.data, this.sendPort);
  String data;
  SendPort sendPort;
}

// A manager for the connection to a spawned isolate.
//
// Isolates communicate with each other via ReceivePorts and SendPorts.
// This class manages these ports and maintains state related to the
// progress of the background computation.
class CalculationManager {
  CalculationManager({ this.onProgressListener, this.onResultListener })
  : _receivePort = new ReceivePort() {
    assert(onProgressListener != null);
    assert(onResultListener != null);
    _receivePort.listen(_handleMessage);
  }

  CalculationState _state = CalculationState.idle;
  CalculationState get state => _state;
  bool get isRunning => _state != CalculationState.idle;

  double _completed = 0.0;
  double _total = 1.0;

  final OnProgressListener onProgressListener;
  final OnResultListener onResultListener;

  // Start the background computation.
  //
  // Does nothing if the computation is already running.
  void start() {
    if (!isRunning) {
      _state = CalculationState.loading;
      _runCalculation();
    }
  }

  // Stop the background computation.
  //
  // Kills the isolate immediately, if spawned. Does nothing if the
  // computation is not running.
  void stop() {
    if (isRunning) {
      _state = CalculationState.idle;
      if (_isolate != null) {
        _isolate.kill(priority: Isolate.IMMEDIATE);
        _isolate = null;
        _completed = 0.0;
        _total = 1.0;
      }
    }
  }

  final ReceivePort _receivePort;
  Isolate _isolate;

  void _runCalculation() {
    // Load the JSON string. Note that this is done in the main isolate; at the
    // moment, spawned isolates do not have access to Mojo services, including
    // the root bundle (see https://github.com/flutter/flutter/issues/3294).
    // However, the loading process is asynchronous, so the UI will not block
    // while the file is loaded.
    rootBundle.loadString('services/data.json').then<Null>((String data) {
      if (isRunning) {
        final CalculationMessage message = new CalculationMessage(data, _receivePort.sendPort);
        // Spawn an isolate to JSON-parse the file contents. The JSON parsing
        // is synchronous, so if done in the main isolate, the UI would block.
        Isolate.spawn(_calculate, message).then<Null>((Isolate isolate) {
          if (!isRunning) {
            isolate.kill(priority: Isolate.IMMEDIATE);
          } else {
            _state = CalculationState.calculating;
            _isolate = isolate;
          }
        });
      }
    });
  }

  void _handleMessage(dynamic message) {
    if (message is List<double>) {
      _completed = message[0];
      _total = message[1];
      onProgressListener(_completed, _total);
    } else if (message is String) {
      _completed = 0.0;
      _total = 1.0;
      _isolate = null;
      _state = CalculationState.idle;
      onResultListener(message);
    }
  }

  // Main entry point for the spawned isolate.
  //
  // This entry point must be static, and its (single) argument must match
  // the message passed in Isolate.spawn above. Typically, some part of the
  // message will contain a SendPort so that the spawned isolate can
  // communicate back to the main isolate.
  //
  // Static and global variables are initialized anew in the spawned isolate,
  // in a separate memory space.
  static void _calculate(CalculationMessage message) {
    SendPort sender = message.sendPort;
    Calculator calculator = new Calculator(
      onProgressListener: (double completed, double total) {
        sender.send(<double>[ completed, total ]);
      },
      onResultListener: (String result) {
        sender.send(result);
      },
      data: message.data
    );
    calculator.run();
  }
}

// Main app widget.
//
// The app shows a simple UI that allows control of the background computation,
// as well as an animation to illustrate that the UI does not block while this
// computation is performed.
//
// This is a StatefulWidget in order to hold the CalculationManager and
// the AnimationController for the running animation.
class IsolateExampleWidget extends StatefulWidget {
  @override
  IsolateExampleState createState() => new IsolateExampleState();
}

// Main application state.
class IsolateExampleState extends State<StatefulWidget> with SingleTickerProviderStateMixin {

  String _status = 'Idle';
  String _label = 'Start';
  String _result = ' ';
  double _progress = 0.0;
  AnimationController _animation;
  CalculationManager _calculationManager;

  @override
  void initState() {
    super.initState();
    _animation = new AnimationController(
      duration: const Duration(milliseconds: 3600),
      vsync: this,
    )..repeat();
    _calculationManager = new CalculationManager(
      onProgressListener: _handleProgressUpdate,
      onResultListener: _handleResult
    );
  }

  @override
  void dispose() {
    _animation.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Material(
      child: new Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          new RotationTransition(
            turns: _animation,
            child: new Container(
              width: 120.0,
              height: 120.0,
              decoration: const BoxDecoration(
                backgroundColor: const Color(0xFF882222)
              )
            )
          ),
          new Opacity(
            opacity: _calculationManager.isRunning ? 1.0 : 0.0,
            child: new CircularProgressIndicator(
              value: _progress
            )
          ),
          new Text(_status),
          new Center(
            child: new RaisedButton(
              child: new Text(_label),
              onPressed: _handleButtonPressed
            )
          ),
          new Text(_result)
        ]
      )
    );
  }

  void _handleProgressUpdate(double completed, double total) {
    _updateState(' ', completed / total);
  }

  void _handleResult(String result) {
    _updateState(result, 0.0);
  }

  void _handleButtonPressed() {
    if (_calculationManager.isRunning)
      _calculationManager.stop();
    else
      _calculationManager.start();
    _updateState(' ', 0.0);
  }

  String _getStatus(CalculationState state) {
      switch(state) {
        case CalculationState.loading:
          return 'Loading...';
        case CalculationState.calculating:
          return 'In Progress';
        case CalculationState.idle:
        default:
          return 'Idle';
      }
  }

  void _updateState(String result, double progress) {
    setState(() {
      _result = result;
      _progress = progress;
      _label = _calculationManager.isRunning ? 'Stop' : 'Start';
      _status = _getStatus(_calculationManager.state);
    });
  }
}

void main() {
  runApp(new MaterialApp(home: new IsolateExampleWidget()));
}
