// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function() {
  'use strict';

  Polymer({
    is: 'gr-edit-preferences',

    properties: {
      hasUnsavedChanges: {
        type: Boolean,
        notify: true,
        value: false,
      },

      /** @type {?} */
      editPrefs: Object,
    },

    loadData() {
      return this.$.restAPI.getEditPreferences().then(prefs => {
        this.editPrefs = prefs;
      });
    },

    _handleEditPrefsChanged() {
      this.hasUnsavedChanges = true;
    },

    _handleTopMenuChanged() {
      this.set('editPrefs.hide_top_menu', this.$.showTopMenu.checked);
      this._handleEditPrefsChanged();
    },

    _handleEditSyntaxHighlightingChanged() {
      this.set('editPrefs.syntax_highlighting',
          this.$.editSyntaxHighlighting.checked);
      this._handleEditPrefsChanged();
    },

    _handleEditShowTabsChanged() {
      this.set('editPrefs.show_tabs', this.$.editShowTabs.checked);
      this._handleEditPrefsChanged();
    },

    _handleWhitespaceErrorsChanged() {
      this.set('editPrefs.show_whitespace_errors',
          this.$.whitespaceErrors.checked);
      this._handleEditPrefsChanged();
    },

    _handleLineNumbersChanged() {
      this.set('editPrefs.hide_line_numbers',
          this.$.showLineNumbers.checked);
      this._handleEditPrefsChanged();
    },

    _handleMatchBracketsChanged() {
      this.set('editPrefs.match_brackets', this.$.showMatchBrackets.checked);
      this._handleEditPrefsChanged();
    },

    _handleEditLineWrappingChanged() {
      this.set('editPrefs.line_wrapping',
          this.$.editShowLineWrapping.checked);
      this._handleEditPrefsChanged();
    },

    _handleIndentWithTabsChanged() {
      this.set('editPrefs.indent_with_tabs',
          this.$.showIndentWithTabs.checked);
      this._handleEditPrefsChanged();
    },

    _handleAutoCloseBracketsChanged() {
      this.set('editPrefs.auto_close_brackets',
          this.$.showAutoCloseBrackets.checked);
      this._handleEditPrefsChanged();
    },

    _handleShowBaseVersionChanged() {
      this.set('editPrefs.show_base',
          this.$.showShowBaseVersion.checked);
      this._handleEditPrefsChanged();
    },

    save() {
      return this.$.restAPI.saveEditPreferences(this.editPrefs)
          .then(() => {
            this.hasUnsavedChanges = false;
          });
    },
  });
})();
