// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library trydart.ui;

import 'dart:html';

import 'dart:async' show
    Future,
    Timer,
    scheduleMicrotask;

import 'cache.dart' show
    onLoad,
    updateCacheStatus;

import 'interaction_manager.dart' show InteractionManager;

import 'run.dart' show
    makeOutputFrame;

import 'themes.dart' show
    THEMES,
    Theme;

import 'samples.dart' show
    EXAMPLE_FIBONACCI,
    EXAMPLE_FIBONACCI_HTML,
    EXAMPLE_HELLO,
    EXAMPLE_HELLO_HTML,
    EXAMPLE_SUNFLOWER;

import 'settings.dart';

import 'user_option.dart';

import 'messages.dart' show messages;

import 'compilation_unit.dart' show
    CompilationUnit;

import 'compilation.dart' show
    currentSource;

// TODO(ahe): Make internal to buildUI once all interactions have been moved to
// the manager.
InteractionManager interaction;

DivElement mainEditorPane;
DivElement statusDiv;
PreElement outputDiv;
DivElement hackDiv;
IFrameElement outputFrame;
MutationObserver observer;
SpanElement cacheStatusElement;
Theme currentTheme = Theme.named(theme);

buildButton(message, action) {
  if (message is String) {
    message = new Text(message);
  }
  return new ButtonElement()
      ..onClick.listen(action)
      ..append(message);
}

buildTab(message, id, action) {
  if (message is String) {
    message = new Text(message);
  }

  onClick(MouseEvent event) {
    event.preventDefault();
    Element e = event.target;
    LIElement parent = e.parent;
    parent.parent.querySelector('li[class="active"]').classes.remove('active');
    parent.classes.add('active');
    action(event);
  }

  codeCallbacks[id] = action;

  return new OptionElement()..append(message)..id = id;
}

Map<String, Function> codeCallbacks = new Map<String, Function>();

void onCodeChange(Event event) {
  SelectElement select = event.target;
  String id = select.querySelectorAll('option')[select.selectedIndex].id;
  Function action = codeCallbacks[id];
  if (action != null) action(event);
  outputFrame.style.display = 'none';
  outputDiv.nodes.clear();
}

buildUI() {
  interaction = new InteractionManager();

  CompilationUnit.onChanged.listen(interaction.onCompilationUnitChanged);

  window.localStorage['currentSample'] = '$currentSample';

  buildCode(interaction);

  (mainEditorPane = new DivElement())
      ..classes.addAll(['mainEditorPane'])
      ..style.backgroundColor = currentTheme.background.color
      ..style.color = currentTheme.foreground.color
      ..style.font = codeFont
      ..spellcheck = false;

  mainEditorPane
      ..contentEditable = 'true'
      ..onKeyDown.listen(interaction.onKeyUp)
      ..onInput.listen(interaction.onInput);

  document.onSelectionChange.listen(interaction.onSelectionChange);

  var inputWrapper = new DivElement()
      ..append(mainEditorPane)
      ..classes.add('well')
      ..style.padding = '0px'
      ..style.overflowX = 'hidden'
      ..style.overflowY = 'scroll'
      ..style.position = 'relative'
      ..style.maxHeight = '80vh';

  var inputHeader = new DivElement()..appendText('Code');

  inputHeader.style
      ..right = '3px'
      ..top = '0px'
      ..position = 'absolute';
  inputWrapper.append(inputHeader);

  statusDiv = new DivElement();
  statusDiv.style
      ..left = '0px'
      ..top = '0px'
      ..position = 'absolute';
  inputWrapper.append(statusDiv);

  outputFrame =
      makeOutputFrame(
          Url.createObjectUrl(new Blob([''], 'application/javascript')));

  outputDiv = new PreElement();
  outputDiv.style
      ..backgroundColor = currentTheme.background.color
      ..color = currentTheme.foreground.color
      ..overflow = 'auto'
      ..padding = '1em'
      ..minHeight = '10em'
      ..whiteSpace = 'pre-wrap';

  var outputWrapper = new DivElement()
      ..append(outputDiv)
      ..style.position = 'relative';

  var consoleHeader = new DivElement()..appendText('Console');

  consoleHeader.style
      ..right = '3px'
      ..top = '0px'
      ..position = 'absolute';
  outputWrapper.append(consoleHeader);

  hackDiv = new DivElement();

  var saveButton = new ButtonElement()
      ..onClick.listen((_) {
        var blobUrl =
            Url.createObjectUrl(new Blob([mainEditorPane.text], 'text/plain'));
        var save = new AnchorElement(href: blobUrl);
        save.target = '_blank';
        save.download = 'untitled.dart';
        save.dispatchEvent(new Event.eventType('Event', 'click'));
      })
      ..style.position = 'absolute'
      ..style.right = '0px'
      ..appendText('Save');

  cacheStatusElement = document.getElementById('appcache-status');
  updateCacheStatus(null);

  var section = document.querySelector('article[class="homepage"]>section');

  DivElement tryColumn = document.getElementById('try-dart-column');
  DivElement runColumn = document.getElementById('run-dart-column');

  tryColumn.append(inputWrapper);
  outputFrame.style.display = 'none';
  runColumn.append(outputFrame);
  runColumn.append(outputWrapper);
  runColumn.append(hackDiv);

  var settingsElement = document.getElementById('settings');
  settingsElement.onClick.listen(openSettings);

  window.onMessage.listen(interaction.onWindowMessage);

  observer = new MutationObserver(interaction.onMutation)
      ..observe(
          mainEditorPane, childList: true, characterData: true, subtree: true);

  scheduleMicrotask(() {
    mainEditorPane.appendText(currentSource);
  });

  // You cannot install event handlers on window.applicationCache
  // until the window has loaded.  In dartium, that's later than this
  // method is called.
  window.onLoad.listen(onLoad);

  // However, in dart2js, the window has already loaded, and onLoad is
  // never called.
  onLoad(null);
}

