<commit_before>import { Component, OnInit } from '@angular/core';
import { ElementService } from '../elements/elements.service';
import { Element } from '../elements/element';
import { Filter } from './filter';

@Component({
  moduleId: module.id,
  selector: 'pt-filter',
  templateUrl: 'filter.component.html',
    styleUrls: ['filter.component.css'] 
})
export class FilterComponent implements OnInit {
  elements: Element[];
  filter: Filter;
  nonMetalNames: string[] = [
    'noble gas',
    'halogen',
    'nonmetal'
  ];
  metalNames: string[] = [
    'actinoid', 
    'alkaline earth metal', 
    'alkali metal', 
    'lanthanoid', 
    'transition metal',
    'metal'
  ];
  metalloid: string = 'metalloid';
  stateNames: string[] = [
    'solid',
    'liquid',
    'gas',
    ''
  ];

  constructor(private _elementService: ElementService) {
  }

  // Initializes filter with no filter parameters
  ngOnInit() {
    this.elements = this._elementService.elements;
    this.filter = {
      groupBlock: [],
      standardState: 'any'
    };
  }

  // Highlights all table elements matching filter criteria
  highlightElements(): void {
    for (let i = 0; i < this.elements.length; i++) {
      const element = this.elements[i];
      const filterHasParameters = this.filterHasParameters();
      const elementInGroupBlock = this.elementIsInGroupBlock(element);
      const elementInState = this.elementIsInStandardState(element);
      
      if (filterHasParameters && elementInGroupBlock && elementInState) {
        this._elementService.highlightElement(i);
      } else {
        this._elementService.unhighlightElement(i);
      }
    }
  }

  // Returns true if there are parameters to filter by
  filterHasParameters(): boolean {
    return this.filter.groupBlock.length !== 0 || 
      this.filter.standardState !== 'any';
  }

  // Returns true if the given element's group is included in the groupBlock
  // filter parameter array
  elementIsInGroupBlock(element: Element) {
    if (this.filter.groupBlock.length === 0) {
      return true;
    } else {
      return this.filter.groupBlock
        .some(groupBlock => groupBlock === element.groupBlock);
    }
  }

  // Returns true if the given element's standard state is the same as the
  // standardState filter parameter
  elementIsInStandardState(element: Element) {
    if (this.filter.standardState === 'any') {
      return true;
    } else {
      return this.filter.standardState === element.standardState;
    }
  }

  // Adds a new groupBlock to the group block filter parameters
  // If the groupBlock passed in is 'nonmetal', then all non-metals are added
  // If the groupBlock passed in is 'metal', then all metals are added
  // Definitely needs to be refactored, but I'm rushed
  addGroupBlock(event: MouseEvent, groupBlock: string): void {
    // this.highlightButton(event);
    if (groupBlock === 'nonmetal' || groupBlock === 'metal') {
      if (this.allElementsAlreadySelected(groupBlock)) {
        this.filter.groupBlock = [];
      } else {
        this.filter.groupBlock = this.returnAllElements(groupBlock);
      }
    } else if (!this.groupBlockAlreadySelected(groupBlock)) {
      this.filter.groupBlock = [groupBlock];
    } else {
      this.filter.groupBlock = [];
    }
    this.highlightElements();
  }

  // Returns true if the groupBlock is already a filter parameter
  groupBlockAlreadySelected(groupBlock: string): boolean {
    if (this.filter.groupBlock.length === 0) {
      return false;
    } else {
      return this.filter.groupBlock
        .every(filterGroupBlock => filterGroupBlock === groupBlock)   
    }
  }

  // Returns true if all of the elements of the specified type are already
  // selected
  allElementsAlreadySelected(elementType: string): boolean {
    const elements = elementType === 'nonmetal' ?
      this.returnAllElements('nonmetal') :
      this.returnAllElements('metal');
    if (this.filter.groupBlock.length === 0) {
      return false;
    } else {
      return elements.every(element => {
        return this.filter.groupBlock
          .some(groupBlock => groupBlock === element);
      });
    }
  }

  // Returns an array of all of the elements of the specified type
  returnAllElements(elementType: string): string[] {
    return elementType === 'nonmetal' ?
      [
        'halogen', 
        'noble gas', 
        'nonmetal'
      ] :
      [
        'actinoid', 
        'alkaline earth metal', 
        'alkali metal', 
        'lanthanoid', 
        'metal',
        'transition metal' 
      ];
  }

  // Highlights the target button
  // Needs to be updated to an 'angular' way, but I don't have time right now
  highlightButton(event: MouseEvent): void {
    this.unhighlightButtons();
    const button = event.target as HTMLElement;
    if (button.style.backgroundColor !== 'gray') {
      button.style.backgroundColor = 'gray';
    } else {
      button.style.backgroundColor = '#fff';
    }
  }

  // Unhighlights all filter buttons
  // Needs to be updated to an 'angular' way, but I don't have time right now
  unhighlightButtons(): void {
    const buttons = document
      .getElementsByClassName('filter-box')[0]
      .getElementsByTagName('button');
    for (let i = 0; i < buttons.length; i++) {
      buttons[i].style.backgroundColor = '#fff';
    }
  }

  // Sets the standardState filter parameter to the string passed in
  addStandardState(event: MouseEvent, standardState: string): void {
    // this.highlightButton(event);
    this.filter.standardState = standardState;
    this.highlightElements();
  }

  // Clears all filter parameters
  clearFilter(): void {
    this.filter.groupBlock = [];
    this.filter.standardState = 'any';
    this.highlightElements();
  }
}<commit_msg>Allow states to be toggled on click<commit_after>import { Component, OnInit } from '@angular/core';
import { ElementService } from '../elements/elements.service';
import { Element } from '../elements/element';
import { Filter } from './filter';

