var FollowManager = {
  register: function(args) {
    var self = this;
    self.follower = jQuery(args.follower);
    self.c = jQuery(args.main);
    self.side = jQuery(args.side);
    self.header = jQuery(args.header);
    if( !self.follower.length || !self.c.length || !self.side.length ) {
        return;
    }
    self.additionalMargin = args.margin ? args.margin : 20;
    self.w = jQuery(window);
    self.isFloat = self.side.css('float');

    var find_relative = function(target) {
      if (!target) {
        return false;
      }
      var parent = target.parent();
      if (parent.length === 1) {
        try {
          if (parent.css('position') === 'relative') {
            return parent;
          } else {
            return find_relative(parent);
          }
        } catch (e) {
          //defaltViewがない場合
          return false;
        }
      } else {
        return false;
      }
    };
    
    self.relativeParent = find_relative(self.c);
    self.fix();
  },
  scroll: function() {
    var self = this;
    var follower = self.follower;
    var c = self.c;
    var w = self.w;
    var side = self.side;

    var side_left = side.offset().left;
    var w_scroll_top = w.scrollTop()
    var c_height = c.height();
    var c_top = c.offset().top;
    var c_bottom = c_top + c_height;
    var follower_height = follower.height();
    var side_height = side.height();

    var need_fixed_pos = side_height + c_top - self.additionalMargin;
    if (follower.position === 'static') {
      need_fixed_pos -= follower_height;
    }
    var follower_bottom = w_scroll_top + follower_height + self.additionalMargin;

    var need_fixed = (w_scroll_top > need_fixed_pos) && (c_height > side_height) ? true : false;
    var position = !need_fixed ? 'static' : follower_bottom > c_bottom ? 'absolute' : 'fixed';
    follower.position = position;

    if (position === 'fixed') {
      var bottom = w.height() - follower_height - self.additionalMargin;
      if (self.header.length && self.header.css('position') === 'fixed') {
        bottom -= self.header.outerHeight();
      }
      var left = c.width() - w.scrollLeft() + c.offset().left;
      if (self.isFloat === 'right') {
        left += side.offset().left - (c.offset().left + c.width());
      }
      follower.css({
        position: position,
        top: '',
        bottom: bottom,
        left: left
      });
    } else if (position === 'absolute') {
      var top = c_bottom - follower_height;
      var left = c.width() - w.scrollLeft() + c.offset().left;
      if (self.isFloat === 'right') {
        left += side.offset().left - (c.offset().left + c.width());
      }
      if (self.relativeParent !== false) {
        var offset = self.relativeParent.offset();
        top -= offset.top;
        left -= offset.left;
      }
      
      follower.css({
        position: position,
        top: top,
        bottom: '',
        left: left
      });
    } else {
      follower.css({ position: position });
    }
  },
  resize: function() {
    var self = this;
    var w = self.w;
    var side = self.side;
    var c = self.c;
    var follower = self.follower;
    var position = self.position;
  
    follower.css({position: 'static'});
    var side_left = side.offset().left;
    var w_left = w.scrollLeft();
    if (position === 'fixed') {
      follower.css({ position: position, top: '', left: side_left - w_left });
    } else if (position === 'absolute') {
      follower.css({ position: position, left: side_left - c.offset().left });
    } else {
      follower.css({ position: position });
    }
  },
  fix: function() {
    var self = this;
    var w = self.w;
    var scroll = function(){ self.scroll(); };
    var resize = function(){ self.resize(); };
    w.bind('scroll', scroll);
    w.bind('resize', resize);
  },
  getposition: function() {
	var self = this;
    var follower = self.follower;
	return follower.position;
  }
};