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

    priv.generateGallery = function (response) {
      // TODO: we will generate two listviews now, until the gallery widget
      // also has a thumbnail option
      // TODO: allow the gallery to exist without links...
      // TODO: zoom is missing, this should also be a feature of gallery
      // ala photoswipe
      var i, j, item, img, gallery, thumbnails, str, obj;

      gallery = "<div class='gallery_wrap'><ul data-role='carousel' " +
        "data-inset='true' class='" +
        "ui-responsive tester' data-captions='true' data-transition='" +
        "slide'>";
      thumbnails = "<div class='gallery_thumbnails '><ul data-role='" +
        "listview' data-inset='true' class='gallery_thumbnail_wrapper'>";

      if (response.items) {
         for (i = 0; i < response.items.length; i += 1) {
          obj = response.items[i];

          gallery += "<li><a href='" + obj.href + "'><img src='" + obj.src +
            "' alt='" + obj.caption + "' />" +
            "<h3 class='translate gallery_header' data-i18n='" +
            obj.i18n + "'>" + obj.caption + "</h3></a></li>";
        }
          gallery += "</ul></div>";
  
        return str = gallery;
      }

      // for every variant (colors, size?, foo?)
      // TODO: declare a variant that carries images in products JSON!
      for (i = 0; i < response.dimensions[0].vars.length; i += 1) {
        item = response.dimensions[0].vars[i];

        // add elements to container only if name is provided
        if (item.name !== undefined) {
          // TODO: allow to pick color to display first or most-sold or...
          if (i === 0) {
            for (j = 0; j < item.media.img.length; j += 1) {
              img = item.media.img[j];

              // TODO: add zoom/photoswipe later!
              gallery += "<li><a href='#'><img src='" + response.media +
                img[shortcut] + size + "' alt='" + item.name + "' />" +
                "<h3 class='translate gallery_header' data-i18n='" +
                item.i18n + "'></h3></a></li>";
            }
          }
          gallery += "</ul></div>";
        }

        // thumbnails - click on link should trigger the display method
        thumbnails += "<li data-icon='false'><a href='#' class='" +
          "display_item'><img src='" + response.media + item.media.img[0]["t"] + "' alt='"
          + item.name + "' /><h3 class='translate gallery_header' data-i18n='" +
          item.i18n + "'>" + item.name + "</h3></li>";
      }
      thumbnails += "</ul></div>";

      return str = gallery + thumbnails;
    };

    priv.generateError = function () {
      return "<p>Foo</p>";
    };

    // 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,

        // TODO: settable options
        screen = App.settings.screen_format,
        size = screen === "small" ? "small" : "medium",
        shortcut = size.substring(0, 1);

      // if we have a pointer-array passed, query that
      // TODO: this is not flexible yet, because "items" and "get" are hardcoded
      // TODO: also, jIO GET only allows to query by id, so that should be
      // what is stored on the image links...
      if (urlPointer) {
        spec = {};
        spec.storage = "items"
        spec.method = "get"
        spec.doc = {"_id": params.pointer[1]}
      }

      if (jsonPointer) {
        spec = {};
        // TODO: no time to get items form somewhere now. This should be passed
        // in the configuration file, as it's something the user can use or not
        // also - should be possible to make this fullscreen by supplying the
        // carousel options!
        spec.items = [
          {"src":"img/stella.jpg", "caption":"Stella", "i18n": "custom.teaser.stella", "href": "products.html?search=stella"},
          {"src":"img/nannin.jpg", "caption":"Nan", "i18n": "custom.teaser.nan", "href": "products.html?search=nan"},
          {"src":"img/vila.jpg", "caption":"Vila", "i18n": "custom.teaser.vila", "href": "products.html?search=vila"}
        ]
      }

      // callback to generate gallery
      spec.callback = function(err, response) {

        if (err) {
          str = priv.generateError();
        } else {
          str = priv.generateGallery(response);
        }

        // TODO: this should not replace the whole gadget content
        markup = params.source.replace(/<!-- gallery -->/g, str);
 
        // this is not response.callback(!!)
        params.callback_mockup(markup);
      };

      if (urlPointer) {
        // query for items
        App[module].switchboard(spec);
      }
      if (jsonPointer) {
        // TODO: image pictures should also be fetched and stored in JIO
        // just run callback now and generate gallery
        spec.callback(undefined, spec);
      }
    }

    // response object
    that.data = source;
    that.mockup = 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;

      priv.generateItems(spec);
    };

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

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

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

  // return response object
  return that;
  }
);
