// Copyright 2015 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:sky' as sky;

import 'package:sky/base/hit_test.dart';
import 'package:sky/base/scheduler.dart' as scheduler;
import 'package:sky/rendering/box.dart';
import 'package:sky/rendering/object.dart';
import 'package:sky/rendering/view.dart';

int _hammingWeight(int value) {
  if (value == 0)
    return 0;
  int weight = 0;
  for (int i = 0; i < value.bitLength; ++i) {
    if (value & (1 << i) != 0)
      ++weight;
  }
  return weight;
}

class PointerState {
  PointerState({ this.result, this.lastPosition });
  HitTestResult result;
  Point lastPosition;
}

typedef void EventListener(sky.Event event);

class SkyBinding {

  SkyBinding({ RenderBox root: null, RenderView renderViewOverride }) {
    assert(_instance == null);
    _instance = this;

    sky.view.setEventCallback(_handleEvent);

    sky.view.setMetricsChangedCallback(_handleMetricsChanged);
    scheduler.init();
    if (renderViewOverride == null) {
      _renderView = new RenderView(child: root, devicePixelRatio: sky.view.devicePixelRatio);
      _renderView.attach();
      _renderView.rootConstraints = _createConstraints();
      _renderView.scheduleInitialFrame();
    } else {
      _renderView = renderViewOverride;
    }
    assert(_renderView != null);
    scheduler.addPersistentFrameCallback(beginFrame);

    assert(_instance == this);
  }

  static SkyBinding _instance; // used to enforce that we're a singleton
  static SkyBinding get instance => _instance;

  RenderView _renderView;
  RenderView get renderView => _renderView;

  ViewConstraints _createConstraints() {
    return new ViewConstraints(size: new Size(sky.view.width, sky.view.height));
  }
  void _handleMetricsChanged() {
    _renderView.rootConstraints = _createConstraints();
  }

  RenderBox get root => _renderView.child;
  void set root(RenderBox value) {
    _renderView.child = value;
  }
  void beginFrame(double timeStamp) {
    RenderObject.flushLayout();
    _renderView.updateCompositingBits();
    RenderObject.flushPaint();
    _renderView.compositeFrame();
  }

  final List<EventListener> _eventListeners = new List<EventListener>();
  void addEventListener(EventListener e) => _eventListeners.add(e);
  bool removeEventListener(EventListener e) => _eventListeners.remove(e);

  void _handleEvent(sky.Event event) {
    if (event is sky.PointerEvent) {
      _handlePointerEvent(event);
    } else if (event is sky.GestureEvent) {
      dispatchEvent(event, hitTest(new Point(event.x, event.y)));
    } else {
      for (EventListener e in _eventListeners)
        e(event);
    }
  }

  Map<int, PointerState> _stateForPointer = new Map<int, PointerState>();

  PointerState _createStateForPointer(sky.PointerEvent event, Point position) {
    HitTestResult result = hitTest(position);
    PointerState state = new PointerState(result: result, lastPosition: position);
    _stateForPointer[event.pointer] = state;
    return state;
  }

  PointerState _getOrCreateStateForPointer(event, position) {
    PointerState state = _stateForPointer[event.pointer];
    if (state == null)
      state = _createStateForPointer(event, position);
    return state;
  }

  EventDisposition _handlePointerEvent(sky.PointerEvent event) {
    Point position = new Point(event.x, event.y);

    PointerState state = _getOrCreateStateForPointer(event, position);

    if (event.type == 'pointerup' || event.type == 'pointercancel') {
      if (_hammingWeight(event.buttons) <= 1)
        _stateForPointer.remove(event.pointer);
    }

    event.dx = position.x - state.lastPosition.x;
    event.dy = position.y - state.lastPosition.y;
    state.lastPosition = position;

    return dispatchEvent(event, state.result);
  }

  HitTestResult hitTest(Point position) {
    HitTestResult result = new HitTestResult();
    _renderView.hitTest(result, position: position);
    return result;
  }

  EventDisposition dispatchEvent(sky.Event event, HitTestResult result) {
    assert(result != null);
    EventDisposition disposition = EventDisposition.ignored;
    for (HitTestEntry entry in result.path.reversed) {
      EventDisposition entryDisposition = entry.target.handleEvent(event, entry);
      if (entryDisposition == EventDisposition.consumed)
        return EventDisposition.consumed;
      else if (entryDisposition == EventDisposition.processed)
        disposition = EventDisposition.processed;
    }
    return disposition;
  }

  String toString() => 'Render Tree:\n${_renderView}';

  void debugDumpRenderTree() {
    toString().split('\n').forEach(print);
  }

}
