function SpellingCity(){
  var self = this;
  self.init();
}
SpellingCity.prototype = {

  isBusy: false,

  init: function()
  {
    var self = this;

    self._bindLoginEvents();
    self._bindImportListEvents();

    // bind action dropdowns if available
    $( '.actions' ).change(
      function()
      {
        if( this.value == 'ajax' ) {
            var id_selected = $(this).find("option:selected").attr("id");
            $("."+id_selected).click();
            return false;
        }

        if( this.value != '' ) window.open( this.value , "mywindow");
      }
    );
    // show onload modals / support chained onload modals
    // any modal created with an id will be displayed first
    $( '#onload-show-modal, .onload-show-modal' ).livequery(
      function()
      {
        var $this = $(this);
        var href = $this.attr('href');
        $this.fancybox({
          centerOnScroll : true,
          hideOnOverlayClick:false,
          onStart: function()
          {
            $( href ).show();
          },
          onClosed: function()
          {
            $( href ).remove();
            // if we started with a class based modal we don't want to show it again
            if( $this.hasClass('onload-show-modal') ){
              $('.onload-show-modal').eq(0).remove();
            }
            if( $('.onload-show-modal').eq(0).length > 0 ){
              var t = setTimeout("$('.onload-show-modal').eq(0).click()",100);
            };
          },
          type: ($(this).attr('t')!='undefined') ? $(this).attr('t') : 'inline'
        }).click();
      }
    );
    // bind custom close buttons for fancyboxes
    $("#modal-msg .close-btn, .modal-msg .close-btn, .fancy-close").livequery( 'click',
      function()
      {
        $.fancybox.close();
      }
    );
    // bind links that should open with fancybox
    var $fancyboxes  = $('.fancybox').not('.fancybox[href*="fancyframe.php');

    var $fancyframes = $('.fancybox[href*="fancyframe.php"]');

    $fancyboxes.fancybox();

    $fancyframes.fancybox({
      'width'  : 490,
      'height' : 430,
      'type'   : 'iframe'
    });

    $(".fancybox-sc-game").live('click', function() {
      var $el  = $(this);
      var href = $el.attr('href');

      var href = href ? href.split('?')[1] : '';
      var qs   = new Querystring(href);

      game_x = qs.params.game_x ? qs.params.game_x : null;
      game_y = qs.params.game_y ? qs.params.game_y : null;

      if (game_x && game_y) {
        $el.fancybox({
          'href'   : $el.attr('href'),
          'width'  : parseInt(game_x),
          'height' : parseInt(game_y),
          'type'   : 'iframe'
        }).trigger('click');
      }
      return false;
    });
    // bind elements with tooltips
    //tooltip();

    $('.listtable-static a.import-all').click(
      function()
      {
        $('.listtable-static a.import').click();
        return false;
      }
    );

    $('.pm-check').each(
      function()
      {
        // game_access is a json global that defines the user's access to pm games
        // it may or may not be present
        if( typeof game_access != 'undefined' ){
          var $el = $(this);
          var activity = $el.attr('activity');
          $(game_access).each(
            function()
            {
              if( this.id == activity && !this.pass ){
                $el.removeClass('pm-check').addClass('pm-block');
              }
            }
          );
        }
      }
    )

    // element with the pm-block class are meant to display an alert when clicked informing the user that the activity is accessible only to PM's
    // the #show-pm-upsell element is assumed to be loaded in the markup
    $(".pm-block").click(
      function( e )
      {
        var $html = $( $('#pm-upsell-src').html() ).clone();
        $('#pm-upsell').html( $html );
        var activity = $(this).attr('activity');
        if( typeof game_access != 'undefined' ){
          var redirect_to = '';
          $(game_access).each(
      function()
      {
              if( this.id == activity ){
                redirect_to = this.sample_url;
                return false;
              }
            }
          );
          if( redirect_to && redirect_to != '' ){
            $('#pm-upsell').append( '<p class="redirect-to">Click <a href="'+redirect_to+'">here</a> to try out this activity with one of our lists!</p>' );
          }
        }
        $("#show-pm-upsell").click();
        e.stopImmediatePropagation();
        return false;
      }
    );

    $(".pm-block-feature").click(
        function( e ) {
          var $html = $( $('#pm-upsell-feature-src').html() ).clone();
          $('#pm-upsell-feature').html( $html );
          $("#show-pm-upsell-feature").click();
          e.stopImmediatePropagation();
          return false;
        }
      );
    // elements with a min-block class require the user to have more words in their list to continue.
    $(".min-block").click(
      function()
      {
        var $this = $(this);
        var min_words = 0;
        $( $this.attr("class").split(" ") ).each(
          function()
          {
            if( this.match(/\min-/) ) min_words = this.split("-")[1];
          }
        );
        if( min_words>0 && ! $this.hasClass("pm-block") ) alert("This game requires at least "+min_words+" word" + ( min_words>1?"s":"") + " to play.");
        return false;
      }
    );


    // handle ads
    try{
      var excludeon = [ 'dev.spellingcity.com', 'beta.spellingcity.com' ];
      if( excludeon.indexOf( window.location.hostname ) < 0 ){
        self.showAds();
      } else {
        $('.place-ads').css({height:'auto',margin:0,padding:0});
      }
    } catch(err){
    }

    self._bindEdmodoEvents();

  },

  _bindLoginEvents: function() {
    var self = this;
    $(document).on('loginRequired.SpellingCity', function(e, message) {

      var promise = $.ajax({
        url: '/index.php?option=com_spellcity&controller=users&task=loginUserAjaxForm&format=raw',
        data: {
          message: message || ''
        }
      });

      promise.done(function(content) {

        $.fancybox({
          'content' : content,
          'autoDimensions': true
        });

        $('#user_name').focus();

        $('#login-user').on('click', function(e) {

          e.preventDefault();

          var $form = $(this).parents('form');

          $form.find('#login-errors').html('');

          var username = $form.find('#user_name').val();
          var password = $form.find('#password').val();

          var login = $.ajax({
            url : 'index.php?option=com_spellcity&controller=users&task=loginUserAjax',
            type: 'POST',
            dataType: 'json',
            data: {
              username: username,
              password: password,
              format: 'json'
            }
          });

          login.done(function(data) {

            if (data.success) {
              location.reload(true);
              return false;
            }

            if (data.errors) {
              $form.find('#login-errors').html(data.errors.join('<br />'));
            }
          });

          login.fail(function() {
            alert('Sorry! There was a problem communicating with the server. Please try again');
          });

        });
      });

      promise.fail(function() {
        alert('There was a problem loading the login form. Please try again in a few moments')
      });

    });
  },

  _bindImportListEvents: function() {
    var self = this;
    $('.import').on('click', function() {

      if( !self.isBusy ){
          var $el   = $(this);
          $el.css({'textDecoration':'none'});
          var $par  = $el.parent();
          var $tr   = $el.parents('tr');
          if( $tr.hasClass('group') ){
            var preloader = '<span style="padding:0 31px;text-align:center;text-decoration:none;"><img src="/images/ajaxpreloader-bed4f1.gif" /></span>';
          } else {
            var preloader = '<span style="padding:0 12px;text-align:center;text-decoration:none;"><img src="/images/ajaxpreloader-fffeab.gif" /></span>';
          }
          var chtml = $el.html();
          $el.html( preloader );

          $.ajax({
            type: "POST",
            url: this.href,
            success: function( result ) {

              if( $.trim(result) == 'OK' ){
                $el.replaceWith('<span class="imported">Imported</span>');
              } else {

                if (result.match('logged')) {
                  $(document).trigger('loginRequired.SpellingCity', [result]);
                } else {
                  alert(result);
                }

                $el.html( chtml );
                $el.css({'textDecoration':'underline'});
              }

              self.isBusy = false;
            }
          });
        }
        isBusy = true;
        return false;
      }
    );
  },

  _bindEdmodoEvents: function() {
    //deal with logout links, framebreaking on edmodo
    if (!window.FROM_EDMODO) {
      //break out of iframes
      if( top.location !== location ){
        top.location.href = document.location.href;
      }
    } else {

      $(document).ready(function() {

        //edmodo logout code
        $('#logout-link').on('click', 'a', function() {

          if (window.top !== window.self) {

            var logout_url = $(this).attr('href');

            $.get(logout_url, function() {

              //edmodo logout code (if in a frame)
              if (window.top !== window.self) {
                //this url should be changed to edmodo once we deploy this
                window.location = parent.window.location = 'http://vocabularyspellingci.edmodobox.com/';
              }
            });

            return false;
          }
        });
      });

    }
  },

  showAds: function()
  {
    $('.place-ads').each(
      function()
      {
        var html = '';
        if( $(this).hasClass('homepage-bottom-left') ){
          html += '<iframe src="http://www.brightsrv.com/spellingcity.com/rectangle.php?path=index.htm" width="310" height="260" scrolling="no" style="border:none;margin:0 0 0 -4px;" frameborder="0"></iframe>';
        } else {
          html +=  '<iframe class="iframe-ad" src ="/index.php?option=com_spellcity&task=fillAdSlot&slot='+$(this).attr('rel')+'" style=""/>';
        }
        html += '<a class="bad-banner" href="/index.php?option=com_content&view=article&id=1255">Advertisement (Bad banner? Please let us know)</a>';
        $(this).html( html );
      }
    );
  }
}



