define([
    'jquery'
  , 'complex_queries'
  , 'jio'
  , 'md5'
  , 'localstorage'
  //, 'indexstorage'
], function () {
  "use strict";

  var priv = {};
  var that = {};

  // ========================================================================
  //                            ATTRIBUTES
  // ========================================================================

  // ========================================================================
  //                            INTERNAL METHODS
  // ========================================================================

  // ============================ JIO ========================
  //
  // setup JIO instances
  // @method setupJIO
  //

  priv.setupJIO = function (callback) {

    // items
    priv.items = jIO.newJio({
      "type": "local",
      "username": "eci",
      "application_name": "items"
    });

    // basket
    priv.basket = jIO.newJio({
      "type": "local",
      "username": "ecb",
      "application_name": "basket"
    });

    // settings - should these be in localstorage or global object?
    priv.settings = jIO.newJio({
     "type": "local",
     "username": "ecs",
     "application_name": "settings"
    });
    // add items
    callback();
  };

  //
  // DEV: add dummy products
  // @method populate_item_storage
  //
  priv.populate_item_storage = function () {
    priv.items.put({
      "_id": "1",
      "item_id": "1",
      "brand": "VILA",
      "brand_id": "123",
      "seller_id": "",
      "title": "Abiona Jacket",
      "unit": "pc",
      "currency": "EUR",
      "keywords": ["Jacket", "Abiona"],
      "category": [
        {"0": "outerwear"},
        {"1": "jackets"},
        {"2": "ladies"}
      ],
      "price": 44.95,
      "original_price": 64.95,
      "total_sales": 69,
      "description": "DOUBELT BREASTED JACKET 100% Polyester, matière souple et très résistante. entretien facile Coupe ajustée Fermeture boutons sur le devant Longueur : 78cm en taille S",
      "media": "http://www.weinparis.com/en/product_module/",
      "comments": [{
        "date": "2012/12/13",
        "locale": "en-EN",
        "rating": "1",
        "comment": "I look fat in this jacket!!!",
        "user": "anonymous"
      }, {
        "date": "2012/12/22",
        "locale": "fr-FR",
        "rating": 5,
        "comment": "parfait pour mon travaille!",
        "user": "Tom"
      }],
      "dimensions": [{
        "name": "colors",
        "i18n": "custom.dimensions.colors",
        "vars": [{
          "name": "blue",
          "i18n": "custom.colors.blue",
          "media": {
            "img": [{
              "type": "main",
              "t": "186/15/default_image?format=jpg&display=micro",
              "s": "186/15/default_image?format=jpg&display=",
              "m": "186/15/default_image?format=jpg&display=",
              "l": "186/15/default_image?format=jpg&display=",
              "xl": "186/15/default_image?format=jpg"
            }, {
              "t": "186/15/1?format=jpg&display=micro",
              "s": "186/15/1?format=jpg&display=",
              "m": "186/15/1?format=jpg&display=",
              "l": "186/15/1?format=jpg&display=",
              "xl": "186/15/1?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "S",
              "i18n": "custom.sizes.s",
              "sold": 21
            }, {
              "ean": "",
              "name": "M",
              "i18n": "custom.sizes.m",
              "sold": 12,
              "na": "true"
            }, {
              "ean": "",
              "name": "L",
              "i18n": "custom.sizes.l",
              "sold": 25,
              "na": "true"
            }, {
              "ean": "",
              "name": "XL",
              "i18n": "custom.sizes.xl",
              "sold": 11
            }]
          }
        }]
      }]
    });

    priv.items.put({
      "_id": "2",
      "item_id": "2",
      "brand": "Stella Forest",
      "brand_id": "123",
      "seller_id": "",
      "title": "Pleat Pantalon",
      "unit": "pc",
      "currency": "EUR",
      "keywords": ["Pleat", "Pantalon", "Stella Forest"],
      "category": [
        {"0": "outerwear"},
        {"1": "pantalon"},
        {"2": "ladies"}
      ],
      "price": "134.00",
      "original_price": "134.00",
      "total_sales": 40,
      "description": "Pantalon 95% polyester 5% spandex. Coupe droite. Fluide. Poches italiennes. Taille élastiquée. un look décontracté chic !",
      "media": "http://www.weinparis.com/en/product_module/",
      "comments": [{
        "date": "2012/12/03",
        "locale": "en-EN",
        "rating": "3",
        "comment": "Nice pants, quick delivery!",
        "user": "anonymous"
      }, {
        "date": "2012/12/12",
        "locale": "fr-FR",
        "rating": "5",
        "comment": "J'adore les pantalones!",
        "user": "Francine"
      }],
      "dimensions": [{
        "name": "colors",
        "i18n": "custom.dimensions.colors",
        "vars": [{
          "name": "blue",
          "i18n": "custom.colors.blue",
          "media": {
            "img": [{
              "type": "main",
              "t": "238/16/default_image?format=jpg&display=micro",
              "s": "238/16/default_image?format=jpg&display=",
              "m": "238/16/default_image?format=jpg&display=",
              "l": "238/16/default_image?format=jpg&display=",
              "xl": "238/16/default_image?format=jpg"
            }, {
              "t": "238/16/3?format=jpg&display=micro",
              "s": "238/16/3?format=jpg&display=",
              "m": "238/16/3?format=jpg&display=",
              "l": "238/16/3?format=jpg&display=",
              "xl": "238/16/3?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "34",
              "i18n": "custom.sizes.34",
              "sold": 2
            }, {
              "ean": "",
              "name": "36",
              "i18n": "custom.sizes.36",
              "sold": 1
            }, {
              "ean": "",
              "name": "38",
              "i18n": "custom.sizes.38",
              "sold": 25,
              "na": "true"
            }, {
              "ean": "",
              "name": "40",
              "i18n": "custom.sizes.40",
              "sold": 12,
              "na": "true"
            }]
          }
        }]
      }]
    });
    priv.items.put({
      "_id": "3",
      "item_id": "3",
      "brand": "Eleven Paris",
      "brand_id": "123",
      "title": "Pull Octave ",
      "unit": "pc",
      "currency": "EUR",
      "keywords": ["Pleat", "Octave", "Eleven Paris"],
      "category": [
        {"0": "outerwear"},
        {"1": "pull"},
        {"2": "ladies"}
      ],
      "price": "45.00",
      "original_price": "65.00",
      "total_sales": 14,
      "description": "Pull bi-matière. coton bio avec polyester Col rond petite poche à une côte. coupe ample",
      "media": "http://www.weinparis.com/en/product_module/",
      "comments": [{
        "date": "2012/12/03",
        "locale": "en-EN",
        "rating": "3",
        "comment": "Nice pants, quick delivery!",
        "user": "anonymous"
      }, {
        "date": "2012/12/12",
        "locale": "fr-FR",
        "rating": "5",
        "comment": "J'adore les pantalones!",
        "user": "Francine"
      }],
      "dimensions": [{
        "name": "colors",
        "i18n": "custom.dimensions.colors",
        "vars": [{
          "name": "orange",
          "i18n": "custom.colors.orange",
          "media": {
            "img": [{
              "type": "main",
              "t": "75/11/default_image?format=jpg&display=micro",
              "s": "75/11/default_image?format=jpg&display=",
              "m": "75/11/default_image?format=jpg&display=",
              "l": "75/11/default_image?format=jpg&display=",
              "xl": "75/11/default_image?format=jpg"
            }, {
              "t": "75/11/3?format=jpg&display=micro",
              "s": "75/11/3?format=jpg&display=",
              "m": "75/11/3?format=jpg&display=",
              "l": "75/11/3?format=jpg&display=",
              "xl": "75/11/3?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "S",
              "i18n": "custom.sizes.s",
              "sold": 12
            }, {
              "ean": "",
              "name": "M",
              "i18n": "custom.sizes.m",
              "sold": 1
            }, {
              "ean": "",
              "name": "L",
              "i18n": "custom.sizes.l",
              "sold": 1
            }, {
              "ean": "",
              "name": "XL",
              "i18n": "custom.sizes.xl",
              "sold": 0
            }]
          }
        }]
      }]
    });
    priv.items.put({
      "_id": "4",
      "item_id": "4",
      "brand": "Eleven Paris",
      "brand_id": "123",
      "seller_id": "",
      "title": "PASSY Pants ",
      "unit": "pc",
      "currency": "EUR",
      "keywords": ["Passy", "Pantalon", "Eleven Paris"],
      "category": [
        {"0": "outerwear"},
        {"1": "pantalones"},
        {"2": "ladies"}
      ],
      "price": "55.00",
      "original_price": "75.00",
      "total_sales": 182,
      "description": "pantalon en 97% Cotton 3% Elastane Fermeture: braguette à fermeture éclair cachée Poches: poches de coté Lavage en machine à 30° C",
      "media": "http://www.weinparis.com/en/product_module/",
      "comments": [{
        "date": "2012/12/01",
        "locale": "en-EN",
        "rating": "4",
        "comment": "Great pant, tight and snuggly fit!",
        "user": "anonymous"
      }, {
        "date": "2012/12/03",
        "locale": "fr-FR",
        "rating": "5",
        "comment": "J'adore!",
        "user": "Francine"
      }],
      "dimensions": [{
        "name": "colors",
        "i18n": "custom.dimensions.colors",
        "vars": [{
          "name": "peppermint",
          "i18n": "custom.colors.peppermint",
          "media": {
            "img": [{
              "type": "main",
              "t": "131/27/default_image?format=jpg&display=micro",
              "s": "131/27/default_image?format=jpg&display=",
              "m": "131/27/default_image?format=jpg&display=",
              "l": "131/27/default_image?format=jpg&display=",
              "xl": "131/27/default_image?format=jpg"
            }, {
              "t": "131/27/3?format=jpg&display=micro",
              "s": "131/27/3?format=jpg&display=",
              "m": "131/27/3?format=jpg&display=",
              "l": "131/27/3?format=jpg&display=",
              "xl": "131/27/3?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "34",
              "i18n": "custom.sizes.34",
              "sold": 27
            }, {
              "ean": "",
              "name": "36",
              "i18n": "custom.sizes.36",
              "sold": 7
            }, {
              "ean": "",
              "name": "38",
              "i18n": "custom.sizes.38",
              "sold": 1
            }, {
              "ean": "",
              "name": "40",
              "i18n": "custom.sizes.40",
              "sold": 6
            }]
          }
        }, {
          "name": "shell",
          "i18n": "custom.colors.shell",
          "media": {
            "img": [{
              "type": "main",
              "t": "131/24/default_image?format=jpg&display=micro",
              "s": "131/24/default_image?format=jpg&display=",
              "m": "131/24/default_image?format=jpg&display=",
              "l": "131/24/default_image?format=jpg&display=",
              "xl": "131/24/default_image?format=jpg"
            }, {
              "t": "131/24/3?format=jpg&display=micro",
              "s": "131/24/3?format=jpg&display=",
              "m": "131/24/3?format=jpg&display=",
              "l": "131/24/3?format=jpg&display=",
              "xl": "131/24/3?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "34",
              "i18n": "custom.sizes.34",
              "sold": 4
            }, {
              "ean": "",
              "name": "36",
              "i18n": "custom.sizes.36",
              "sold": 0
            }, {
              "ean": "",
              "name": "38",
              "i18n": "custom.sizes.38",
              "sold": 0
            }, {
              "ean": "",
              "name": "40",
              "i18n": "custom.sizes.40",
              "sold": 1
            }]
          }
        }, {
          "name": "peach",
          "i18n": "custom.colors.peach",
          "media": {
            "img": [{
              "type": "main",
              "t": "131/25/default_image?format=jpg&display=micro",
              "s": "131/25/default_image?format=jpg&display=",
              "m": "131/25/default_image?format=jpg&display=",
              "l": "131/25/default_image?format=jpg&display=",
              "xl": "131/25/default_image?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "34",
              "i18n": "custom.sizes.34",
              "sold": 14,
              "na": "true"
            }, {
              "ean": "",
              "name": "36",
              "i18n": "custom.sizes.36",
              "sold": 12,
              "na": "true"
            }, {
              "ean": "",
              "name": "38",
              "i18n": "custom.sizes.38",
              "sold": 10,
              "na": "true"
            }, {
              "ean": "",
              "name": "40",
              "i18n": "custom.sizes.40",
              "sold": 2
            }]
          }
        }, {
          "name": "passy",
          "i18n": "custom.colors.passy",
          "media": {
            "img": [{
              "type": "main",
              "t": "131/26/default_image?format=jpg&display=micro",
              "s": "131/26/default_image?format=jpg&display=",
              "m": "131/26/default_image?format=jpg&display=",
              "l": "131/26/default_image?format=jpg&display=",
              "xl": "131/26/default_image?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "34",
              "i18n": "custom.sizes.34",
              "sold": 56,
              "na": "true"
            }, {
              "ean": "",
              "name": "36",
              "i18n": "custom.sizes.36",
              "sold": 23,
              "na": "true"
            }, {
              "ean": "",
              "name": "38",
              "i18n": "custom.sizes.38",
              "sold": 12,
              "na": "true"
            }, {
              "ean": "",
              "name": "40",
              "i18n": "custom.sizes.40",
              "sold": 7
            }]
          }
        }]
      }]
    });
    priv.items.put({
      "_id": "5",
      "item_id": "5",
      "brand": "See U Soon",
      "brand_id": "356",
      "title": "Debardeur Eve",
      "unit": "pc",
      "currency": "EUR",
      "keywords": ["Debardeur", "Eve", "See U Soon"],
      "category": [
        {"0": "outerwear"},
        {"1": "debardeur"},
        {"2": "ladies"}
      ],
      "price": "30.00",
      "original_price": "45.00",
      "total_sales": 5,
      "description": "Debarteur en Polyester. matière souple et très résistante. entretien facile Coupe ample Fermeture éclair sur le dos.",
      "media": "http://www.weinparis.com/en/product_module/",
      "comments": [{
        "date": "2012/11/03",
        "locale": "en-EN",
        "rating": "5",
        "comment": "Who is Missoni?",
        "user": "Viktor"
      }, {
        "date": "2012/11/05",
        "locale": "fr-FR",
        "rating": "1",
        "comment": "Jeu perfer noir et blanc!",
        "user": "Francine"
      }],
      "dimensions": [{
        "name": "colors",
        "i18n": "custom.dimensions.colors",
        "vars": [{
          "name": "vert",
          "i18n": "custom.colors.vert",
          "media": {
            "img": [{
              "type": "main",
              "t": "595/15/default_image?format=jpg&display=micro",
              "s": "595/15/default_image?format=jpg&display=",
              "m": "595/15/default_image?format=jpg&display=",
              "l": "595/15/default_image?format=jpg&display=",
              "xl": "595/15/default_image?format=jpg"
            }, {
              "t": "595/15/3?format=jpg&display=micro",
              "s": "595/15/3?format=jpg&display=",
              "m": "595/15/3?format=jpg&display=",
              "l": "595/15/3?format=jpg&display=",
              "xl": "595/15/3?format=jpg"
            }]
          },
          "variations": {
            "name": "sizes",
            "i18n": "custom.dimensions.sizes",
            "variants": [{
              "ean": "",
              "name": "T0",
              "i18n": "custom.sizes.t0",
              "sold": 4
            }, {
              "ean": "",
              "name": "T1",
              "i18n": "custom.sizes.t1",
              "sold": 1
            }, {
              "ean": "",
              "name": "T2",
              "i18n": "custom.sizes.t2",
              "sold": 0
            }, {
              "ean": "",
              "name": "T3",
              "i18n": "custom.sizes.t3",
              "sold": 0
            }]
          }
        }]
      }]
    });
  };

  // initialize application
  // @method initialize
  //
  priv.initialize = function () {

    // > set up JIOs
    priv.setupJIO(function() {
      // > populate JIOs
      priv.populate_item_storage();
    });
  };

  // ========================================================================
  //                      PUBLIC METHODS => window.App.method()
  // ========================================================================

//
  // query one of the available storages
  // @method queryStorage
  // @param {object} param > jIO parameters (storage, method, doc, options...)
  // @return {object} response > response/error object
  //
  that.queryStorage = function (param) {
    if (param.doc !== undefined) {
      priv[param.storage][param.method](param.doc, param.options, param.callback);
    } else {
      priv[param.storage][param.method](param.options, param.callback);
    }
  };

  //
  // switchboard to root function calls while links are not working
  // @method switchboard
  // @param {string} pointer > temporary solution until links can be used!
  // @param {string} method > jIO method to call
  // @param {object} options > options for jIO object
  // @param {method} callback > callback to run with results
  // pointer, method, options, callback
  that.switchboard = function (param) {
    var i,
      j,
      item,
      cases = [],
      query = {},
      spec = param || {},
      searchString = "";

    // default object
    spec.default_items = [
      "_id",
      "item_id",
      "brand",
      "total_sales",
      "price",
      "original_price",
      "title",
      "media",
      "dimensions"
    ];

    query.limit = [];
    query.sort_on = [];
    query.select_list = [];
    query.wildcard_character = '%'

    // if we have a pointer, we can disregard method & options,
    // but we must set on spec directly, because query will only be
    // assigned in a defined case
    // TODO: not nice to hardquery for "allDocs" here, but... improve later
    if (param.pointer === undefined && param.method === "allDocs" && spec.options !== undefined) {
      spec.options.limit = param.options.limit;
      spec.options.sort_on = param.options.sort_on;
      spec.options.select_list = param.options.select_list || spec.default_items;
      spec.options.wildcard_character = '%'
    }

    // queries can be run
    // > with different cases (currently upper/lower case),
    // > on full select_list (passed elements or default),
    // > without a query object, if empty string is passed (nothing to parse, faster search)
    // > TODO: optionable?
    if (spec.query) {
      if (spec.query_string !== "") {
        cases.push(
          spec.query_string,
          spec.query_string.toUpperCase(),
          spec.query_string.toLowerCase(),
          spec.query_string.charAt(0).toUpperCase() + spec.query_string.slice(1)
        );
        for (j = 0; j < cases.length; j += 1) {
          for (i = 0; i < spec.options.select_list.length; i += 1) {
            item = spec.options.select_list[i];
            searchString += item + ': = "' + query.wildcard_character + cases[j] + query.wildcard_character + '"';
            if (i < spec.options.select_list.length-1) {
              searchString += ' OR ';
            }
          }
        }
        spec.options.query = searchString;
      }
    }

    switch (param.pointer) {
      case "topsellers":
        query.limit.push(0, 4);
        query.sort_on.push(["total_sales", "descending"]);
        query.select_list = spec.default_items;

        spec.storage = "items";
        spec.method = "allDocs";
        spec.options = query;
        spec.callback = param.callback;

        // query
        that.queryStorage(spec);
      break;
      case "topbrands":

      break;

      // default
      default:
        that.queryStorage(spec);
      break;
    }
  };
  // ========================================================================
  //                            INITIALIZE
  // ========================================================================
  priv.initialize();

  // ========================================================================
  //                            PUBLISH APP
  // ========================================================================

  // return public methods to main.js
  return that;
});