var STH_FlowManager = {
  shareChecked: false,
  
  init: function() {
    var self = this;
    
    $('body').append('<div id="fb-root"></div>');
    FB.init({appId: superglue.settings.api_keys.facebook, cookie: false, status: false, xfbml: false});
    FB.getLoginStatus(function(response){
      if (response.session) {
        STH_UserManager.isLoggedIntoFacebook = true;
      }
      else {
        STH_UserManager.isLoggedIntoFacebook = false;
      }
    });
    
    if (STH_UserManager.isUserRegistered()) {
      $('#counter').hide();
    }
    else {
      $('header nav').hide();
    }
    
    $('#main > .content').css({top: $('#main').height() + 'px'}).hide();
    $('#avatars').data('origHeight', '350px').css({height: 0});   //this should be dynamic: $('#avatars').css('height'), but jquery is experiencing a race condition for some reason
    STH_LoadingIndicator.init();
    STH_CounterManager.init();
    if (STH_UserManager.isUserRegistered()) {
      $('#join').remove();
      $('body').addClass('noflash');
      STH_FlowManager.showNextSteps();
    }
    else {
      STH_BackgroundManager.init({
        onSuccess: function() {
          if (STH_UserManager.isUserRegistered()) {
            self.shareChecked = false;
            self.completeShare(); //force start progress thru the flow
          }
          else {
            self.showIntro();
          }
        },
        onFail: function() {
          if (STH_UserManager.isUserRegistered()) {
            self.shareChecked = false;
            self.completeShare(); //force start progress thru the flow
          }
          else {
            self.showJoinDialog();
          }
        },
        onIntroComplete: self.showJoinDialog
      });
    }
  },
  
  showIntro: function() {
    STH_BackgroundManager.player.play(STH_BackgroundManager.clips.intro);
  },
  
  showJoinDialog: function() {
    $('#options').prepend('<input type="checkbox" name="share" id="share-checkbox" class="checkbox" checked="checked" /><label for="share-checkbox">share with my friends</label>');
    $('#join .social-buttons').show();
    $('#main > .content').show().animate({top: 0}, 500, 'swing', function(){
      STH_TwitterManager.init();
      STH_FacebookManager.init();
      STH_EmailManager.init();
      STH_AvatarListManager.init();
    });
    $('#join-no-thanks').click(function() {
      STH_FlowManager.completeAvatar();
      return false;
    });
  },
  
  completeJoin: function() {
    $('#join>div').fadeOut(500, this.showAvatarDialog);
  },
  
  showAvatarDialog: function() {
    $.get(superglue.settings.base + '/avatar', {service: STH_UserManager.user.service, flash: !$('body').hasClass('noflash')}, function(data) {
      $('#join>div:first').html(innerShiv(data));
      STH_AvatarSelectionManager.init();
      $('#join>div:first').fadeIn(500, function(){
        STH_AvatarSelectionManager.init();
      });
    });
  },
  
  completeAvatar: function() {
    $('#main > .content').animate({top: $('#main').height() + 'px'}, 500, function(){
      if (STH_FlowManager.shareChecked) {
        STH_FlowManager.showShareDialog();
      }
      else {
        STH_FlowManager.completeShare();
      }
      //$(this).hide();
    });
  },
  
  showShareDialog: function() {
    STH_ShareManager.init();
  },
  
  completeShare: function() {
    if ($('#avatars').length > 0 && $('#avatars').is(':visible')) {
      $('#avatars').fadeOut(500, function() {
        $('#avatars').remove();
        STH_FlowManager.showNextSteps();
      });
    }
    else {   //backup plan, in case twitter hangs up jquery cycle
      $('#avatars').remove();
      STH_FlowManager.showNextSteps();
    }
    $('#join').remove();
  },
  
  showNextSteps: function() {
    STH_LoadingIndicator.show();
    STH_BackgroundManager.allowOnStart = true;
    if ($('body').hasClass('noflash')) {
      STH_BackgroundManager.setBackground('next-steps-page');
      STH_FlowManager.showNextStepsDialog();
    }
    else {
      STH_BackgroundManager.player.play(STH_BackgroundManager.clips.nextSteps);
    }
  },
  
  showNextStepsDialog: function() {
    STH_LoadingIndicator.hide();
    $('#counter').fadeOut(1000, function(){
      $('header nav li ul').hide();
      $('header nav').fadeIn(1000);
      $('header nav li:has(ul)').hoverIntent({
        timeout: 400,
        over: function(){
          $(this).find('ul:first').slideDown(200);
        },
        out: function(){
          $(this).find('ul:first').slideUp(200);
        }
      }).toggle(
        function(){
          $(this).find('ul:first').slideDown(200);
        },
        function(){
          $(this).find('ul:first').slideUp(200);
        }
      );
    });
    $('header nav li a').click(function(e){
      e.stopPropagation();
    });
    $.get(superglue.settings.base + '/nextsteps', function(data) {
      $('#main > .content').html(innerShiv(data)).show().animate({top: 0}, 500);
    });
  }
};