@Component({
  moduleId: module.id,
  selector: 'pt-filter',
  templateUrl: 'filter.component.html',
    styleUrls: ['filter.component.css'] 
})
export class FilterComponent implements OnInit {
  elements: Element[];
  filter: Filter;
  nonMetalNames: string[] = [
    'noble gas',
    'halogen',
    'nonmetal'
  ];
  metalNames: string[] = [
    'actinoid', 
    'alkaline earth metal', 
    'alkali metal', 
    'lanthanoid', 
    'transition metal',
    'metal'
  ];
  metalloid: string = 'metalloid';
  stateNames: string[] = [
    'solid',
    'liquid',
    'gas',
    ''
  ];

  constructor(private _elementService: ElementService) {
  }

  // Initializes filter with no filter parameters
  ngOnInit() {
    this.elements = this._elementService.elements;
    this.filter = {
      groupBlock: [],
      standardState: 'any'
    };
  }

  // Highlights all table elements matching filter criteria
  highlightElements(): void {
    for (let i = 0; i < this.elements.length; i++) {
      const element = this.elements[i];
      const filterHasParameters = this.filterHasParameters();
      const elementInGroupBlock = this.elementIsInGroupBlock(element);
      const elementInState = this.elementIsInStandardState(element);
      
      if (filterHasParameters && elementInGroupBlock && elementInState) {
        this._elementService.highlightElement(i);
      } else {
        this._elementService.unhighlightElement(i);
      }
    }
  }

  // Returns true if there are parameters to filter by
  filterHasParameters(): boolean {
    return this.filter.groupBlock.length !== 0 || 
      this.filter.standardState !== 'any';
  }

  // Returns true if the given element's group is included in the groupBlock
  // filter parameter array
  elementIsInGroupBlock(element: Element) {
    if (this.filter.groupBlock.length === 0) {
      return true;
    } else {
      return this.filter.groupBlock
        .some(groupBlock => groupBlock === element.groupBlock);
    }
  }

  // Returns true if the given element's standard state is the same as the
  // standardState filter parameter
  elementIsInStandardState(element: Element) {
    if (this.filter.standardState === 'any') {
      return true;
    } else {
      return this.filter.standardState === element.standardState;
    }
  }

  // Adds a new groupBlock to the group block filter parameters
  // If the groupBlock passed in is 'nonmetal', then all non-metals are added
  // If the groupBlock passed in is 'metal', then all metals are added
  // Definitely needs to be refactored, but I'm rushed
  addGroupBlock(event: MouseEvent, groupBlock: string): void {
    // this.highlightButton(event);
    if (groupBlock === 'nonmetal' || groupBlock === 'metal') {
      if (this.allElementsAlreadySelected(groupBlock)) {
        this.filter.groupBlock = [];
      } else {
        this.filter.groupBlock = this.returnAllElements(groupBlock);
      }
    } else if (!this.groupBlockAlreadySelected(groupBlock)) {
      this.filter.groupBlock = [groupBlock];
    } else {
      this.filter.groupBlock = [];
    }
    this.highlightElements();
  }

  // Returns true if the groupBlock is already a filter parameter
  groupBlockAlreadySelected(groupBlock: string): boolean {
    if (this.filter.groupBlock.length === 0) {
      return false;
    } else {
      return this.filter.groupBlock
        .every(filterGroupBlock => filterGroupBlock === groupBlock)   
    }
  }

  // Returns true if all of the elements of the specified type are already
  // selected
  allElementsAlreadySelected(elementType: string): boolean {
    const elements = elementType === 'nonmetal' ?
      this.returnAllElements('nonmetal') :
      this.returnAllElements('metal');
    if (this.filter.groupBlock.length === 0) {
      return false;
    } else {
      return elements.every(element => {
        return this.filter.groupBlock
          .some(groupBlock => groupBlock === element);
      });
    }
  }

  // Returns an array of all of the elements of the specified type
  returnAllElements(elementType: string): string[] {
    return elementType === 'nonmetal' ?
      [
        'halogen', 
        'noble gas', 
        'nonmetal'
      ] :
      [
        'actinoid', 
        'alkaline earth metal', 
        'alkali metal', 
        'lanthanoid', 
        'metal',
        'transition metal' 
      ];
  }

  // Highlights the target button
  // Needs to be updated to an 'angular' way, but I don't have time right now
  highlightButton(event: MouseEvent): void {
    this.unhighlightButtons();
    const button = event.target as HTMLElement;
    if (button.style.backgroundColor !== 'gray') {
      button.style.backgroundColor = 'gray';
    } else {
      button.style.backgroundColor = '#fff';
    }
  }

  // Unhighlights all filter buttons
  // Needs to be updated to an 'angular' way, but I don't have time right now
  unhighlightButtons(): void {
    const buttons = document
      .getElementsByClassName('filter-box')[0]
      .getElementsByTagName('button');
    for (let i = 0; i < buttons.length; i++) {
      buttons[i].style.backgroundColor = '#fff';
    }
  }

  // Sets the standardState filter parameter to the string passed in
  addStandardState(event: MouseEvent, standardState: string): void {
    // this.highlightButton(event);
    if (standardState === this.filter.standardState) {
      this.filter.standardState = 'any';
    } else {
      this.filter.standardState = standardState;
    }
    this.highlightElements();
  }

  // Clears all filter parameters
  clearFilter(): void {
    this.filter.groupBlock = [];
    this.filter.standardState = 'any';
    this.highlightElements();
  }
}
{'fraction_non_alphanumeric': 0.11894348683646343, 'fraction_numerical': 0.0012005831403824716, 'mean_word_length': 2.8705609027547294, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4126533', 'n_tokens_mistral': 3395, 'n_tokens_neox': 3274, 'n_words': 896}