define([
    'app'
  , 'text!item.html!strip'
  , 'css!item'
  ],
  function (App, source) {
    var that = {};
    var priv = {};

    // ========================== ATTRIBUTES ==============================
    // set response, so it's available across function calls
    priv.response;
    priv.generateContent = function (response) {
      var i, j, k, content, child, dimension, dimensions, variation,
        sub_dimension, sub_dimension_i18n;

      // expose response (will be overwritten, when next item loads
      priv.response = response;

      if (response.price === response.original_price) {
        price = response.price + response.currency;
      } else {
        price = "<span class='rebate'>" + response.price + response.currency +
          "</span> (" + response.original_price + response.currency + ")";
      }

      content = "<ul data-role='listview' data-inset='true' class='" +
        "content_wrap'><li><h3><span class='content_brand'>" + response.brand +
        "</span>&nbsp;<span class='content_title translate' data-i18n=''>" +
        response.title + "</span></h3><p class='content_description" +
        " translate' data-i18n=''>" + response.description +
        "</p><p class='content_pricing ui-li-aside'>" +
        price + "</p></li></ul>";

      dimensions = "<div data-role='fieldcontain' class='dimension_wrap'>";

      // for every dimension
      for (i = 0; i < response.dimensions.length; i += 1) {
        dimension = response.dimensions[i];

        dimensions += "<label for='dims_" + dimension.name + "' class='" +
          "translate' data-i18n='item.select'>Select</label>" +
          "<select class='main_dimension' name='dims_" +
          dimension.name + "' id='" + dimension.name + "'>" +
          "<option class='translate' data-i18n='" + dimension.i18n +
          "' selected='selected' disabled>" + dimension.name +
          "</option>";

        // for every variantion of this dimension
        for (j = 0; j < dimension.vars.length; j += 1) {
          variation = dimension.vars[j];
          dimensions += "<option class='translate' data-i18n='" +
            variation.i18n + "' value='" + variation.name + "'>" +
            variation.name + "</option>";
          // TODO: bad, should not set subdimensions like this...
          if (j === 0) {
            sub_dimension = variation.variations.name;
            sub_dimension_i18n = variation.variations.i18n;
          }
        }

        dimensions += "</select>";

        // TODO: handling of colors is crap. Should be another dimension, but
        // this would be to difficult to associate now. Fix later.
        // TODO: multiple dimensions should work both ways = user can pick a
        // color and all available sizes are shown or user picks a size and
        // all available colors are shown.
        // TODO: change of selected color should also update gallery

        // child dimension container
        child = "<label for='dims_child' class='translate' data-i18n='" +
          "item.select'>Select</label>" +
          "<select name='dims_child' id='dims_child'>" +
          "<option class='translate' data-i18n='" + sub_dimension_i18n +
          "' selected='selected' disabled>" + sub_dimension + "</option></select>";
      }

      return str = content + dimensions + child +"</div>";
    };

    // TODO: show some thing
    priv.generateError = function () {
      return "<p>JIO ERROR</p>";
    };

    // generate content items?
    priv.generateContentItems = function (name) {
//       var i, j, item, img, str = "";
// 
//       item = priv.response.dimensions[0].vars[0];
// 
//       // find item name or default to first variant in dimension
//       if (name !== undefined) {
//         for (i = 0; i < priv.response.dimensions[0].vars.length; i += 1) {
//           item = priv.response.dimensions[0].vars[i];
//           if (item.name === name || location.hash === name) {
//             break;
//           }
//         }
//       }
// 
//       // for every variant (colors, size?, foo?)
//       // TODO: declare a variant that carries images in products JSON!
//       // build string
//       for (j = 0; j < item.media.img.length; j += 1) {
//         img = item.media.img[j];
//         // TODO: add zoom/photoswipe later!
//         str += "<li class='product_img'><a href='#'><img src='" + priv.response.media +
//           img[shortcut] + size + "' alt='" + item.name + "' />" +
//           "<h3 class='translate gallery_header' data-i18n='" +
//           item.i18n + "'></h3></a></li>";
//       }
// 
//       return str;
    };

    priv.swapSecondaryOptions = function (name, element) {
//       var newString = priv.generateContentItems(name),
//         // TODO: if thumbnails are a gallery option, it should be possible
//         // to reference the gallery from the thumbnail without doing this:
//         wrap = App.util.closest(element, ".gallery_thumbnails").previousSibling,
//         gallery = wrap.getElementsByTagName("ul");
// 
//       $(gallery[0]).empty().append(newString).carousel("refresh");
    };

    // generate items to display
    priv.generateItems = function (params) {
      var markup, spec, response;
        id = params.gadget.dom.attr('id').split("__").splice(-1)[0],
        config = params.gadget.state[0][id]._config,
        module = config.datasource.module,
        urlPointer = params.pointer.length > 1,
        jsonPointer = config.datasource.pointer;

      // if we have a pointer-array passed, query that
      // TODO: this access a globally stored current_item set by details gadget!
      if (urlPointer) {
        spec = {};
        spec.storage = "items"
        spec.method = "get"
        spec.doc = {"_id": params.pointer[1]}
      }

      if (jsonPointer) {

      }

      // callback to generate gallery
      spec.callback = function(err, response) {
        if (err) {
          str = priv.generateError();
        } else {
          str = priv.generateContent(response);
        }

        // TODO: this should not replace the whole gadget content
        markup = params.source.replace(/<!-- dimensions_template -->/g, str);

        // this is not response.callback(!!)
        params.callback_mockup(markup);
      };

      if (urlPointer) {
        App[module].switchboard(spec);
      }
    }

    // response object
    that.data = source;
    that.before = function (source, callback_mockup) {
      var spec = {};

      spec.gadget = RenderJs.getSelfGadget();
      spec.page = App.util.closest(spec.gadget.dom.get(0), "div[data-role='page']");
      spec.pageId = "#" + spec.page.id;
      // TODO: retrieving pointers should be a generic method that retrieves
      // pointers either from the URL or from a JSON config object passed!
      spec.pointer = location.search.split("=");
      spec.callback_mockup = callback_mockup;
      spec.source = source;

      // TODO: remove to separate function
      if (!spec.page.getAttribute("events_items")) {
        spec.page.setAttribute("events_items", true);

        $(document).on("pagebeforeshow.items", spec.pageId, function (e) {
          // the pointer in the URL may be updated
          if (location.search) {
            spec.pointer = location.search.split("=");
          }
          priv.generateItems(spec, true);
        })
        .on("change.item", spec.pageId + " .main_dimension", function (e) {
//           var target = e.target,
//             color;
// 
//           if (e.target.tagName === "A") {
//             color = target.href.split("#")[1];
//           } else {
//             color = App.util.closest(target, "a").href.split("#")[1];
//           }
//           priv.swapSecondaryOptions(color, e.target);
        });
        // and run intial
        priv.generateItems(spec);
      }
    };

    that.after = function (self) {
      if (App === undefined) {
        def = new $.Deferred;

        def.done(function(gadget) {
          // prefix instance-ids, pass JSON
          App.renderGadgets(gadget, true);
        });

        window.fallbackLoader.deferreds.push(def);
        window.fallbackLoader.args.push(self);
      } else {
        // prefix instance-ids, pass JSON
        App.renderGadgets(self, true);
      }
    };

  // return response object
  return that;
  }
);
