$(function(){
  var Toggler = function(opts){
    var obj = this;
    var defaults = {};
    defaults.selector = ".toggle";
    defaults.showText = "Show";
    defaults.hideText = "Hide";
    defaults.useImage = false;
    defaults.imagePosition = "left";
    defaults.updateTriggerNodeValue = false;
    defaults.transShow = function(el, time, callback){
      el.slideDown(obj.opts.effectTime, callback);
    };
    defaults.transHide = function(el, time, callback){
        el.slideUp(obj.opts.effectTime, callback); 
        
    };  
    defaults.scrollfx = function(el, status){
      if(status != 'none'){
        var offsetTop = el.offset().top - ($(window).width() / 8);
        if(offsetTop < 0) offsetTop = 0;
        $('html,body').animate({scrollTop: offsetTop}, obj.opts.scrollSpeed);              
      }
    }
    defaults.imageShown = "";
    defaults.imageHidden = "";
    defaults.hideByDefault = true;
    defaults.effectTime = 600;
    defaults.scrollToDestination = false;
    defaults.scrollSpeed = 850;
    
    obj.opts = $.extend({}, defaults, opts);
    
    // toggleize .toggle divs and stuff
    $(obj.opts.selector).each(function(index, trigger){
      var trigger = $(trigger);         // the trigger
      var dest_id = trigger.attr('rel');// the destination id
      
      if(typeof dest_id != 'string') return true;
      
      var dest    = $('#' + dest_id) // the destination    
      
      if(dest.length == 0) return;
      
      // sets visibility to none by default
      if(obj.opts.hideByDefault){
        dest.hide();      
      }
      
      // converts trigger tags into link if the are not so by default
      if(trigger.get(0).tagName != 'A'){
        var new_trigger = $(document.createElement('A'));
        new_trigger.html(trigger.html());
        trigger.html("");
        trigger.removeAttr('rel');
        trigger.append(new_trigger);
        
        var trigger = new_trigger;
      }
      trigger.attr('href', 'javascript:void(0)');
      trigger.attr('rel', dest_id);
      trigger.attr('title', (obj.opts.hideByDefault? obj.opts.showText: obj.opts.hideText));
      if(obj.opts.updateTriggerNodeValue && trigger.find("span").length > 0){
        trigger.find("span").text((obj.opts.hideByDefault? obj.opts.showText: obj.opts.hideText))
      }
      
      // creates a flexible trigger indicator
      if(obj.opts.useImage == true){
        var trigger_i = $(document.createElement('img'));
        trigger_i.attr('src', obj.opts.imageHidden);
        trigger_i.attr('border', 0);
        
        if(obj.opts.imagePosition == "left"){
          trigger.prepend(trigger_i);          
        }else{
          trigger.append(trigger_i);
        } 
      }
      
      // sets callback
      trigger.click(function(e){
        var trigger   = $(this);
        var trigger_i = trigger.children('img');
        var dest      = $('#' + trigger.attr('rel'));
        
        var status_prev = dest.css('display'); 
        var status_next = status_prev == 'none'? '': 'none';      
        
        var callback = function(){
          // updates trigger and indicator too
          trigger.attr('title', status_next == 'none'? obj.opts.showText: obj.opts.hideText);
          if(obj.opts.updateTriggerNodeValue && trigger.find("span").length > 0){
            trigger.find("span").text((status_next == 'none'? obj.opts.showText: obj.opts.hideText))
          }        
          if(obj.opts.useImage == true){
            trigger_i.attr('src', status_next == 'none'? obj.opts.imageHidden: obj.opts.imageShown);
          }      

          if(obj.opts.scrollToDestination == true){
            obj.opts.scrollfx(dest, status_next);
          }          
        };
        
        status_next != 'none'? obj.opts.transShow(dest, obj.opts.effectTime, callback): obj.opts.transHide(dest, obj.opts.effectTime, callback);
        
        e.stopPropagation();
        e.preventDefault();
        return false;        
      });
      
    });
  };
  
  // extends jquery
  $.extend({
    toggler: function(opts){
      var toggler = new Toggler(opts);
    }
  });  
});
