@import "scoreboard-colors";

$delay: 300ms;
$timing-fn: ease-out;
$tree-label-mask-stop: 90%;
$traveling-overlap: 17px;
$tree-item-height: 36px;

@mixin prefix($property, $value, $prefixes: ()) {
   @each $prefix in $prefixes {
    #{'-' + $prefix + '-' + $property}: $value;
  }

  #{$property}: $value;
}

@mixin gradientBackground($startColor, $stopColor) {
  background-image: -webkit-linear-gradient(left, $startColor, $stopColor);
  background-image: linear-gradient(to right, $startColor, $stopColor);

  [dir=rtl] & {
    background-image: -webkit-linear-gradient(right, $startColor, $stopColor);
    background-image: linear-gradient(to left, $startColor, $stopColor);
  }
}

@mixin rtlTransformRotate($transform) {
  transform: rotate($transform * 1deg);

  [dir=rtl] & {
    transform: rotate($transform * -1deg);
  }
}

@mixin base-node() {
  list-style: none;
  position: absolute;
  opacity: 1;
  width: 100%;
  height: 36px;
  top: 0;
  inset-inline-start: 0;

  /*
   * This seems weird, and it is, but in FF (See #364), when nodes are moved in the tree, when you go to update some innerHTML of the node
   * the node text disappears. It seems to be a bug introduced in FF 25 (worked fine up until FF 24.8). Forcing a node's overflow to visible
   * forces FF to not make the innerHTML of the `.label` vanish. Somewhat surprisingly, overflow of visible is okay since we're using label masking.
   * See a simplified demo of the bug here: http://codepen.io/anon/pen/VmRROj
   */
  overflow: visible;

  transition-property: opacity;
  transition-duration: $delay;
  transition-timing-function: $timing-fn;

  .node-contents {
    padding: 10px 0px 8px;
    font-size: 14px;
    line-height: 1; // automatically the same as font size
    text-align: start;
    white-space: nowrap;

    svg.icon {
      display: inline-block;
      vertical-align: middle;
      margin-inline-start: 2px;
      width: 12px;
      height: 11px;
      fill: $color-tree-node-text-color;
    }

    .label {
      display: inline-block;
      vertical-align: middle;
      margin-inline-start: 10px;
      color: $color-tree-node-text-color;
      text-shadow: 0 1px 0 $color-tree-node-text-shadow;
    }
  }

  .label-mask {
    /* This is used to mask long label names on the nodes */
    position: absolute;
    width: 100px;
    height: 100%;
    top: 0;
    inset-inline-end: 0;

    &:after {
      content: "";
      position: absolute;
      width: 5px;
      height: 5px;
      top: 16px;
      inset-inline-end: 12px;
      border-radius: 50%;
    }
  }
}