buildCode(InteractionManager interaction) {
  var codePicker =
      document.getElementById('code-picker')
      ..style.visibility = 'hidden'
      ..onChange.listen(onCodeChange);
  var htmlGroup = new OptGroupElement()..label = 'HTML';
  var benchmarkGroup = new OptGroupElement()..label = 'Benchmarks';

  interaction.projectFileNames().then((List<String> names) {
    OptionElement none = new OptionElement()
        ..appendText('--')
        ..disabled = true;
    codePicker
        ..append(none)
        ..style.visibility = 'visible'
        ..selectedIndex = 0;

    for (String name in names) {
      codePicker.append(buildTab(name, name, (event) {
        interaction.onProjectFileSelected(name);
      }));
    }
  }).catchError((error) {
    codePicker.style.visibility = 'visible';
    OptionElement none = new OptionElement()
        ..appendText('Pick an example')
        ..disabled = true;
    codePicker.append(none);

    // codePicker.classes.addAll(['nav', 'nav-tabs']);
    codePicker.append(buildTab('Hello, World!', 'EXAMPLE_HELLO', (_) {
      mainEditorPane
          ..nodes.clear()
          ..appendText(EXAMPLE_HELLO);
    }));
    codePicker.append(buildTab('Fibonacci', 'EXAMPLE_FIBONACCI', (_) {
      mainEditorPane
          ..nodes.clear()
          ..appendText(EXAMPLE_FIBONACCI);
    }));
    codePicker.append(htmlGroup);
    // TODO(ahe): Restore benchmarks.
    // codePicker.append(benchmarkGroup);

    htmlGroup.append(
        buildTab('Hello, World!', 'EXAMPLE_HELLO_HTML', (_) {
      mainEditorPane
          ..nodes.clear()
          ..appendText(EXAMPLE_HELLO_HTML);
    }));
    htmlGroup.append(
        buildTab('Fibonacci', 'EXAMPLE_FIBONACCI_HTML', (_) {
      mainEditorPane
          ..nodes.clear()
          ..appendText(EXAMPLE_FIBONACCI_HTML);
    }));
    htmlGroup.append(buildTab('Sunflower', 'EXAMPLE_SUNFLOWER', (_) {
      mainEditorPane
          ..nodes.clear()
          ..appendText(EXAMPLE_SUNFLOWER);
    }));

    benchmarkGroup.append(buildTab('DeltaBlue', 'BENCHMARK_DELTA_BLUE', (_) {
      mainEditorPane.contentEditable = 'false';
      LinkElement link = querySelector('link[rel="benchmark-DeltaBlue"]');
      String deltaBlueUri = link.href;
      link = querySelector('link[rel="benchmark-base"]');
      String benchmarkBaseUri = link.href;
      HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
        HttpRequest.getString(deltaBlueUri).then((String deltaBlue) {
          benchmarkBase = benchmarkBase.replaceFirst(
              'part of benchmark_harness;', '// part of benchmark_harness;');
          deltaBlue = deltaBlue.replaceFirst(
              "import 'package:benchmark_harness/benchmark_harness.dart';",
              benchmarkBase);
          mainEditorPane
              ..nodes.clear()
              ..appendText(deltaBlue)
              ..contentEditable = 'true';
        });
      });
    }));

    benchmarkGroup.append(buildTab('Richards', 'BENCHMARK_RICHARDS', (_) {
      mainEditorPane.contentEditable = 'false';
      LinkElement link = querySelector('link[rel="benchmark-Richards"]');
      String richardsUri = link.href;
      link = querySelector('link[rel="benchmark-base"]');
      String benchmarkBaseUri = link.href;
      HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
        HttpRequest.getString(richardsUri).then((String richards) {
          benchmarkBase = benchmarkBase.replaceFirst(
              'part of benchmark_harness;', '// part of benchmark_harness;');
          richards = richards.replaceFirst(
              "import 'package:benchmark_harness/benchmark_harness.dart';",
              benchmarkBase);
          mainEditorPane
              ..nodes.clear()
              ..appendText(richards)
              ..contentEditable = 'true';
        });
      });
    }));

    codePicker.selectedIndex = 0;
  });
}