var STH_BackgroundManager = {
  player: null,
  allowOnStart: false,  //needed because flowplayer bug
  clips: {
    intro: {
      name: 'intro',
      url: superglue.settings.videos.intro
    },
    nextSteps: {
      name: 'nextSteps',
      url: superglue.settings.videos.next_steps
    }
  },
  
  init: function(params) {
    var self = this;
    var p = params;  //closure
    STH_BackgroundManager.setBackground('start-page');
    $('#main').prepend('<div id="player"></div>');
    $('#player').flowplayer({
      src: superglue.settings.base + '/assets/swfs/flowplayer-3.2.5.swf',
      allowfullscreen: 'false',
      wmode: 'transparent',
      onFail: function() {
        this.player = null;
        $('body').addClass('noflash');
        STH_BackgroundManager.setBackground('intro-page');
        STH_LoadingIndicator.hide();
        $('#player').remove();
        p.onFail();
      }
    },
    {
      canvas: {
         backgroundGradient: 'none'
      },
      clip: {
        autoPlay: false,
        autoBuffer: true,
        accelerated: true,
        // can't add events to individual clips because of bug in flowplayer
        onCuepoint: [[1000, 4000, 7000], function(clipRef, cuepoint){
          if (clipRef.name !== 'intro') {
            switch (cuepoint) {
              case 1000:
                //you would think this works, but no, you can't rely on flowplayer to actually fire cuepoints appropriately, so leave this commented out
                //STH_BackgroundManager.setBackground('next-steps-page');
                break;
            }
            return;
          }
          switch (cuepoint) {
            case 1000:
              //you would think this works, but no, you can't rely on flowplayer to actually fire cuepoints appropriately, so leave this commented out
              //STH_BackgroundManager.setBackground('intro-page');
              $('#caption').html('<h2>' + superglue.settings.captions[0] + '</h2>');
              $('#caption').fadeIn(400);
              break;
            case 4000:
              $('#caption').fadeOut(400, function() {
                $('#caption').html('<h2>' + superglue.settings.captions[1] + '</h2>');
                $('#caption').fadeIn(400);
              });
              break;
            case 7000:
              $('#caption').fadeOut(400, function(){
                $(this).remove();
              });
              break;
          }
        }],
        onStart: function(clipRef) {
          $('#main').prepend('<div id="caption"></div>');
          STH_LoadingIndicator.hide();
          if (clipRef.name == 'intro') {
            // should be able to set a cuepoint, but flowplayer sucks, hence this redonk workaround
            setTimeout(function(){
              STH_BackgroundManager.setBackground('intro-page');
            }, 1000);
          }
          else if (clipRef.name == 'nextSteps' && STH_BackgroundManager.allowOnStart) {
            STH_BackgroundManager.player.show();
            setTimeout(function(){
              STH_BackgroundManager.setBackground('next-steps-page');
            }, 1000);
          }
        },
        onFinish: function(clipRef) {
          if (clipRef.name == 'intro') {
            if ($('#caption').length > 0) {   //special case, if the last cuepoint doesn't fire for some reason
              $('#caption').fadeOut(400, function(){
                $(this).remove();
              });
            }
            STH_BackgroundManager.player.setClip(STH_BackgroundManager.clips.nextSteps).startBuffering();
            STH_FlowManager.showJoinDialog();
          }
          else {
            STH_FlowManager.showNextStepsDialog();
          }
          STH_BackgroundManager.player.hide();
        }
      },
      plugins: {
        controls: null,
        play: null,
        disableClick: {
          url: superglue.settings.base + '/assets/swfs/flowplayer.content-3.2.0.swf',
          top: 0,
          left: 0,
          width: '100%',
          height: '100%',
          borderRadius: 0,
          opacity: 0,
          border: 'none',
          onClick: function() {
              return false;
          }
        }
      },
      play: null,
      onLoad: function(){
        self.player = $f('player');
        p.onSuccess();
      },
      onBeforePause: function () { return false; },
      onBegin: function () { this.getPlugin('play').hide(); }
    });
  },
  setBackground: function(className) {
    $('#main').addClass(className);
    $('#main').removeClass('intro-page start-page next-steps-page'.replace(className, ''));
  }
};

