{{!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.
}}

<div id="installOptions">
  <h2>{{t installer.step2.header}}</h2>

  <p class="alert alert-info">{{t installer.step2.body}}</p>

  <div id="targetHosts">
    <h5>{{t installer.step2.targetHosts}}</h5>

    <div {{bindAttr class="hostsError:error :control-group"}}>
      <p>{{t installer.step2.targetHosts.info}}. Or use
        <a href="javascript:void(null)"
           rel="popover"
          {{translateAttr title="installer.step2.hostPattern.tooltip.title" data-content="installer.step2.hostPattern.tooltip.content"}}>
          {{t installer.step2.hostPattern.tooltip.title}}
        </a>
      </p>

      {{#if view.parentView.controller.hideBackButton}}
        {{#if content.oldHostNames }}
          <p class="alert alert-info">
            {{t hosts.add.step2.warning}}
            <br/>
            {{{content.oldHostNames}}}
              {{#if content.showMoreHostsText}}
                <a href="" {{action showMoreHosts target="view.parentView.controller"}}>{{content.showMoreHostsText}}</a>
              {{/if}}
          </p>
        {{/if}}
      {{/if}}

      <div class="controls">
        {{view Ember.TextArea class="span6" valueBinding="content.hostNames" rows="5" placeholder="host names"}}
        {{#if hostsError}}
        <p class="help-inline">{{hostsError}}</p>
        {{/if}}
      </div>
    </div>
  </div>

  <div id="hostConnectivity">
    <div class="ambari-agents">
      <h5>{{t installer.step2.sshKey}}</h5>

      <p>{{t installer.step2.sshKey.info}}</p>

      <div {{bindAttr class="sshKeyError:error :control-group"}}>
        {{#if view.isFileApi}}
          {{view App.SshKeyFileUploader}}
          <pre {{bindAttr class="view.sshKeyPreviewClass"}}>{{content.sshKey}}</pre>
        {{/if}}
        <div class="controls">
          {{view Ember.TextArea class="span6" rows="4" classBinding="view.sshKeyClass"  id="sshKey" placeholder="ssh private key" disabledBinding="view.sshKeyState" valueBinding="content.sshKey"}}
          {{#if sshKeyError}}
          <span class="help-inline">{{sshKeyError}}</span>
          {{/if}}
        </div>
      </div>

      <div class="manual-install">
      <label class="checkbox">
        {{t installer.step2.manualInstall.label}}
        <a href="javascript:void(null)"
           rel="popover"
          {{translateAttr title="installer.step2.manualInstall.tooltip.title" data-content="installer.step2.manualInstall.tooltip.content"}}>
          Learn more</a>
        {{view Ember.Checkbox checkedBinding="content.manualInstall"}}
      </label>
      </div>

      {{#if "manualInstall"}}
      <div class="alert">
        {{t installer.step2.manualInstall.info}}
      </div>
      {{/if}}

      <!--
    {{view Ember.TextField type="text" placeholder="passphrase" valueBinding="content.passphrase"}}

    <div {{bindAttr class="passphraseMatchErr:error :control-group :ambari-agents"}}>
      <div class="controls">
        {{view Ember.TextField type="text" placeholder="confirm passphrase" valueBinding="content.confirmPassphrase"}}

        {{#if passphraseMatchErr}}
        <p class="help-inline">{{t installer.step2.passphrase.error.match}}</p>
        {{/if}}
      </div>
    </div>
    -->
    </div>
  </div>

  <div id="localRepo">
    <h5>{{t installer.step2.localRepo.header}}</h5>
    <label class="checkbox">
      {{t installer.step2.localRepo.label}}
      <a href="javascript:void(null)"
         rel="popover"
        {{translateAttr title="installer.step2.localRepo.tooltip.title" data-content="installer.step2.localRepo.tooltip.content"}}>
        Learn more</a>
      {{view Ember.Checkbox checkedBinding="content.localRepo"}}
    </label>

    {{#if "localRepo"}}
    <div {{bindAttr class="localRepoError:error :control-group"}}>
      <div class="alert alert-info">
        {{t installer.step2.localRepo.info}}
      </div>
    </div>
    {{/if}}
  </div>
  <div class="btn-area">
    {{#unless view.parentView.controller.hideBackButton }}
    <a class="btn pull-left" {{action back}}>&larr; Back</a>
    {{/unless}}
    <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action evaluateStep}}>
      Discover and Validate &rarr;</a>
  </div>

</div>