num settingsHeight = 0;

void openSettings(MouseEvent event) {
  event.preventDefault();

  if (settingsHeight != 0) {
    var dialog = document.getElementById('settings-dialog');
    if (dialog.getBoundingClientRect().height > 0) {
      dialog.style.height = '0px';
    } else {
      dialog.style.height = '${settingsHeight}px';
    }
    return;
  }

  void updateCodeFont(Event e) {
    TextInputElement target = e.target;
    codeFont = target.value;
    mainEditorPane.style.font = codeFont;
  }

  void updateTheme(Event e) {
    var select = e.target;
    String theme = select.queryAll('option')[select.selectedIndex].text;
    window.localStorage['theme'] = theme;
    currentTheme = Theme.named(theme);

    mainEditorPane.style
        ..backgroundColor = currentTheme.background.color
        ..color = currentTheme.foreground.color;

    outputDiv.style
        ..backgroundColor = currentTheme.background.color
        ..color = currentTheme.foreground.color;

    bool oldCompilationPaused = compilationPaused;
    compilationPaused = true;
    interaction.onMutation([], observer);
    compilationPaused = false;
  }

  var body = document.getElementById('settings-body');

  body.nodes.clear();

  var form = new FormElement();
  var fieldSet = new FieldSetElement();
  body.append(form);
  form.append(fieldSet);

  bool isChecked(CheckboxInputElement checkBox) => checkBox.checked;

  String messageFor(UserOption option) {
    var message = messages[option.name];
    if (message is List) message = message[0];
    return (message == null) ? option.name : message;
  }

  String placeHolderFor(UserOption option) {
    var message = messages[option.name];
    if (message is! List) return '';
    message = message[1];
    return (message == null) ? '' : message;
  }

  void addBooleanOption(BooleanUserOption option) {
    CheckboxInputElement checkBox = new CheckboxInputElement()
        ..checked = option.value
        ..onChange.listen((Event e) { option.value = isChecked(e.target); });

    LabelElement label = new LabelElement()
        ..classes.add('checkbox')
        ..append(checkBox)
        ..appendText(' ${messageFor(option)}');

    fieldSet.append(label);
  }

  void addStringOption(StringUserOption option) {
    fieldSet.append(new LabelElement()..appendText(messageFor(option)));
    var textInput = new TextInputElement();
    textInput.classes.add('input-block-level');
    String value = option.value;
    if (!value.isEmpty) {
      textInput.value = value;
    }
    textInput.placeholder = placeHolderFor(option);;
    textInput.onChange.listen(updateCodeFont);
    fieldSet.append(textInput);
  }

  void addThemeOption(StringUserOption option) {
    fieldSet.append(new LabelElement()..appendText('Theme:'));
    var themeSelector = new SelectElement();
    themeSelector.classes.add('input-block-level');
    for (Theme theme in THEMES) {
      OptionElement option = new OptionElement()..appendText(theme.name);
      if (theme == currentTheme) option.selected = true;
      themeSelector.append(option);
    }
    themeSelector.onChange.listen(updateTheme);
    fieldSet.append(themeSelector);
  }

  for (UserOption option in options) {
    if (option.isHidden) continue;
    if (option.name == 'theme') {
      addThemeOption(option);
    } else if (option is BooleanUserOption) {
      addBooleanOption(option);
    } else if (option is StringUserOption) {
      addStringOption(option);
    }
  }

  var dialog = document.getElementById('settings-dialog');

  if (settingsHeight == 0) {
    settingsHeight = dialog.getBoundingClientRect().height;
    dialog.classes
        ..add('slider')
        ..remove('myhidden');
    Timer.run(() {
      dialog.style.height = '${settingsHeight}px';
    });
  } else {
    dialog.style.height = '${settingsHeight}px';
  }

  onSubmit(Event event) {
    event.preventDefault();

    window.localStorage['alwaysRunInWorker'] = '$alwaysRunInWorker';
    window.localStorage['verboseCompiler'] = '$verboseCompiler';
    window.localStorage['minified'] = '$minified';
    window.localStorage['onlyAnalyze'] = '$onlyAnalyze';
    window.localStorage['enableDartMind'] = '$enableDartMind';
    window.localStorage['compilationPaused'] = '$compilationPaused';
    window.localStorage['codeFont'] = '$codeFont';

    dialog.style.height = '0px';
  }
  form.onSubmit.listen(onSubmit);

  var doneButton = document.getElementById('settings-done');
  doneButton.onClick.listen(onSubmit);
}
