     window.notify.morale = moraleValue
     @setState
       timeSettingShow: false
+  selectInput: (id) ->
+    document.getElementById(id).select()
+  render: ->
+    <Grid>
+      <div>
+        <Col xs={6}>
+          <Button bsStyle={if @state.enableNotify then 'success' else 'danger'} onClick={@handleSetNotify} style={width: '100%'}>
+            {if @state.enableNotify then '√ ' else ''}{__ 'Enable notification'}
+          </Button>
+        </Col>
+        <Col xs={6}>
+          <OverlayTrigger placement='top' overlay={
+              <Tooltip id='poiconfig-volume'>{__ 'Volume'} <strong>{parseInt(@state.notifyVolume * 100)}%</strong></Tooltip>
+            }>
+            <Input type="range" ref="notifyVolume"
+              onChange={@handleChangeNotifyVolume} onMouseUp={@handleEndChangeNotifyVolume}
+              min={0.0} max={1.0} step={0.05} defaultValue={@state.notifyVolume} />
+          </OverlayTrigger>
+        </Col>
+      </div>
+      <div>
+        <Col xs={12} style={marginTop: 10}>
+          <ButtonGroup style={display: 'flex'}>
+            <Button bsStyle={if @state.constructionNotify then 'success' else 'danger'}
+                    onClick={@handleSetNotifyIndividual.bind this, 'construction'}
+                    className='notif-button'>
+              {__ 'Construction'}
+            </Button>
+            <Button bsStyle={if @state.expeditionNotify then 'success' else 'danger'}
+                    onClick={@handleSetNotifyIndividual.bind this, 'expedition'}
+                    className='notif-button'>
+              {__ 'Expedition'}
+            </Button>
+            <Button bsStyle={if @state.repairNotify then 'success' else 'danger'}
+                    onClick={@handleSetNotifyIndividual.bind this, 'repair'}
+                    className='notif-button'>
+              {__ 'Docking'}
+            </Button>
+            <Button bsStyle={if @state.moraleNotify then 'success' else 'danger'}
+                    onClick={@handleSetNotifyIndividual.bind this, 'morale'}
+                    className='notif-button'>
+              {__ 'Morale'}
+            </Button>
+            <Button bsStyle={if @state.othersNotify then 'success' else 'danger'}
+                    onClick={@handleSetNotifyIndividual.bind this, 'others'}
+                    className='notif-button'>
+              {__ 'Others'}
+            </Button>
+            <Button onClick={@handleSetTimeSettingShow} bsStyle='primary' style={width: 40}>
+              <FontAwesome name="#{if @state.timeSettingShow then 'angle-up' else 'angle-down'}" />
+            </Button>
+          </ButtonGroup>
+          <Collapse in={@state.timeSettingShow}>
+            <div>
+              <Well>
+                <Row>
+                  <Col xs={9} className='notif-container'>
+                    <div className='notif-input-desc'>{__ 'Expedition'}: {__ 'Notify when expedition returns in'}</div>
+                  </Col>
+                  <Col xs={3} className='notif-container'>
+                    <Input type="number" ref="expeditionValue" id="expeditionValue"
+                           disabled={!@state.expeditionNotify}
+                           value={@state.expeditionValue}
+                           onChange={@handleSetExpedition}
+                           onClick={@selectInput.bind @, "expeditionValue"}
+                           bsSize='small'
+                           addonAfter='S'
+                           className='notif-input' />
+                  </Col>
+                </Row>
+                <Row>
+                  <Col xs={9} className='notif-container'>
+                    <div className='notif-input-desc'>{__ 'Morale'}: {__ 'Notify when morale is greater than'}</div>
+                  </Col>
+                  <Col xs={3} className='notif-container'>
+                    <Input type="number" ref="moraleValue" id="moraleValue"
+                           disabled={!@state.moraleNotify}
+                           value={@state.moraleValue}
+                           onChange={@handleSetMorale}
+                           onClick={@selectInput.bind @, "moraleValue"}
+                           bsSize='small'
+                           className='notif-input' />
+                  </Col>
+                </Row>
+                <Row>
+                  <Col xs={2} xsOffset={10}>
+                    <Button bsSize='small' onClick={@saveNotifySetting}>{__ 'Save'}</Button>
+                  </Col>
+                </Row>
+              </Well>
+            </div>
+          </Collapse>
+        </Col>
+      </div>
+    </Grid>
+
+# Parameters:
+#   label       String  The text to display
+#   configName  String  Where you store in config
+#   defaultVal  Bool    The default value for config. False if not given (not recommended)
+CheckboxLabelConfig = React.createClass
+  getInitialState: ->
+    myval: config.get @props.configName, (@props.defaultVal || false)
+  handleChange: ->
+    console.log @state.myval
+    enabled = @state.myval
+    config.set @props.configName, !enabled
+    @setState
+      myval: !enabled
+  render: ->
+    <Col xs={12}>
+      <Input type="checkbox" label={@props.label} checked={@state.myval} onChange={@handleChange} />
+    </Col>
+
+# Parameters:
+#   label       String         The title to display
+#   configName  String         Where you store in config
+#   defaultVal  Bool           The default value for config
+#   onNewVal    Function(val)  Called when a new value is set.
+FolderPickerConfig = React.createClass
+  getInitialState: ->
+    myval: config.get @props.configName, @props.defaultVal
   onDrag: (e) ->
     e.preventDefault()
