<svelte:head>
  <title>Buttons the Programming Language</title>
</svelte:head>

<script>
  import {goto, stores} from '@sapper/app';
  import { ButtonMachine } from 'buttons';
  import Icon from '../components/Icon.svelte';
  const { session } = stores();

  let code = [
    ['PUSH', -20], // start at -20
    ['PUSH', 1],  // increment by 1
    ['ADD'],      
    ['JZ'],    // if we're at 0 jumps to the end
    ['JUMP', 1]    // the previous test fails so it jumps to loop again
  ];

  let machine = new ButtonMachine(code);

  let has_error = false;

  $: has_error = machine.error != '';

  const data_ops = new Set(['PUSH', 'JZ', 'JNZ', 'JUMP', 'STOR', 'RSTOR', 'HALT']);

  const ops = machine.operations;

  const change_op = (i, count) => {
    let cur_op = code[i][0];
    let cur_index = ops.indexOf(cur_op);
    let new_index = (cur_index + count) < 0 ? ops.length - 1 : (cur_index + count) % ops.length; 

    code[i][0] = ops[new_index];
  }

  const op_has_data = (op) => data_ops.has(op);

  const run_machine = () => {
    machine.run();
    machine = machine; // make svelte go
  }

  const step_machine = () => {
    machine.step();
    machine = machine;
  }

  const reset_machine = () => {
    machine = new ButtonMachine(code);
  }

  const clone_line = (i) => {
    let clone = code[i];
    code.splice(i, 0, [...clone]);
    code = code;
  }

  const delete_line = (i) => {
    let item = code.splice(i, 1);
    code = code;
  }
</script>

<style lang="scss">
  @import "sass/_variables";

  .active-line {
    background-color: $warning-color !important;
  }

  .empty-data {
    width: 100%;
    background-color: lighten($primary-color, 40%);
  }
</style>

<div class="container grid-xl" id="content" data-testid="buttons-page">
  <div class="columns">
    <div class="column col-12">
      <table class="table">
        <thead>
          <tr>
            <th>IP</th>
            <th>TICK</th>
            <th>HALT</th>
            <th>ERROR</th>
          </tr>
        </thead>
        <tbody>
          <tr class="active">
            <td>{ machine.ip }</td>
            <td>{ machine.tick }</td>
            <td>{ machine.halted }</td>
            <td>{ machine.error }</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <br/>

  <div class="columns">
    <div class="column col-6">
    <button class="btn btn-primary" on:click={ run_machine }><Icon name="play-circle" tooltip="Run it" light={ true }/></button>
    <button class="btn btn-primary" on:click={ step_machine }><Icon name="clock" tooltip="Step through" light={ true }/></button>
    <button class="btn btn-primary" on:click={ reset_machine }><Icon name="power" tooltip="Reset" light={ true }/></button>

    <div class="divider"></div>
      {#each code as [op, data], i} 
        <div class="input-group" class:has-error={ has_error }>
          {#if has_error && machine.error_line == i}
            <Icon name="alert-triangle" color="red" />
          {:else}
            {i}:
          {/if}

            <button class:active-line={ machine.ip == i } 
                       on:click={ () => change_op(i, +1) } 
                       on:contextmenu|preventDefault={ () => change_op(i, -1) }
                       class="btn btn-primary input-group-btn">{op}</button>

          {#if op_has_data(op)}
            {#if op === 'STOR' || op === 'RSTOR' || op == 'HALT'}
              <input class:active-line={ machine.ip == i } 
                     type="text" class="form-input" placeholder="register" bind:value={data}>
            {:else}
              <input class:active-line={ machine.ip == i } 
                     type="number" class="form-input" placeholder="data" bind:value={data}>
            {/if}
          {:else}
            <div class:active-line={ machine.ip == i } class="empty-data"></div>
          {/if}

          <button class="btn btn-primary input-group-addon"
                  on:click={ () => clone_line(i) }>
                  <Icon name="copy" tooltip='Clone it'/>
          </button>
          <button class="btn btn-primary input-group-addon"
                  on:click={ () => delete_line(i) }>
                  <Icon name="delete" tooltip='Delete it'/>
          </button>
        </div>
      {/each}
    </div>
    <div class="column col-2">
      <table class="table">      <thead>
         <tr>
           <th>STACK</th>
         </tr>
       </thead>

        {#each machine.stack as datum, i} 
          <tr>
            <td>{datum}</td>
          </tr>
        {/each}
      </table>
    </div>
    <div class="column col-4">
     <table class="table">
       <thead>
         <tr>
           <th>REGISTER</th>
           <th>VALUE</th>
         </tr>
       </thead>
       <tbody>
         {#each machine.register_entries as [name, value] }
         <tr class="active">
           <td>{ name }</td>
           <td>{ value }</td>
         </tr>
         {/each}
       </tbody>
     </table>
    </div>
  </div>
</div>
