-function() { 

Slide = function(slides,template,o) { 
  if(!(this instanceof Slide)) return new Slide(slides,template,o);
  this.els = [];
  this.slides = slides; 

  this.init(template,o);

  return this;
}

Slide.prototype.init = function(template,o) { 
  this.get_elements();
  this.view = SlideView(template,o);
  this.active = this.view.active;
  this.enable(); //Set up various event handlers.
};

Slide.prototype.get_elements  = function() { 
  var self = this;
  this.slides.each(function(i,el) { 
    var clone = $(el).clone()
    clone.attr('style','');
    self.els.push(clone);
  });
  this.max = this.els.length -1; 
  this.index = 0;
};


Slide.prototype.show_first = function() { 
  this.index = 0;
  this.show(0);
};

Slide.prototype.show_img = function(i) { 
  this.index = i; 
  this.show(this.index);
};

Slide.prototype.prev = function() { 
  (this.index > 0) 
    ? this.index -= 1
    : this.index = this.max;

  this.show(this.index);
};

Slide.prototype.next = function() { 
  (this.index < this.max) 
    ? this.index += 1
    : this.index = 0;

  this.show(this.index);
};

Slide.prototype.show = function(index) { 
  this.view.push(this.els[index]);
};

Slide.prototype.enable = function() { 
  var self = this;

  this.view //Close Handler
      .find('.close a')
      .click(function(e) { 
        $.log('clickedy click');
        self.view.remove();
        return false;
  });

  this.view //Outer click handler
      .find('.bg')
      .click(function(e) { 
        self.view.remove(); 
        return false;
      });

  this.view //Prev  Handler
      .find('.prev')
      .click(function(e) {
        self.prev();
        return false;
  });

  this.view //Next Hnadler
      .find('.next')
      .click(function(e) {
        self.next();
        return false;
  });
};


SlideView = function(template,o) { 
  if(!(this instanceof SlideView)) return new SlideView(template,o);
  this.init(template,o);
  return this;
}

SlideView.prototype.init = function(template,o) { 
  this.settings(o);
  this.scaffold();
  this.template(template);
  this.layers();
  this.events();
};

SlideView.prototype.settings = function(o) { 
  this.o = { 
      top: 70
    , left: 0
    , min: 500
    , max: 900
    , wo: 160
    , ho: 160
    , show_guide: true
  };

  $.extend(this.o, o);

  this.win = $(window);
  this.win_dim();
}

SlideView.prototype.win_dim = function() { 
  this.ww  = this.win.width();
  this.wh  = this.win.height();
};

SlideView.prototype.scaffold = function() { 
  var scaffold = $('<div class="scaffold"><div class="sqr"><div class="targ"></div></div></div>');
  this.scaf = scaffold.appendTo('body');
  this.sqr = this.scaf.find('.sqr');
  this.targ = this.scaf.find('.targ');

  this.draw_scaf();
};

SlideView.prototype.template = function(t) { 
  $('body')
    .append(t.html());

  this.wrap = $('.slidewrap');
  this.bg   = this.wrap.find('bg');
  this.view = this.wrap.find('.view');
  this.prev = this.wrap.find('.prev');
  this.next = this.wrap.find('.next');
};

SlideView.prototype.layers = function() { 
  this.scaf.css('z-index',100);
  this.sqr.css('z-index',0);
  this.targ.css('z-index',10);

  this.wrap.css('z-index',500);
  this.bg.css('z-index',0);
  this.view.css('z-index',20);
  this.prev.css('z-index',20);
  this.next.css('z-index',20);
};

SlideView.prototype.events = function() { 
  var self = this;

  $(window).resize(function(e) {
    self.resize(); 
  });

};

SlideView.prototype.find = function(sel) { 
  return this.wrap.find(sel);
}

SlideView.prototype.box = function(o) {
  var box = { 
      w: o.width() 
    , h: o.height()
    , t: o.offset().top
    , r: o.offset().left + o.width()
    , b: o.offset().top + o.height()
    , l: o.offset().left 
    , ww: this.ww
    , wh: this.wh
  }

  box.w2 = box.w/2; 
  box.h2 = box.h/2;
  box.w4 = box.w/4;
  box.h4 = box.h/4;

  return box;
}

SlideView.prototype.css_ctr = function(obj, top, left, o) {
  var css = { 
      position: 'absolute'
    , top: '50%'
    , left: '50%'
    , 'margin-top': top 
    , 'margin-left': left
  };

  $.extend(css, o);

  obj.css(css);
};

SlideView.prototype.push = function(el) { 
  this.view.children().remove();
  this.view.append(el);  
  this.draw();
};

SlideView.prototype.remove = function() { 
  this.scaf.remove();
  this.wrap.remove();
}; 

SlideView.prototype.resize = function(e) { 
  this.win_dim();
  this.draw_scaf();
  this.draw();
};

SlideView.prototype.draw = function() { 
  this.draw_scaf();
  this.draw_item(); 
  this.draw_nav();
};

SlideView.prototype.draw_scaf = function() { 
  //scale & position scaffold parent
  this.scaf.css({ 
      position: 'fixed'
    , top: this.o.top
    , left: this.o.left 
    , width: this.ww
    , height: this.wh - this.o.top
  });

  if(this.o.show_guide)
    this.scaf.css({background: '#ff0000', opacity:0.4});
  //scale & position outer square 
  //nav buttons will be positioned realtive to this
  var size;

  (this.scaf.width() > this.scaf.height()) 
    ? size = this.scaf.height()
    : size = this.scaf.width(); 

  if(size > this.o.max || size < this.o.min) { 
    if(size > this.o.max) 
      size = this.o.max;
    else 
      size = this.o.min
  }

  this.sqr.width(size);
  this.sqr.height(size);

  var sbox = this.box(this.sqr); 
  this.css_ctr(this.sqr, 0, -sbox.w2, { top: 0 });

  if(this.o.show_guide)
    this.sqr.css({background: '#00ff00', opacity:0.4});

  //scale & position inner view target
  //viewable item will be positioned relative to this
  sbox = this.box(this.sqr);

  this.targ.width(sbox.w - this.o.wo);
  this.targ.height(sbox.h - this.o.ho);

  var tbox = this.box(this.targ); 
  this.css_ctr(this.targ,-tbox.h2, -tbox.w2); 

  if(this.o.show_guide)
    this.targ.css({background: '#0000ff', opacity:0.4});

};

SlideView.prototype.draw_item = function() { 
  this.item = this.view.children(); 
  this.img  = this.item.find('img'); 
  this.ifr  = this.item.find('iframe');

  if(this.img.length > 0) { 
    this.draw_img();
  } else if(this.ifr.length > 0) { 
    this.draw_iframe();
  } else { 
    this.draw_text();
  }

};

SlideView.prototype.draw_img = function() { 
  var view = this.view
    , img  = this.img
    , tbox = this.box(this.targ)
    , st   = this.win.scrollTop();

    
    if(img.width() > img.height()) { 
      if(img.width() > tbox.w) 
        img.width(tbox.w);
    } else { 
      if(img.height() > tbox.w)
        img.height(tbox.w);
    }

  view.width(img.width());
  view.height(img.height());

  view.css({
      position: 'absolute' 
    , top: (tbox.t - st) + tbox.h2
    , left: tbox.l + tbox.w2
    , 'margin-left': - (view.width() / 2)
    , 'margin-top': - (view.height() / 2)
  });

};

SlideView.prototype.draw_iframe = function() { 
  var view = this.view
    , ifr  = view.find('iframe')
    , tbox = this.box(this.targ)
    , st   = this.win.scrollTop();

  view.width(ifr.attr('width'));
  view.height(ifr.attr('height'));

  view.css({ 
      position: 'absolute' 
    , top: (tbox.t - st) + tbox.h2
    , left: tbox.l + tbox.w2
    , 'margin-left': - (view.width() / 2)
    , 'margin-top': - (view.height() / 2)
  });

};

SlideView.prototype.draw_text = function() { 
  var view = this.view
    , text = view.children()
    , tbox = this.box(this.targ) 
    , st   = this.win.scrollTop();

  view.width(tbox.w) 
  view.height(text.height());

  view.css({ 
      position: 'absolute'
    , top: (tbox.t - st) + tbox.h2
    , left: tbox.l + tbox.w2
    , 'margin-left': - (view.width() / 2)
    , 'margin-top': - (view.height() / 2)
  });

  view.find('.slideshow')
      .remove();

  (view.width() > this.o.min) 
    ? view.addClass('large_text')
    : view.addClass('small_text');

};

SlideView.prototype.draw_nav = function() { 
  var sbox = this.box(this.sqr)
    , prv  = this.prev
    , nxt  = this.next
    , no   = 0;

  (this.ww > this.hh) 
    ? no = 0
    : no = 20;

  prv.css({ 
      position: 'absolute'
    , top: (sbox.h2+this.o.top) - (prv.height()/2)
    , left: (sbox.l)+no
  });

  nxt.css({ 
      position: 'absolute'
    , top: (sbox.h2+this.o.top) - (nxt.height()/2)
    , left: (sbox.r - (prv.width() +no))
  });

};

}();

