<!DOCTYPE html>
<html>

<head>
  <link href="//cdn.jsdelivr.net/picnicss/5.1.0/picnic.min.css" rel="stylesheet" />
  <link href="//cdn.jsdelivr.net/picnicss/5.1.0/plugins.min.css" rel="stylesheet" />
</head>

<body>

  <h1>Hello Mag.JS - Redux Todos!</h1>
  <a target="_tab" href="https://github.com/magnumjs/mag.js">GitHub</a>
  <hr/> (based on <a href="https://github.com/chrisharrington/react-todo">React-Todo</a>)

  <div class="container content">
    <div id="app">
      <div class="container">
        <div class="row">
          <div class="col-md-8">
            <h2>Todo List</h2>
            <status>Loading ..</status>
          </div>
          <div class="col-md-4">
            <label for="modal_1" type="button" class="btn btn-primary pull-right spacing-top button">New Task</label>
          </div>
        </div>
        <div class="row">
          <div class="col-md-6">
            <h3 class="spacing-bottom">Incomplete</h3>
            <listIncomplete>
            </listIncomplete>
          </div>
          <div class="col-md-6">
            <h3 class="spacing-bottom">Complete</h3>
            <listComplete>
            </listComplete>
          </div>
        </div>

        <div id="modal">
          <div class="modal">
            <input id="modal_1" type="checkbox" />
            <label for="modal_1" class="overlay"></label>
            <article>
              <header>
                <h3>New Task</h3>
                <label for="modal_1" class="close">&times;</label>
              </header>
              <section class="content">
                <input name="text" class="field" />
              </section>
              <footer>
                <a class="button" href="#">Save</a>
                <label for="modal_1" class="button dangerous">
                  Close
                </label>
              </footer>
            </article>
          </div>
        </div>

      </div>
    </div>
  </div>

  <div style="display:none;">
    <div id="lister">
      <div class="list-group card">
        <renderItems>
          <item></item>
        </renderItems>
      </div>
    </div>
  </div>

  <div style="display:none;">
    <div id="item">
      <header class="list-group-item pointer">
        <span class="button stack icon-picture" data-bind="name">Home</span>
      </header>
    </div>
  </div>

  <script src="//rawgit.com/magnumjs/mag.js/master/dist/mag.0.21.3.min.js"></script>
  <script src="//rawgit.com/magnumjs/mag.js/master/dist/mag.addons.0.21.min.js"></script>
  <script src="//rawgit.com/magnumjs/mag.js/master/dist/mag-redux.0.22.min.js"></script>
  <script src="//rawgit.com/magnumjs/mag.js/master/src/addons/redux-middleware.js"></script>

  <script src="item.js"></script>
  <script src="modal.js"></script>
  <script src="list.js"></script>
  <script src="app.js"></script>
  <script src="redux.js"></script>
  <script src="boot.js"></script>
</body>

</html>
//Component definition and instance creation - not executed
var app = mag.create('app', {
  controller: function(props) {

    // get all todos
    props.getAllTodos()

    modaler({
      isVisible: props.isVisible,
      onSave: function(data) {
        props.createTodo({
          name: data.name
        });
      }
    });

  },

  view: function(state, props) {
    mag.show(!props.todos.data.length, state.status = {});
    
    if (props.todos.data.length) {
      state.listIncomplete = this.renderList(props.todos.data, false, props.update);

      state.listComplete = this.renderList(props.todos.data, true, props.update);
    }
  },
  renderList: function(todos, complete, update) {

    var filteredItems = todos.filter(function(x) {
      return x.isComplete === complete;
    });

    return lister({
      update: update,
      key: Math.random(),
      items: filteredItems
    })
  }
}, {
  isVisible: null
});
var magRedux = (function() {

  //Action types:
  var constants = {
    todo: {
      GET_ALL_TODOS: "GET_ALL_TODOS",
      ADD_TODO: "ADD_TODO",
      UPDATE: "UPDATE"
    }
  };

  //Redux State reducer: 
  var reducer = function(state, action) {
    if (!state) {
      return {
        data: [],
        text: "ZZZ"
      };
    }

    function setState(state, change) {
      return Object.assign({}, state, change);
    }

    switch (action.type) {
      case constants.todo.UPDATE:
        var found = state.data.findIndex(function(item) {
          return item.id == action.todo.id;
        });
        state.data[found] = action.todo;
        return setState(state, {
          data: state.data
        });
      case constants.todo.GET_ALL_TODOS:
        return setState(state, {
          data: action.todos
        });
      case constants.todo.ADD_TODO:

        action.todo.id = Math.max.apply(Math, state.data.map(function(o) {
          return o.id;
        })) + 1;
        action.todo.isComplete = false;
        state.data.push(action.todo);

        return setState(state, {
          text: action.todo.name,
          data: state.data
        });

      default:
        return state;
    }
  };


  //Actions:
  var actions = {
    createTodo: function(todo) {
      return {
        type: constants.todo.ADD_TODO,
        todo: todo
      }
    },
    update: function(todo) {
      return {
        type: constants.todo.UPDATE,
        todo: todo
      }
    },
    getAllTodos: function() {
      return function(dispatch) {
        mag.request({
          url: 'todos.json',
          cache: false
        }).then(function(data) {
          // dispatch when completed
          dispatch({
            todos: data,
            type: constants.todo.GET_ALL_TODOS
          });
        })

      };
    },
    clickText: function(text) {
      return {
        type: constants.todo.ADD_TODO,
        text: text
      }
    }
  };

  return {
    constants: constants,
    reducer: reducer,
    actions: actions
  }

})();
//Connect & run Component:

mag.reduxConnect({}, magRedux.actions, {
  "todos": magRedux.reducer
}, [Redux.middle.logger, Redux.middle.readyStatePromise])(app);

var lister = mag.create('lister', {
  
  view: function(state, props) {
    
    state.renderItems =
      props.items.map(function(item, i) {
        
        return {
          item: itemer({
            key: props.key + i,
            todo: item,
            toggle: function(iteme) {
              iteme.isComplete = !iteme.isComplete;
              props.update(iteme);
            }.bind({}, item)
          })
        }
      })
  }
})
var itemer = mag.create('item', {

  view: function(state, props) {

    state.header = {
      name: props.todo.name,
      _onClick: props.toggle
    }
    
  }
});
[
    {
        "id": 1,
        "name": "Pick up milk",
        "isComplete": false
    },
    {
        "id": 2,
        "name": "Pick up dry cleaning",
        "isComplete": true
    },
    {
        "id": 3,
        "name": "Grocery shopping",
        "isComplete": false
    },
    {
        "id": 4,
        "name": "Hem pants",
        "isComplete": false
    },
    {
        "id": 5,
        "name": "Oil change",
        "isComplete": true
    }
]
var modaler = mag.create('modal', {
  controller: function(props) {

    this.text = '';

  },
  view: function(state, props) {

    state.modal_1 = {
      _checked: typeof props.isVisible != 'undefined' ? props.isVisible : null
    }

    state.a = {
      _onClick: function() {
        props.onSave({
          name: state.text
        });
        state.text = '';
        props.isVisible = false;
      }
    }

  }
})