dojo.require("dojox.fx.scroll");
dojo.require('dojox.image.ThumbnailPicker');
dojo.require('dojox.image.SlideShow');
dojo.require('dojox.image.Gallery');

function removeStyleProperty(node, property) {
  var style = node.style;
  if (typeof style.removeProperty === 'function') {
    style.removeProperty(property);
  }
  else {
    style.removeAttribute(property);
  }
}

(function(){
  
  dojox.fx.smoothScroll = function(/* Object */args){
    // summary: Returns an animation that will smooth-scroll to a node
    // description: This implementation support either horizontal or vertical scroll, as well as
    // both. In addition, element in iframe can be scrolled to correctly.
    // offset: {x: int, y: int} this will be added to the target position
    // duration: Duration of the animation in milliseconds.
    // win: a node or window object to scroll

    if(!args.target){ args.target = dojo.position(args.node); }

    var isWindow = dojo[(dojo.isIE ? "isObject" : "isFunction")](args["win"].scrollTo),
      delta = { x: args.target.x, y: args.target.y }
    ;
    /*
    if(!isWindow){
      var winPos = dojo.position(args.win);
      delta.x -= winPos.x;
      delta.y -= winPos.y;
    }
    */
    var _anim = (isWindow) ?
      (function(val){
        args.win.scrollTo(val[0],val[1]);
      }) :
      (function(val){
        args.win.scrollLeft = val[0];
        args.win.scrollTop = val[1];
      });
    var anim = new dojo.Animation(dojo.mixin({
      beforeBegin: function(){
        if(this.curve){ delete this.curve; }
        var current = isWindow ? dojo._docScroll() : {x: args.win.scrollLeft, y: args.win.scrollTop};
        anim.curve = new dojox.fx._Line([current.x,current.y],[args.target.x, args.target.y]);
        //anim.curve = new dojox.fx._Line([current.x,current.y],[current.x + delta.x, current.y + delta.y]);
      },
      onAnimate: _anim
    },args));
    return anim; // dojo.Animation
  };

  var thumbPickerProto = dojox.image.ThumbnailPicker.prototype;
  thumbPickerProto.templateString = dojo.cache("uzh.image", "resources/ThumbnailPicker.html");
  var oldThumbPickerProtoPostCreate = thumbPickerProto.postCreate;
  thumbPickerProto.postCreate = function() {
    oldThumbPickerProtoPostCreate.apply(this, arguments);
    removeStyleProperty(this.outerNode, "width");
    removeStyleProperty(this.outerNode, "text-align");
    removeStyleProperty(this.thumbScroller, "width");
    this._scrollerSize = this.thumbScroller.offsetWidth;
    dojo.style(this.thumbScroller, "width", this._scrollerSize + "px");
  };
  
  thumbPickerProto.resize = function(dim) {
    
    if(this._thumbs.length > 0 && dojo.marginBox(this._thumbs[0]).w == 0){
      // Skip the resize if the widget is not visible
      return;
    }

    var sizeParam = this.isHorizontal ? "w": "h";
    var i, total = 0;
    for (i = 0; i < this._thumbs.length; i++) {
      dojo.addClass(this._thumbs[i], 'thumbnail');
    }
    
    dojo.forEach(this._thumbs, dojo.hitch(this, function(imgContainer){
      var size = imgContainer.offsetWidth + dojo.style(imgContainer, 'marginLeft') + dojo.style(imgContainer, 'marginRight');
      total += Number(size);
      
      var Dim = function(args) {
        var that = args;
        that.aspect = args.h / args.w;
        return that;
      }

      var containerDim = Dim({w: imgContainer.offsetWidth, h: imgContainer.offsetHeight });
      var img = imgContainer.firstChild;
      if (!img.resized) {
        var dim = Dim({w: img.offsetWidth, h: img.offsetHeight});
        if (dim.aspect < containerDim.aspect) {
          dojo.style(img, 'height', containerDim.h + 'px');
          dojo.style(img, 'marginLeft', ((containerDim.w - img.offsetWidth) / 2) + "px");
        }
        else {
          dojo.style(img, 'width', containerDim.w + 'px');
          dojo.style(img, 'marginTop', ((containerDim.h - img.offsetHeight) / 3) + "px");
        }
        img.resized = true;
      }
      
      /*
      if (imgHeight > containerHeight) {
        dojo.style(img, 'marginTop', ((containerHeight - imgHeight) / 2) + "px");
      }
      */

    }));
    dojo.style(this.thumbsNode, this._sizeProperty, total + "px");
    
    this._updateNavControls();
    dojo.addClass(this._thumbs[0], 'first');
  };
  
  thumbPickerProto.init = function() {
    // summary:
    //    Creates DOM nodes for thumbnail images and initializes their listeners
    if(this.isInitialized) {return false;}
  
    var classExt = this.isHorizontal ? "Horiz" : "Vert";
  
    // FIXME: can we setup a listener around the whole element and determine based on e.target?
    dojo.addClass(this.navPrev, "prev" + classExt);
    dojo.addClass(this.navNext, "next" + classExt);
    dojo.addClass(this.thumbsNode, "thumb"+classExt);
    dojo.addClass(this.outerNode, "thumb"+classExt);
    
    this.connect(this.navPrev, "onclick", "_prev");
    this.connect(this.navNext, "onclick", "_next");
    this.isInitialized = true;
    
    if(this.isHorizontal){
      this._offsetAttr = "offsetLeft";
      this._sizeAttr = "offsetWidth";
      this._scrollAttr = "scrollLeft";
    }else{
      this._offsetAttr = "offsetTop";
      this._sizeAttr = "offsetHeight";
      this._scrollAttr = "scrollTop";
    }
  
    this._updateNavControls();
    if(this.imageStore && this.request){this._loadNextPage();}
    return true;
  },


  thumbPickerProto._prev_BACKUP = function(){
    // summary:
    //    Displays the next page of images
    if(this.thumbScroller[this.isHorizontal ? "scrollLeft" : "scrollTop"] == 0){return;}
    var pos = this.isHorizontal ? "offsetLeft" : "offsetTop";
    var size = this.isHorizontal ? "offsetWidth" : "offsetHeight";
  
    var firstThumb = this._thumbs[this._thumbIndex];
    var origOffset = firstThumb[pos] - this.thumbsNode[pos];
  
    var index = -1, img;
    for(var i = this._thumbIndex - 1; i > -1; i--) {
      img = this._thumbs[i];
      console.log(i + ": " + img[pos]);
      if(firstThumb[pos] - img[pos] > this._scrollerSize){
        console.log(dojo.toJson({ft: firstThumb[pos], ip: img[pos], diff: firstThumb[pos] - img[pos], ss: this._scrollerSize}));
        this._showThumbs(i+1);
        return;
      }
    }
    this._showThumbs(0);
  };
  
  thumbPickerProto._showThumbs = function(index){
    
    // summary:
    //    Displays thumbnail images, starting at position 'index'
    // index: Number
    //    The index of the first thumbnail

//FIXME: When is this be called with an invalid index?  Do we need this check at all?
//    if(typeof index != "number"){ index = this._thumbIndex; }
    index = Math.min(Math.max(index, 0), this._maxPhotos);
    
    if(index >= this._maxPhotos){ return; }
    
    var img = this._thumbs[index];
    if(!img){ return; }
    
    var left = img.offsetLeft - this.thumbsNode.offsetLeft;
    var top = img.offsetTop - this.thumbsNode.offsetTop;
    var offset = this.isHorizontal ? left : top;

    /*
    if( (offset >= this.thumbScroller[this._scrollAttr]) &&
      (offset + img[this._sizeAttr] <= this.thumbScroller[this._scrollAttr] + this._scrollerSize)
    ){
      // FIXME: WTF is this checking for?
      return;
    }
    */
    
    
    if(this.isScrollable){
      var target = this.isHorizontal ? {x: left, y: 0} : { x:0, y:top};
      dojox.fx.smoothScroll({
        target: target,
        win: this.thumbScroller,
        duration:300,
        easing:dojo.fx.easing.easeOut,
        onEnd: dojo.hitch(this, "_checkLoad", img, index)
      }).play(10);
    }else{
      if(this.isHorizontal){
        this.thumbScroller.scrollLeft = left;
      }else{
        this.thumbScroller.scrollTop = top;
      }
      this._checkLoad(img, index);
    }
  };
  
  var slideShowPrototype = dojox.image.SlideShow.prototype;
  var oldPostCreate = slideShowPrototype.postCreate;
  
  slideShowPrototype.templateString = dojo.cache("uzh.image", "resources/SlideShow.html");
  slideShowPrototype.titleTemplate = '${title}';
  slideShowPrototype.currentPositionTemplate = '${current} / ${total}';
  
  slideShowPrototype._hideNav = function(evt) {};
  
  slideShowPrototype.postCreate = function(){
    oldPostCreate.apply(this, arguments);
    if (this.hasNav) {
      this._showNav(true);
    }
    removeStyleProperty(this.outerNode, "width");
  };
  
  slideShowPrototype._setTitle = function(title) {
    this.titleNode.innerHTML = dojo.string.substitute(this.titleTemplate,{
      title: title
    });
    this.currentPositionNode.innerHTML = dojo.string.substitute(this.currentPositionTemplate,{
      current: 1 + this.imageIndex,
      total: this.maxPhotos || ""
    });
  };

  slideShowPrototype._fitSize = function(fixed) {
   if(!this.fixedHeight||fixed){
      var height=(this._currentImage.height+(this.hasNav?20:0));
      dojo.style(this.innerWrapper,"min-height",height+"px");
      return;
    }
    dojo.style(this.largeNode,"paddingTop",this._getTopPadding()+"px");
  };
  
  var oldShowImage = slideShowPrototype.showImage;
  slideShowPrototype.showImage = function(index, /* Function? */callback) {
    oldShowImage.apply(this, arguments);
    window.location.hash = index + 1;
  };
  
  dojox.image.Gallery.prototype._centerChildren = function() {};
  
})();