-  selectInput: (id) ->
-    document.getElementById(id).select()
   synchronize: (callback) ->
     return if @lock
     @lock = true
     callback()
     @lock = false
+  setPath: (val) ->
+    @props.onNewVal(val) if @props.onNewVal
+    config.set @props.configName, val
+    @setState
+      myval: val
+  folderPickerOnDrop: (e) ->
+    e.preventDefault()
+    droppedFiles = e.dataTransfer.files
+    isDirectory = fs.statSync(droppedFiles[0].path).isDirectory()
+    @setPath droppedFiles[0].path if isDirectory
+  folderPickerOnClick: ->
+    @synchronize =>
+      fs.ensureDirSync @state.myval
+      filenames = dialog.showOpenDialog
+        title: @props.label
+        defaultPath: @state.myval
+        properties: ['openDirectory', 'createDirectory']
+      @setPath filenames[0] if filenames isnt undefined
+  render: ->
+    <Grid>
+      <Col xs={12}>
+        <div className="folder-picker"
+             onClick={@folderPickerOnClick}
+             onDrop={@folderPickerOnDrop}
+             onDragEnter={@onDrag}
+             onDragOver={@onDrag}
+             onDragLeave={@onDrag}>
+          {@state.myval}
+        </div>
+      </Col>
+    </Grid>
+
+ClearCacheCookieConfig = React.createClass
+  handleClearCookie: (e) ->
+    remote.getCurrentWebContents().session.clearStorageData {storages: ['cookies']}, ->
+      toggleModal __('Delete cookies'), __('Success!')
+  handleClearCache: (e) ->
+    remote.getCurrentWebContents().session.clearCache ->
+      toggleModal __('Delete cache'), __('Success!')
+  render: ->
+    <Grid>
+      <Col xs={6}>
+        <Button bsStyle="danger" onClick={@handleClearCookie} style={width: '100%'}>
+          {__ 'Delete cookies'}
+        </Button>
+      </Col>
+      <Col xs={6}>
+        <Button bsStyle="danger" onClick={@handleClearCache} style={width: '100%'}>
+          {__ 'Delete cache'}
+        </Button>
+      </Col>
+      <Col xs={12}>
+        <Alert bsStyle='warning' style={marginTop: '10px'}>
+          {__ 'If connection error occurs frequently, delete both of them.'}
+        </Alert>
+      </Col>
+    </Grid>
+
+SelectLanguageConfig = React.createClass
+  getInitialState: ->
+    language: config.get 'poi.language', language
+  handleSetLanguage: (language) ->
+    language = @refs.language.getValue()
+    return if @state.language == language
+    config.set 'poi.language', language
+    for namespace of window.i18n
+      console.log namespace
+      window.i18n[namespace].setLocale language
+    window.language = language
+    @setState {language}
+  render: ->
+    <Grid>
+      <Col xs={6}>
+        <Input type="select" ref="language" value={@state.language} onChange={@handleSetLanguage}>
+          <option value="zh-CN">简体中文</option>
+          <option value="zh-TW">正體中文</option>
+          <option value="ja-JP">日本語</option>
+          <option value="en-US">English</option>
+        </Input>
+      </Col>
+    </Grid>
+
+SlotCheckConfig = React.createClass
+  preProcess: ->
+    # Remove this method after some future releases
+    old = config.get 'poi.mapstartcheck'
+    if old?
+      if old.ship?
+        config.set 'poi.mapStartCheck.ship.enable', old.ship
+      if old.freeShipSlot?
+        config.set 'poi.mapStartCheck.ship.minFreeSlots', old.freeShipSlot
+      if old.item?
+        config.set 'poi.mapStartCheck.item.enable', old.item
+      if old.freeItemSlot?
+        config.set 'poi.mapStartCheck.item.minFreeSlots', old.freeItemSlot
+      config.set 'poi.mapstartcheck'
+
+  getInitialState: ->
+    @preProcess()
+
+    @cfgEntry = "poi.mapStartCheck.#{@props.type}"
+
+    showInput: false
+    enable: config.get "#{@cfgEntry}.enable", false
+    value: ''
+  CheckValid: (v) ->
+    !isNaN(v) and !isNaN(n = parseInt v) and n >= 0
+  handleToggleInput: ->
+    if @state.showInput
+      @handleDisable()
+    else
+      num = config.get "#{@cfgEntry}.minFreeSlots", -1
+      @setState
+        showInput: true
+        value: if @CheckValid(num) then num else ''
+    console.log @props.type + JSON.stringify(config.get @cfgEntry) if process.env.DEBUG?
+  handleChange: (e) ->
+    @setState
+      value: e.target.value
+  handleSubmit: (e) ->
+    e.preventDefault()
+    if @CheckValid @state.value
+      n = parseInt @state.value
+      config.set @cfgEntry, {enable: true, minFreeSlots: n}
+      @setState
+        showInput: false
+        enable: true
+        value: n
+    else
+      @handleDisable()
+    console.log @props.type + JSON.stringify(config.get @cfgEntry) if process.env.DEBUG?
+  handleDisable: ->
+    config.set "#{@cfgEntry}.enable", false
+    @setState
+      showInput: false
+      enable: false
+  selectText: ->
+    @textInput.getInputDOMNode().select()
+  render: ->
+    toggleBtnStyle = if @state.enable then 'success' else 'default'
+    toggleBtnStyle = 'danger' if @state.showInput
+    toggleBtnTxt = if @state.enable then 'ON' else 'OFF'
+    toggleBtnTxt = __ 'Disable' if @state.showInput
+    toggleBtn = <Button onClick={@handleToggleInput} bsSize='xs'
+      bsStyle={toggleBtnStyle} style={verticalAlign: 'text-bottom'}>
+      {toggleBtnTxt}</Button>
+    inputValid = @CheckValid @state.value
+    submitBtn = <Button type='submit'
+      bsStyle={if inputValid then 'success' else 'danger'}>
+      {if inputValid then __ 'Save' else __ 'Disable'}</Button>
+    <div style={margin: '5px 15px'}>
+      <form onSubmit={@handleSubmit}>
+        <div>
+          {__ "#{@props.type} slots"} {toggleBtn}
+        </div>
+        <Collapse in={@state.showInput} onEntered={@selectText}>
+          <div>
+            <Well>
+              <Input type="text" bsSize='small'
+                bsStyle={if inputValid then 'success' else 'error'}
+                label={__ "Warn if the number of free #{@props.type} slots is less than"}
+                value={@state.value}
+                ref={(r) => this.textInput = r}
+                onChange={@handleChange}
+                buttonAfter={submitBtn} />
+            </Well>
+          </div>
+        </Collapse>
+      </form>
+    </div>
+
+PoiConfig = React.createClass
   render: ->
     <div>
       <form>

          <NavigatorBar />
          {
            if process.platform isnt 'darwin'
              <Grid>
                <Col xs={12}>
                  <Input type="checkbox" label={__ 'Confirm before exit'} checked={@state.enableConfirmQuit} onChange={@handleSetConfirmQuit} />
                </Col>
              </Grid>
          }
        </div>
        <div className="form-group">
          <Divider text={__ 'Notification'} />
          <Grid>
            <div>
              <Col xs={6}>
                <Button bsStyle={if @state.enableNotify then 'success' else 'danger'} onClick={@handleSetNotify} style={width: '100%'}>
                  {if @state.enableNotify then '√ ' else ''}{__ 'Enable notification'}
                </Button>
              </Col>
              <Col xs={6}>
                <OverlayTrigger placement='top' overlay={
                    <Tooltip id='poiconfig-volume'>{__ 'Volume'} <strong>{parseInt(@state.notifyVolume * 100)}%</strong></Tooltip>
                  }>
                  <Input type="range" ref="notifyVolume"
                    onChange={@handleChangeNotifyVolume} onMouseUp={@handleEndChangeNotifyVolume}
                    min={0.0} max={1.0} step={0.05} defaultValue={@state.notifyVolume} />
                </OverlayTrigger>
              </Col>
            </div>
            <div>
              <Col xs={12} style={marginTop: 10}>
                <ButtonGroup style={display: 'flex'}>
                  <Button bsStyle={if @state.constructionNotify then 'success' else 'danger'}
                          onClick={@handleSetNotifyIndividual.bind this, 'construction'}
                          className='notif-button'>
                    {__ 'Construction'}
                  </Button>
                  <Button bsStyle={if @state.expeditionNotify then 'success' else 'danger'}
                          onClick={@handleSetNotifyIndividual.bind this, 'expedition'}
                          className='notif-button'>
                    {__ 'Expedition'}
                  </Button>
                  <Button bsStyle={if @state.repairNotify then 'success' else 'danger'}
                          onClick={@handleSetNotifyIndividual.bind this, 'repair'}
                          className='notif-button'>
                    {__ 'Docking'}
                  </Button>
                  <Button bsStyle={if @state.moraleNotify then 'success' else 'danger'}
                          onClick={@handleSetNotifyIndividual.bind this, 'morale'}
                          className='notif-button'>
                    {__ 'Morale'}
                  </Button>
                  <Button bsStyle={if @state.othersNotify then 'success' else 'danger'}
                          onClick={@handleSetNotifyIndividual.bind this, 'others'}
                          className='notif-button'>
                    {__ 'Others'}
                  </Button>
                  <Button onClick={@handleSetTimeSettingShow} bsStyle='primary' style={width: 40}>
                    <FontAwesome name="#{if @state.timeSettingShow then 'angle-up' else 'angle-down'}" />
                  </Button>
                </ButtonGroup>
                <Collapse in={@state.timeSettingShow}>
                  <div>
                    <Well>
                      <Row>
                        <Col xs={9} className='notif-container'>
                          <div className='notif-input-desc'>{__ 'Expedition'}: {__ 'Notify when expedition returns in'}</div>
                        </Col>
                        <Col xs={3} className='notif-container'>
                          <Input type="number" ref="expeditionValue" id="expeditionValue"
                                 disabled={!@state.expeditionNotify}
                                 value={@state.expeditionValue}
                                 onChange={@handleSetExpedition}
                                 onClick={@selectInput.bind @, "expeditionValue"}
                                 bsSize='small'
                                 addonAfter='S'
                                 className='notif-input' />
                        </Col>
                      </Row>
                      <Row>
                        <Col xs={9} className='notif-container'>
                          <div className='notif-input-desc'>{__ 'Morale'}: {__ 'Notify when morale is greater than'}</div>
                        </Col>
                        <Col xs={3} className='notif-container'>
                          <Input type="number" ref="moraleValue" id="moraleValue"
                                 disabled={!@state.moraleNotify}
                                 value={@state.moraleValue}
                                 onChange={@handleSetMorale}
                                 onClick={@selectInput.bind @, "moraleValue"}
                                 bsSize='small'
                                 className='notif-input' />
                        </Col>
                      </Row>
                      <Row>
                        <Col xs={2} xsOffset={10}>
                          <Button bsSize='small' onClick={@saveNotifySetting}>{__ 'Save'}</Button>
                        </Col>
                      </Row>
                    </Well>
                  </div>
                </Collapse>
              </Col>
            </div>
          </Grid>
        </div>
      </form>
      <div className="form-group" >

      <form>
        <div className="form-group">
          <Divider text={__ 'Cache and cookies'} />
          <ClearCacheCookieConfig />
        </div>
        <div className="form-group">
          <Divider text={__ 'Language'} />
          <SelectLanguageConfig />
        </div>
        <div className="form-group">
          <Divider text={__ 'Screenshot Folder'} />
          <FolderPickerConfig 
            label={__ 'Screenshot Folder'} 
            configName="poi.screenshotPath" 
            defaultVal={window.screenshotPath} 
            onNewVal={(pathname) -> window.screenshotPath = pathname} />
        </div>
        <div className="form-group">
          <Divider text={__ 'Cache Folder'} />
          <FolderPickerConfig label={__ 'Cache Folder'} configName="poi.cachePath" defaultVal={remote.getGlobal('DEFAULT_CACHE_PATH')} />
        </div>
        <div className="form-group">
          <Divider text={__ 'Advanced'} />
          <Grid>
            <CheckboxLabelConfig 
              label={__ 'Disable Hardware Acceleration'} 
              configName="poi.disableHA" 
              defaultVal=false />
            <CheckboxLabelConfig 
              label={__ 'Editing DMM Cookie\'s Region Flag'} 
              configName="poi.enableDMMcookie" 
              defaultVal=false />
            <CheckboxLabelConfig 
              label={__ 'Prevent DMM Network Change Popup'} 
              configName="poi.disableNetworkAlert" 
              defaultVal=false />
            <CheckboxLabelConfig 
              label={__ 'Developer option: check update of beta version'} 
              configName="enableBetaPluginCheck" 
              defaultVal=false />
          </Grid>
        </div>
      </form>