.tree-container {
  position: relative;
  background-color: $color-tree-background;
  width: 100%;
  height: 100%;

  &.ie-trident {
    .tree {
      &.tree-overflow {
        overflow-y: scroll;
      }
    }
  }

  .traveling-node {
    @include base-node;

    height: $tree-item-height;
    background: $color-tree-traveling-node-background;
    box-shadow: 0 2px 6px 0 $color-tree-traveling-node-shadow;
    width: calc(100% + #{$traveling-overlap});
    opacity: 0.9;
    border-start-end-radius: 3px;
    border-end-end-radius: 3px;
    cursor: move;
    overflow-x: hidden;

    .node-contents {
      padding-top: 10px;
      padding-inline-end: 0px;
      padding-bottom: 8px;
      padding-inline-start: 14px;
      transition-property: transform, opacity;
      transition-duration: $delay;
      transition-timing-function: $timing-fn;

      // Align with non traveling icons
      svg.icon {
        margin-inline-start: 8px;
        margin-top: 1px;
        fill: $color-tree-node-selected-text-color;
      }

      .label {
        color: $color-tree-node-selected-text-color;
        transition-property: color;
        transition-duration: $delay;
        transition-timing-function: $timing-fn;
      }
    }

    .label-mask {
      @include gradientBackground(rgba($color-tree-background, 0) 0%, $color-tree-background $tree-label-mask-stop);
      // Round off the right edge of the traveling node
      border-start-end-radius: 3px;
      border-end-end-radius: 3px;
    }

    &.selected {
      box-shadow: inset 4px 0 0 $color-tree-editable-highlight;

      [dir=rtl] & {
        box-shadow: inset -4px 0 0 $color-tree-editable-highlight;
      }

      &.illegal {
        box-shadow: inset 4px 0 0 $color-warning;
      }
    }

    &.illegal {
      opacity: .9;

      .node-contents {
        opacity: .7;

        .icon {
          fill: $color-error;
        }

        .label {
          color: $color-error;
        }
      }

      &:after {
        color: $color-error;
        background: $color-error;
        box-shadow: 0 0.25em 0 0 $color-error, 0 0.5em 0 0 $color-error;
      }
    }

    // The traveling drag handle
    &:after {
      content: "";
      position: absolute;
      width: 12px;
      top: 13px;
      inset-inline-end: 10px;
      height: .1em;
      background: $color-tree-node-selected-text-color;
      box-shadow: 0 0.25em 0 0 $color-tree-node-selected-text-color, 0 0.5em 0 0 $color-tree-node-selected-text-color;
      opacity: 0.9;

      transition-property: background, box-shadow, color;
      transition-duration: $delay;
      transition-timing-function: $timing-fn;
    }

    .toggler, .indicator:after {
      display: none;
    }
  }

  // Selected traveling nodes use yellow drag handles when in edit mode
  .tree.editable:not(.filtered-results) + .traveling-node.selected:not(.illegal):after {
      background: $color-tree-editable-highlight;
      box-shadow: 0 0.25em 0 0 $color-tree-editable-highlight, 0 0.5em 0 0 $color-tree-editable-highlight;
  }

  // Without setting the correct transparent end color for this gradient, the
  // gradient will be off in Safari
  // https://github.com/SpiderStrategies/Scoreboard/issues/6382
  .traveling-node .label-mask {
    @include gradientBackground(rgba($color-tree-traveling-node-background, 0) 0%, $color-tree-traveling-node-background $tree-label-mask-stop);
  }

  .tree {
    overflow: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;

    width: 100%;
    height: 100%;

    @include prefix(user-select, none, webkit ms);

    // Most tree functions that modify the dom send a callback into transitionWrap where has some magic
    // to determine whether or not we actually want transitions. It's in charge of adding the .transitions
    // class, executing the callback (which modifies the dom), then removes the class.
    &.transitions {
      ul {
        li.node {
          &.transitioning-node {
            // Transitioning nodes have an opacity of 0, because if they are incoming nodes, they start at 0
            // and if they are outgoing nodes, they end up at 0.
            opacity: 0;

            &:not(.outgoing-node) {
              // For incoming-nodes (i.e. not marked as outgoing-node), ignore transitioning the opacity. Once
              // the transitioning-node class is removed (right after a browser reflow), the transition-property
              // will pick up from the `li.node` styling, so opacity will transition.
              // This fixes a bizarre IE11 bug that will break the entire transition
              transition-property: height, transform;
            }
          }

          transition-property: transform, opacity, height;
          transition-duration: $delay;
          transition-timing-function: $timing-fn;
          .node-contents {
            transition-property: transform, opacity;
            transition-duration: $delay;
            transition-timing-function: $timing-fn;

            .toggler {
              transition-property: transform;
              transition-duration: $delay;
            }
          }
        }
      }
    }

    // Show the expand/collapse indicators on hover
    &:hover {
      // Don't show it for the root node on normal trees
      li.node:not(.root) {
        .toggler { opacity: 1; }
      }
    }

    ul {
      list-style-type: none;
      padding: 0px;
      margin: 0px;
      transform: translateX(0); // Specify 0 transform, otherwise we get overflow on nodes

      li.node {
        @include base-node;
        cursor: pointer;

        &.transitioning-node {
          pointer-events: none;
        }

        .node-contents {
          .toggler {
            display: inline-block;
            vertical-align: middle;
            width: 22px;
            height: 22px;
            margin-top: -4px;
            margin-inline-end: 0;
            margin-bottom: 0;
            margin-inline-start: -2px;
            opacity: 0;
            @include rtlTransformRotate(-90);
            transform-origin: center center;

            svg {
              position: absolute;
              width: 9px;
              height: 6px;
              top: 9px;
              inset-inline-end: 8px;
              fill: $color-tree-node-text-color;
            }

            &.expanded {
              transform: rotate(0deg);
            }
            &.leaf { visibility: hidden !important; }
          }
        }

        .label-mask {
          @include gradientBackground(rgba($color-tree-background,0) 0%, $color-tree-background $tree-label-mask-stop);

          &.indicator {
            @include gradientBackground(rgba($color-tree-background,0) 0%, $color-tree-background 50%);
          }
        }

        &.placeholder, &.transition-placeholder {
          &.transition-placeholder {
            // This is for transition placeholder nodes popping in or out
            background-color: $color-tree-node-selected-background;
          }

          * {
            display: none;
          }
        }

        // Styling for the transient tree node which appears when creating a new item
        &.transient {
          pointer-events: none;
          overflow: hidden; // prevent scrollbar for opening animation
          border: 1px dashed $color-tree-node-transient-border;
          border-radius: 2px;
          background-color: $color-tree-node-selected-background;

          div.label-mask {
            @include gradientBackground(rgba($color-tree-node-selected-background,0) 0%, $color-tree-node-selected-background $tree-label-mask-stop);

            &:after {
              display: none;
            }
          }

          .node-contents {
            margin-inline-start: -1px; // Compensate for added node border
          }
        }

        &.fading-node {
          height: 0; // either finishes or ends at 0
        }

        &.selected {
          background-color: $color-tree-node-selected-background;
          z-index: 1;

          &:not(.placeholder) {
            // left white vertical bar
            box-shadow: inset 4px 0 0 $color-tree-node-selected-text-color;

            [dir=rtl] & {
              box-shadow: inset -4px 0 0 $color-tree-node-selected-text-color !important;
            }
          }

          .label-mask {
            @include gradientBackground(rgba($color-tree-node-selected-background,0) 0%, $color-tree-node-selected-background $tree-label-mask-stop);

            &.indicator {
              @include gradientBackground(rgba($color-tree-node-selected-background,0) 0%, $color-tree-node-selected-background 50%);
            }
          }
        }

        &:hover, &.selected, &.transient {
          svg.icon {
            fill: $color-tree-node-selected-text-color
          }

          .label {
            color: $color-tree-node-selected-text-color;
          }
        }
      }
    }

    // Bottom yellow highlight displayed when in edit mode
    &:after {
      position: absolute;
      bottom: 0px;
      content: '';
      width: 100%;
      display: block;
      height: 0;
      background: $color-tree-editable-highlight;
      opacity: .5;
    }

    &.editable {
      &:after {
        height: 3px;
      }

      // Yellow selected node highlight to the left of the node
      li.node.selected:not(.placeholder) {
        box-shadow: inset 4px 0 0 $color-tree-editable-highlight;
      }

      li.node.selected, + .traveling-node.selected {
        &:not(.illegal) {
          .label {
            color: $color-tree-editable-highlight;
          }
          .node-contents .icon, .node-contents .toggler svg {
            fill: $color-tree-editable-highlight;
          }
        }
      }

      &.dragging {
        li.node {
          &.selected.placeholder {
            background-color: inherit;
          }
          .toggler {
             opacity: 0 !important; // Never show the toggler when the user is dragging
          }
        }
      }

      &:not(.filtered-results) {
        li.node.movable:not(.root):not(.transient) {
          cursor: move;

          &:after {
            content: "";
            position: absolute;
            width: 5px;
            top: 13px;
            inset-inline-end: 0;
            height: .1em;
            background: $color-tree-node-drag-handle-fill;
            box-shadow: 0 0.25em 0 0 $color-tree-node-drag-handle-fill, 0 0.5em 0 0 $color-tree-node-drag-handle-fill;
          }

          &:hover:after {
            background: $color-tree-node-selected-text-color;
            box-shadow: 0 0.25em 0 0 $color-tree-node-selected-text-color, 0 0.5em 0 0 $color-tree-node-selected-text-color;
          }

          &.selected:hover:after {
            background: $color-tree-editable-highlight;
            box-shadow: 0 0.25em 0 0 $color-tree-editable-highlight, 0 0.5em 0 0 $color-tree-editable-highlight;
          }
        }
      }
    }

    &.forest-tree {
      .node .node-contents {
        padding-inline-start: 8px;
      }
    }

    &.filtered-results {
      .toggler {
        opacity: 0 !important; // Never show the toggler when displaying filtered results
      }
    }
  }
}