var STH_AvatarListManager = {
  avatarPage: 0,
  getAvatars: true,
  avatarsPerSlide: null,
  
  init: function() {
    var self = this;
    var maxAvatarsX = Math.floor($('#avatars .avatar-grid').width() / superglue.settings.avatars.width);
    maxAvatarsX = maxAvatarsX - Math.ceil(superglue.settings.avatars.width / (4 * maxAvatarsX)); //account for padding

    var maxAvatarsY = Math.floor($('#avatars .avatar-grid').height() / superglue.settings.avatars.height);
    maxAvatarsY = maxAvatarsY - Math.ceil(superglue.settings.avatars.height / (4 * maxAvatarsY)); //account for padding

    this.avatarsPerSlide = maxAvatarsX * maxAvatarsY;

    var slide = this.getNextAvatarSlide(this.avatarsPerSlide);
    if (slide) {
      $('#avatars .avatar-grid').append(slide);
      slide = this.getNextAvatarSlide(this.avatarsPerSlide); //call again to fully populate for cycle
    }
    $('#avatars').height($('#avatars').data('origHeight'));
    if (slide) {
      $('#avatars .avatar-grid').append(slide);
      $('#avatars .avatar-grid').cycle({
        fx: 'scrollUp',
        cleartypeNoBg: true,
        timeout: superglue.settings.avatars.rotate_timeout,
        before: function(curr, next, opts){
          if (!opts.addSlide) {
            return;
          }
          var slide = STH_AvatarListManager.getNextAvatarSlide(STH_AvatarListManager.avatarsPerSlide);
          if (slide) {
            opts.addSlide(slide);
          }
        }
      });
    }
  },
  getNextAvatarSlide: function(avatarsPerSlide) {
    if (this.getAvatars) {
      var xhr = $.ajax({
        url: superglue.settings.base + '/api/user/avatars',
        async: false,
        data: {limit: this.avatarsPerSlide, page: this.avatarPage},
        dataType: 'json'
      });
      if (xhr.responseText !== '') {
        var response;
        try {
          response = $.parseJSON(xhr.responseText);
        }
        catch (err)
        {
          return false;
        }
        if (response.success === true)
        {
          var slide = '';
          var i = 0;
          for (i = 0; i < response.data.users.length; i++) {
            var avatar = '<img src="' + response.data.users[i].avatar + '" alt="" width="25" height="25" />';
            if (response.data.users[i].url){
              avatar = '<a href="' + response.data.users[i].url + '" title="' + response.data.users[i].name + '">' + avatar + '</a>';
            }
            else {
              avatar = '<span>' + avatar + '</span>';
            }
            slide += avatar;
          }
          this.avatarPage = response.data.nextPage;
          if (response.data.nextPage == 0) {
            this.getAvatars = false;
          }
          return '<div class="slide clearfix">' + slide + '</div>';
        }
        else
        {
          this.getAvatars = false;
        }
      }
    }
    
    return false;
  }
};

var STH_UserManager = {
  user: new STH_User(),
  isLoggedIntoFacebook: false,
  
  isUserRegistered: function() {
    if ($.cookie('STH_uid')) {
      return true;
    }
    
    return false;
  },
  
  register: function(data) {
    this.saveUser({
      data: data, 
      action: 'create',
      onSuccess: function() {
        STH_FlowManager.shareChecked = $('#share-checkbox').is(':checked');
        STH_FlowManager.completeJoin();
      },
      onFail: function() {
        STH_FlowManager.shareChecked = false;
        STH_FlowManager.completeAvatar();  //pushes thru flow so that join dialog is hidden
      }
    });
  },
  
  saveUser: function(params) {
    STH_LoadingIndicator.show();
    var p = params;
    var actions = {
      create: superglue.settings.base + '/api/user/add',
      update: superglue.settings.base + '/api/user/update?uid=' + $.cookie('STH_uid')
    };
    $.extend(this.user, p.data);
    var userPostObject = {};
    for (prop in this.user) {
      if (this.user[prop] !== undefined) {  //leave null in for nulling out values
        userPostObject[prop] = this.user[prop];
      }
    }
    $.post(actions[p.action], userPostObject, function(response){
      STH_LoadingIndicator.hide();
      if (response.success === true) {
        $.cookie('STH_uid', response.data.uid.toString(), {expires: new Date(2037, 0, 1), path: superglue.settings.base});
        p.onSuccess();
      }
      else {
        p.onFail();
      }
    }, 'json');
  }
};

