<commit_before>import React, { Component, PropTypes } from 'react';
import update from 'react/lib/update';
import { Glyphicon, Overlay, OverlayTrigger, Tooltip, Well, Panel, Button, ButtonToolbar, Checkbox, Modal, Col, Form, FormGroup, InputGroup, FormControl, ControlLabel } from 'react-bootstrap';
import Loader from 'react-loader-advanced';

import reactMixin from 'react-mixin';
import reactor from 'modules/flux';
import { toImmutable } from 'nuclear-js';

import EnvelopeDialog from 'components/EnvelopeDialog';
import EnvelopeModule from 'components/envelope/EnvelopeModule';
import EnvelopeModuleConstAbs from 'components/envelope/EnvelopeModuleConstAbs';
import EnvelopeModuleConstRel from 'components/envelope/EnvelopeModuleConstRel';
import EnvelopeModuleDynExpDown from 'components/envelope/EnvelopeModuleDynExpDown';
import EnvelopeModuleDynExpUp from 'components/envelope/EnvelopeModuleDynExpUp';
import EnvelopeModuleDynLinDown from 'components/envelope/EnvelopeModuleDynLinDown';
import EnvelopeModuleDynLinUp from 'components/envelope/EnvelopeModuleDynLinUp';
import EnvelopeModuleDynRemain from 'components/envelope/EnvelopeModuleDynRemain';
import EnvelopeModuleEmpty from 'components/envelope/EnvelopeModuleEmpty';
import EnvelopeModuleExpDown from 'components/envelope/EnvelopeModuleExpDown';
import EnvelopeModuleExpUp from 'components/envelope/EnvelopeModuleExpUp';
import EnvelopeModuleKeyWeight from 'components/envelope/EnvelopeModuleKeyWeight';
import EnvelopeModuleLinDown from 'components/envelope/EnvelopeModuleLinDown';
import EnvelopeModuleLinUp from 'components/envelope/EnvelopeModuleLinUp';
import EnvelopeModuleNoise from 'components/envelope/EnvelopeModuleNoise';
import EnvelopeModuleRepeat from 'components/envelope/EnvelopeModuleRepeat';
import EnvelopeModuleStepAbs from 'components/envelope/EnvelopeModuleStepAbs';
import EnvelopeModuleStepRel from 'components/envelope/EnvelopeModuleStepRel';
import EnvelopeModuleVibrato1 from 'components/envelope/EnvelopeModuleVibrato1';
import EnvelopeModuleVibrato2 from 'components/envelope/EnvelopeModuleVibrato2';