var sc;
$().ready(
  function()
  {
    sc = new SpellingCity();
  }
);


//---------------------------------------------------------------------
// IE6/7 doesn't have an Array.indexOf property so add it if it doesn't exist.
//---------------------------------------------------------------------
if( !Array.prototype.indexOf ){
  Array.prototype.indexOf = function( obj, from )
  {
    from = ( from == null ) ? 0 : Math.max( 0, this.length + from );
    for( var i = from, j = this.length; i < j; i++ ) if (this[i] === obj) return i;
    return -1;
  };
}

(function($) {
  $.isiOS = function() {
    if (navigator.userAgent.match(/iPad|iPhone|iPod/)) {
      return true;
    } else {
      return false;
    }
  };

  $.iOSVersion = function() {
    var re     = /\((iPad|iPhone|iPod);.+ ([0-9_]+) like/i;
    var raw   = navigator.userAgent.match(re);

    if (raw) {
      var device = raw[1];
      var os     = raw[2].replace(/_/g, '.');

      if (device && os) {
        return [device, os];
      } else {
        return false;
      }

    } else {
      return false;
    }
  };

  $.iOSLatest = function() {
    var re = /(4\.3)/i;
    var version = $.iOSVersion()[1];

    if (version && version.match(re))  {
      return true;
    } else {
      return false;
    }
  };

  $.unsupportediOS = function() {
    var ios_version = $.iOSVersion();
    if (ios_version && ios_version[1][0] != 'undefined' && ios_version[1][0] < 4) {
      return true;
    } else {
      return false;
    }
  };

  $.upgradeiOSAlert = function() {

    if ($.unsupportediOS()) {

      var content =
            '<div class="ios-alert" style="width: 400px; text-align: center;">'
          + '<h2> Out-of-date Apple iOS detected! </h2>'
          + '<a href="http://www.apple.com/ios/" target="_blank"><img width="214" height="252" src="/images/ios.jpg" style="margin: 0 auto;" /></a>'
          + '<p style="font-size:13px">To use this activity on Apple Devices (iPad, iPhone, iPod touch), you need to upgrade your iOS device operating system to the latest version. </p>'
          + '<p style="font-size:12px">Upgrading is quick, easy and free. </p>'
          + '<p style="font-size:12px">Please visit <a href="http://www.apple.com/ios/" target="_blank">http://www.apple.com/ios/</a> for more information</p>';
          + '</div>';


      return $('<div class="fancybox">')
            .css({'width' : '400px', 'height' : '420px'})
            .html(content)
            .appendTo('#main')
            .fancybox( {
              onClosed: function() {
                $('.fancybox, div[id^=fancybox-]').remove();
              }
            })
            .trigger('click')
            .unbind('click');
    }
  };

})(jQuery);

//---------------------------------------------------------------------
// add a highlight method to jquery for the filter stuff
//---------------------------------------------------------------------
jQuery.fn.extend({
  highlight: function( search, insensitive, hclass ){
    //var regex = new RegExp("(<[^>]*>)|(\\b"+ search.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1") +")", insensitive ? "ig" : "g"); // the word boundary flag (\\b) is messing with our middle-of the-word-awesome-highlighting mojo
    var regex = new RegExp("(<[^>]*>)|("+ search.replace(/([-.*+?^${}()|[\]\/\\])/ig,"\\$1") +")", insensitive ? "ig" : "g");
    return this.html( this.html().replace(regex,
      function( a, b, c )
      {
        return ( a.charAt(0) == "<" ) ? a : "<strong class=\""+ hclass +"\">" + c + "</strong>";
      }
    ));
  }
});

//---------------------------------------------------------------------
// client-side access to querystring name=value pairs
// based on Adam Vandenberg Querystring class v1.2.3
//---------------------------------------------------------------------
function Querystring(qs) {
  this.params = new Object();
  this.get=Querystring_get;
  if (qs == null) qs=location.search.substring(1,location.search.length);
  if (qs.length == 0) return;
  qs = qs.replace(/\+/g, ' ');
  var args = qs.split('&');
  for( var i=0;i<args.length;i++ ){
    var value;
    var pair = args[i].split('=');
    var name = unescape(pair[0]);
    value = (pair.length == 2) ? unescape(pair[1]) : name;
    this.params[name] = value
  }
}

function Querystring_get(key, default_) {
  if( default_ == null ) default_ = null;  // This silly looking line changes UNDEFINED to NULL
  var value=this.params[key]
  if( value==null ) value=default_;
  return value
}

//------------------------------------------------------------------------
// Log in detect for Time Zones
function getOffest()
{
    var d=(new Date().getTimezoneOffset()/60)*(-1);
    offset = '<input type="hidden" name="offset" value="'+d+'" />';
    return offset;
}

//------------------------------------------------------------------------
// Password Show
function passwordShowHide()
{
    if ( $("#showPassword").is(':checked') ) {
        $('#passwordHide').show();
        $('#passwordShow').hide();
    } else {
        $('#passwordShow').show();
        $('#passwordHide').hide();

    }
}

//------------------------------------------------------------------------
// Password Show
function passwordShare(source)
{
    if ( source == 'password' ) {
        value = $('#mod_login_password_hide').val();
        $('#mod_login_password_show').val(value);
        $('#passwordValue').val(value);
    } else {
        value = $('#mod_login_password_show').val();
        $('#mod_login_password_hide').val(value);
        $('#passwordValue').val(value);
    }
}

function login(type)
{
    if ( type == 'teacher' ) {
        student_user = $('#mod_login_username_s').val();
        student_pass = $('#passwordValue').val();
        $('#mod_login_username').val(student_user);
        $('#mod_login_password').val(student_pass);
        $('#teacherLogin').show();
        $('#studentLogin').hide();
    } else {
        teacher_user = $('#mod_login_username').val();
        teacher_pass = $('#mod_login_password').val();
        $('#mod_login_username_s').val(teacher_user);
        $('#mod_login_password_show').val(teacher_pass);
        $('#mod_login_password_hide').val(teacher_pass);
        $('#passwordValue').val(teacher_pass);
        $('#studentLogin').show();
        $('#teacherLogin').hide();
    }
}

//------------------------------------------------------------------------
// Limit Chars used in edit list and definitions and anywhere definsions and sentences are entered or edited
function limitChars(textid, infodiv, limit)
{
    var text = $('#'+textid).val();
    var textlength = text.length;
    if(textlength > limit)
    {
        $('#' + infodiv).html('You cannot write more than '+limit+' characters!');
        $('#'+textid).val(text.substr(0,limit));

        return false;

    } else {

        if ((textlength < 45) && (textlength > 0))
        {
            $('#' + textid).css("border", "1px solid #00C000");
            $('#' + infodiv).html('Best : '+ (limit - textlength) +' characters left.');
        } else {
            $('#' + textid).css("border", "1px solid #FF0000");
            $('#' + infodiv).html('Long : '+ (limit - textlength) +' characters left.');
        }

        return true;
    }
}

(function($) {
  $.preg_quote = function(str, delimiter) {
      return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
  };
})(jQuery);