var STH_FacebookManager = {
  init: function() {
    var self = this;
    $('body').append('<div id="fb-root"></div>');
    $('#facebook').click(function(){
      if (STH_UserManager.isLoggedIntoFacebook) {
        FB.api('/me', self.onAuthSuccess);
      }
      else {
        FB.login(function(response) {
          if (response.session) {
            FB.api('/me', self.onAuthSuccess);
          }
        });
      }
    });
  },
  
  onAuthSuccess: function(data) {
    STH_UserManager.register({
      name: data.first_name + ' ' + data.last_name,
      url: data.link,
      service: 'facebook',
      avatar: 'http://graph.facebook.com/' + data.id + '/picture',
      facebook_id: data.id
    });
  },
  
  share: function() {
    FB.ui({
      method: 'stream.publish',
      attachment: superglue.settings.facebook_share_settings
    }, STH_FlowManager.completeShare);
  }
};

var STH_TwitterManager = {
  twitterObject: null,
  
  init: function() {
    var self = this;
    twttr.anywhere(function (T) {
      self.twitterObject = T;
      $('#twitter').click(function() {
        STH_TwitterManager.twitterObject.signIn();
      });
      self.twitterObject.bind('authComplete', self.onAuthSuccess);
    });
  },
  
  onAuthSuccess: function (e, data) {
    STH_UserManager.register({
      name: data.name,
      url: 'http://www.twitter.com/' + data.screenName,
      service: 'twitter',
      avatar: data.profileImageUrl,
      twitter_id: data.id
    });
  },
  
  share: function() {
    var self = this;
    $.colorbox({
      innerWidth: 420,
      innerHeight: 180,
      html: '<div id="tweetbox"></div>',
      onClosed: STH_FlowManager.completeShare
    }, function(){
      self.twitterObject("#tweetbox").tweetBox({
        width: 400,
        height: 100,
        defaultContent: superglue.settings.twitter_share_message,
        onTweet: function(){
          $.colorbox.close();
        }
      });
    });
  }
};

var STH_EmailManager = {
  init: function() {
    $('#email .button').click(function(){
      if (STH_Utils.validateEmailField($('#email .text:first'))) {
        STH_UserManager.register({
          service: 'email',
          avatar: null,
          email: $('#email .text').val()
        });
      }
      
      return false;
    });
  },
  
  share: function() {
    $.colorbox({
      href: superglue.settings.base + '/email',
      onComplete: function() {
        $('#colorbox input[placeholder], #colorbox textarea[placeholder]').placeholder();
        $('#email-dialog input[type=submit]').click(function() {
          if (STH_Utils.validateEmailField($('#email-dialog #email-recipient'))) {
            $.post(superglue.settings.base + '/api/email/send?uid=' + $.cookie('STH_uid'), {recipient: $('#email-dialog #email-recipient').val(), message: $('#email-dialog #email-message').val()},
              function(response) {
                $.colorbox.close();
              },
              'json'
            );
          }
          
          return false;
        });
      },
      onClosed: STH_FlowManager.completeShare
    });
  }
};

var STH_CounterManager = {
  init: function() {
    setTimeout(STH_CounterManager.updateCount, superglue.settings.update_count_timeout);
  },
  updateCount: function() {
    $.getJSON(superglue.settings.base + '/api/user/count', function(result) {
      if (result.success === false)
      {
        if ($('.count:first').filter(':empty').length > 0)
        {
          $('.count').hide().parent('#counter').hide();
        }
      }
      else
      {
        $('.count').html(STH_Utils.addCommas(result.count.toString()));
        setTimeout(STH_CounterManager.updateCount, superglue.settings.update_count_timeout);
      }
    });
  }
};

var STH_ShareManager = {
  init: function() {
    switch (STH_UserManager.user.service) {
      case 'facebook':
        STH_FacebookManager.share();
      break;
      case 'twitter':
        STH_TwitterManager.share();
      break;
      case 'email':
        STH_EmailManager.share();
      break;
    }
  }
};