import { DropTarget, DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

import { actions as instrumentActions, getters as instrumentGetters } from 'modules/instrument';

const moduleTarget = {
  drop(props, monitor, component) {
    // Indicate that we just dropped
    component.setState((state) => {
      return {
        dropCount: state.dropCount + 1
      };
    });
  }
};

@DragDropContext(HTML5Backend)
@DropTarget("envelope", moduleTarget, connect => ({
  connectDropTarget: connect.dropTarget()
}))

class Envelope extends Component {
  static propTypes = {
    connectDropTarget: PropTypes.func.isRequired
  };
  
  static defaultProps = {
    ...Component.defaultProps,
    moduleSlots: 7,
    moduleMargin: 5,
    moduleWidth: 122,
    moduleHeight: 210
  };
  
  constructor(props) {
    super(props);
    
    this.state = {
      showAdd: false,
      showValues: false,
      modules: null,
      dropCount: 0,
      releasePhaseStart: 3,
      
      loading: false
    };
    
    this._unwatchFn = null;
    
    // References to all EnvelopeModule components
    this._moduleEls = [];
    
    // Use global modules variable to allow simple communication between modules
    window.envelopeModules = [];
  }
    
  shouldComponentUpdate(nextProps, nextState) {
    // Check if we just dropped a module
    if (this.state.dropCount !== nextState.dropCount) {
      // NOTE: this is a hacky anti-pattern!
      this._moduleEls.forEach((dnd) => {
        const module = dnd.getDecoratedComponentInstance().getDecoratedComponentInstance();
        module.saveModule();
      });
      return false;
    }
    return true;
  }
  
  _handleData(dataNormal) {
    // Convert to Uint8Array
    const data = new Uint8Array(dataNormal);
    
    // Dissect attack and release data
    let releasePhaseStart = (data[1] - 2) / 6;
    if (releasePhaseStart > 6) {
      // Release disabled, just enable it for now and fix it on the last module
      releasePhaseStart = 6;
    }
    
    // Dissect module data (6 bytes each, 7 modules)
    let modules = [];
    for(let i = 0; i < 7; ++i) {
      modules.push(this._handleLoadModule(i, data));
    }
    this.setState({
      modules: modules,
      data: data,
      releasePhaseStart: releasePhaseStart
    });
  }
  
  _watch(envAddress, type) {
    const getter = instrumentGetters.byId(envAddress, type);

    // Unwatch if possible
    this._unwatch();
    
    // Register observer (databindings do not work because of retarded conflicts with decorators)
    this._unwatchFn = reactor.observe(getter, this._handleData.bind(this));
    
    // Get initial data
    const data = reactor.evaluate(getter);
    if (data) {
      this._handleData(data);
    }
  }
  _unwatch() {
    // Remove observer if it exists
    if (this._unwatchFn) {
      this._unwatchFn();
    }
  }
  
  componentWillUnmount() {
    this._unwatch();
  }
  
  componentWillMount() {
    this._watch(this.props.envAddress, this.props.type);
  }
  
  componentWillUpdate(nextProps, nextState) {
    // Check if instrument has changed
    if (this.props.envAddress !== nextProps.envAddress) {
      this._watch(nextProps.envAddress, nextProps.type);
    }
  }
  _handleAdd() {
    this.setState({ showAdd: true });
  }

  _handleToggleValues() {
    this.setState((state) => {
      return {
        showValues: !state.showValues
      };
    }, () => { console.log(this.state.showValues); });
  }
  
  _handleSave() {
    // Set attack and release offsets (attack always starts at 2, module 0).
    const releaseOffset = 2 + (this.state.releasePhaseStart * 6);
    this.state.data[0] = 2;
    this.state.data[1] = releaseOffset;
    
    // Send to SysEx
    this.setState({ loading: true }, () => {
      this.props.client.setAmpl(this.props.envAddress, this.state.data)
      .then(() => {
        // Refresh data in case the Wersi has made any changes
        return this.props.client.getAmpl(this.props.envAddress);
      })
      .then((data) => {
        // Update store
        instrumentActions.update(this.props.envAddress, 'ampl', toImmutable(data));
        this.setState({ loading: false });<commit_msg>Removed console log.<commit_after>import React, { Component, PropTypes } from 'react';
import update from 'react/lib/update';
import { Glyphicon, Overlay, OverlayTrigger, Tooltip, Well, Panel, Button, ButtonToolbar, Checkbox, Modal, Col, Form, FormGroup, InputGroup, FormControl, ControlLabel } from 'react-bootstrap';
import Loader from 'react-loader-advanced';

import reactMixin from 'react-mixin';
import reactor from 'modules/flux';
import { toImmutable } from 'nuclear-js';

import EnvelopeDialog from 'components/EnvelopeDialog';
import EnvelopeModule from 'components/envelope/EnvelopeModule';
import EnvelopeModuleConstAbs from 'components/envelope/EnvelopeModuleConstAbs';
import EnvelopeModuleConstRel from 'components/envelope/EnvelopeModuleConstRel';
import EnvelopeModuleDynExpDown from 'components/envelope/EnvelopeModuleDynExpDown';
import EnvelopeModuleDynExpUp from 'components/envelope/EnvelopeModuleDynExpUp';
import EnvelopeModuleDynLinDown from 'components/envelope/EnvelopeModuleDynLinDown';
import EnvelopeModuleDynLinUp from 'components/envelope/EnvelopeModuleDynLinUp';
import EnvelopeModuleDynRemain from 'components/envelope/EnvelopeModuleDynRemain';
import EnvelopeModuleEmpty from 'components/envelope/EnvelopeModuleEmpty';
import EnvelopeModuleExpDown from 'components/envelope/EnvelopeModuleExpDown';
import EnvelopeModuleExpUp from 'components/envelope/EnvelopeModuleExpUp';
import EnvelopeModuleKeyWeight from 'components/envelope/EnvelopeModuleKeyWeight';
import EnvelopeModuleLinDown from 'components/envelope/EnvelopeModuleLinDown';
import EnvelopeModuleLinUp from 'components/envelope/EnvelopeModuleLinUp';
import EnvelopeModuleNoise from 'components/envelope/EnvelopeModuleNoise';
import EnvelopeModuleRepeat from 'components/envelope/EnvelopeModuleRepeat';
import EnvelopeModuleStepAbs from 'components/envelope/EnvelopeModuleStepAbs';
import EnvelopeModuleStepRel from 'components/envelope/EnvelopeModuleStepRel';
import EnvelopeModuleVibrato1 from 'components/envelope/EnvelopeModuleVibrato1';
import EnvelopeModuleVibrato2 from 'components/envelope/EnvelopeModuleVibrato2';

import { DropTarget, DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

import { actions as instrumentActions, getters as instrumentGetters } from 'modules/instrument';

const moduleTarget = {
  drop(props, monitor, component) {
    // Indicate that we just dropped
    component.setState((state) => {
      return {
        dropCount: state.dropCount + 1
      };
    });
  }
};

@DragDropContext(HTML5Backend)
@DropTarget("envelope", moduleTarget, connect => ({
  connectDropTarget: connect.dropTarget()
}))

class Envelope extends Component {
  static propTypes = {
    connectDropTarget: PropTypes.func.isRequired
  };
  
  static defaultProps = {
    ...Component.defaultProps,
    moduleSlots: 7,
    moduleMargin: 5,
    moduleWidth: 122,
    moduleHeight: 210
  };
  
  constructor(props) {
    super(props);
    
    this.state = {
      showAdd: false,
      showValues: false,
      modules: null,
      dropCount: 0,
      releasePhaseStart: 3,
      
      loading: false
    };
    
    this._unwatchFn = null;
    
    // References to all EnvelopeModule components
    this._moduleEls = [];
    
    // Use global modules variable to allow simple communication between modules
    window.envelopeModules = [];
  }
    
  shouldComponentUpdate(nextProps, nextState) {
    // Check if we just dropped a module
    if (this.state.dropCount !== nextState.dropCount) {
      // NOTE: this is a hacky anti-pattern!
      this._moduleEls.forEach((dnd) => {
        const module = dnd.getDecoratedComponentInstance().getDecoratedComponentInstance();
        module.saveModule();
      });
      return false;
    }
    return true;
  }
  
  _handleData(dataNormal) {
    // Convert to Uint8Array
    const data = new Uint8Array(dataNormal);
    
    // Dissect attack and release data
    let releasePhaseStart = (data[1] - 2) / 6;
    if (releasePhaseStart > 6) {
      // Release disabled, just enable it for now and fix it on the last module
      releasePhaseStart = 6;
    }
    
    // Dissect module data (6 bytes each, 7 modules)
    let modules = [];
    for(let i = 0; i < 7; ++i) {
      modules.push(this._handleLoadModule(i, data));
    }
    this.setState({
      modules: modules,
      data: data,
      releasePhaseStart: releasePhaseStart
    });
  }
  
  _watch(envAddress, type) {
    const getter = instrumentGetters.byId(envAddress, type);

    // Unwatch if possible
    this._unwatch();
    
    // Register observer (databindings do not work because of retarded conflicts with decorators)
    this._unwatchFn = reactor.observe(getter, this._handleData.bind(this));
    
    // Get initial data
    const data = reactor.evaluate(getter);
    if (data) {
      this._handleData(data);
    }
  }
  _unwatch() {
    // Remove observer if it exists
    if (this._unwatchFn) {
      this._unwatchFn();
    }
  }
  
  componentWillUnmount() {
    this._unwatch();
  }
  
  componentWillMount() {
    this._watch(this.props.envAddress, this.props.type);
  }
  
  componentWillUpdate(nextProps, nextState) {
    // Check if instrument has changed
    if (this.props.envAddress !== nextProps.envAddress) {
      this._watch(nextProps.envAddress, nextProps.type);
    }
  }
  _handleAdd() {
    this.setState({ showAdd: true });
  }

  _handleToggleValues() {
    this.setState((state) => {
      return {
        showValues: !state.showValues
      };
    });
  }
  
  _handleSave() {
    // Set attack and release offsets (attack always starts at 2, module 0).
    const releaseOffset = 2 + (this.state.releasePhaseStart * 6);
    this.state.data[0] = 2;
    this.state.data[1] = releaseOffset;
    
    // Send to SysEx
    this.setState({ loading: true }, () => {
      this.props.client.setAmpl(this.props.envAddress, this.state.data)
      .then(() => {
        // Refresh data in case the Wersi has made any changes
        return this.props.client.getAmpl(this.props.envAddress);
      })
      .then((data) => {
        // Update store
        instrumentActions.update(this.props.envAddress, 'ampl', toImmutable(data));
        this.setState({ loading: false });
{'fraction_non_alphanumeric': 0.10368479821343117, 'fraction_numerical': 0.005742542670282342, 'mean_word_length': 3.6406365655070316, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 20, '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': '3485848', 'n_tokens_mistral': 3727, 'n_tokens_neox': 3672, 'n_words': 865}