var STH_Utils = {
  validateEmailField: function(field) {
    var valid = false;
    if (field.attr('placeholder') && field.val() !== field.attr('placeholder')) {
      var pattern = /[a-z0-9!#$%&'*+\/=?\^_`{|}~\-]+(?:\.[a-z0-9!#$%&'*+\/=?\^_`{|}~\-]+)*@(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?/i;
      valid = pattern.test(field.val());
    }
    if (!valid) {
      this.createFormError('invalid email address', field);
    }
    
    return valid;
  },
  
  createFormError: function(text, field) {
    var offset = field.position();
    var errorElement = document.createElement('span');
    var error = $(errorElement).html(text).addClass('form-error').appendTo(field.parent()).css({
      top: Math.ceil(offset.top) + ((field.outerHeight() - $(errorElement).outerHeight()) / 2),
      left: Math.ceil(offset.left) + field.outerWidth() - $(errorElement).outerWidth() - ((field.outerHeight() - $(errorElement).outerHeight()) / 2),
      display: 'none'
    }).fadeIn(500).bind('click', function(){
      $($(this).data('field')).focus();
    }).data('field', field[0]);
    field.data('errorElement', error);
    field.bind('change focus', function(){
      $($(this).data('errorElement')).fadeOut(500, function(){
        $(this).remove();
      });
    });
  },
  
  addCommas: function(nStr) {    //http://www.mredkj.com/javascript/nfbasic.html
    nStr += '';
    var x = nStr.split('.');
    var x1 = x[0];
    var x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
      x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
  }
};

var STH_AvatarSelectionManager = {
  init: function(){
    var self = this;
    $('#use-social-avatar').click(self.onAvatarSocial);
    var uploader = new qq.FileUploaderBasic({
      button: $('#use-uploaded-avatar').parents('.fileuploader-wrapper')[0],
      action: superglue.settings.base + '/api/image/upload?uid=' + $.cookie('STH_uid'),
      onSubmit: function() {
        STH_LoadingIndicator.show();
      },
      onComplete: self.onAvatarUploaded
    });
    $('#use-new-avatar').click(function() {
      $.colorbox({
        initialWidth: 338,
        initialHeight: 600,
        href: superglue.settings.base + '/camera?callback=STH_AvatarSelectionManager.onAvatarCreated&uid=' + $.cookie('STH_uid'),
        onComplete: function(){
          try {
            if ($.browser.mozilla) {
              $(window).resize(function(){
                $('#colorbox').css({
                  left: parseInt($('#colorbox').offset().left) + 'px',
                  top: parseInt($('#colorbox').offset().top) + 'px',
                });
              }).resize();
            }
          } catch(ex){}
        }
      });
      
      return false;
    });
    $('#use-no-avatar').click(STH_AvatarSelectionManager.onAvatarNone);
  },
  
  onAvatarSocial: function(){
    // passthru because social is automatically selected
    STH_FlowManager.completeAvatar();
    return false;
  },
  onAvatarUploaded: function(id, fileName, response) {
    STH_LoadingIndicator.hide();
    if (response.success === true) {
      STH_AvatarSelectionManager.updateUserAvatar(response.url);
    }
    else {
      $.colorbox({
        html: '<h1>Uh oh...</h1><p>It looks like your upload has failed. Make sure you are uploading a jpg, png, or gif and try again.</p>'
      });
    }
  },
  onAvatarCreated: function(response) {
    $.colorbox.close();
    if (response.success === true) {
      STH_AvatarSelectionManager.updateUserAvatar(response.url);
    }
    else {
      STH_FlowManager.completeAvatar();
    }
  },
  onAvatarNone: function() {
    if (STH_UserManager.user.service !== 'email') {
      STH_AvatarSelectionManager.updateUserAvatar(null);
    }
    else {
      STH_FlowManager.completeAvatar();
    }
    return false;
  },
  updateUserAvatar: function(url) {
    STH_UserManager.saveUser({
      data: {
        avatar: url
      },
      action: 'update',
      onSuccess: STH_FlowManager.completeAvatar,
      onFail: STH_FlowManager.completeAvatar
    });
  }
};

var STH_LoadingIndicator = {
  init: function() {
    $('<div id="loading-indicator">loading...</div>').appendTo('#main');
  },
  show: function() {
    $('#loading-indicator').show();
  },
  hide: function() {
    $('#loading-indicator').hide();
  }
};

function STH_User() {
  this.name = undefined;
  this.url = undefined;
  this.service = undefined;
  this.avatar = undefined;
  this.email = undefined;
}


$(document).ready(function() {
  $('body').removeClass('nojs').addClass('js');
  $('input[placeholder], textarea[placeholder]').placeholder();
  STH_FlowManager.init();
});

