// Client.js
var Client = Class.create(
  ChasteEnvironment, {
    'initialize': function ($super) {
      $super(false, true);
      var header = new Header('header');
      fire('client:initialized', {});
    }
  }
);

// Header.js
var Header = Class.create(
  VisualSlot, {
    'generic_login_error_message': '',
    'handle_sub_menu_click': function (event) {
      var a = event.target;
      var href = a.readAttribute('href');
      if (!href.endsWith('logout.html')) {
        event.stop();
      }
    },
    'handle_open_signup_panel': function (event) {
      event.stop();
      // @@ should only be called when not logged in!
      this.accordion.showThisHideOpen(0);
    },
    'handle_open_login_panel': function (event) {
      event.stop();
      this.open_login_panel();
    },
    'open_login_panel': function () {
      this.accordion.showThisHideOpen(1);
    },
    'handle_close_panel': function (event) {
      event.stop();
      this.accordion.showThisHideOpen(-1);
      this.handle_accordion_state_change({
          'memo': {
            'index': -1
          }
        }
      );
    },
    'handle_login_form': function (event) {
      event.stop();
      var lfe = this.dom.get('login-form-errors');
      lfe.hide();
      this.dom.get('login-form').request({
          'onSuccess': function () {
            // double check cookie support before reloading
            var double_check = new Ajax.Request('/@@login.ajax', {
                'onSuccess': function () {
                  window.location.reload(true);
                },
                'on401': function () {
                  lfe.update('You must have cookies enabled to login');
                  lfe.show();
                  event.findElement('div.section').fire('section:resized');
                }
              }
            );
          },
          'on401': function () {
            lfe.update(this.generic_login_error_message);
            lfe.show();
            event.findElement('div.section').fire('section:resized');
          }.bind(this)
        }
      );
    },
    'handle_show_forgot_password_form': function (event) {
      event.stop();
      this.dom.get('forgot-password-form-container').show();
      event.findElement('div.section').fire('section:resized');
    },
    'handle_accordion_state_change': function (event) {
      var index = event.memo.index;
      this.bars.each(
        function ($target, i) {
          if (index == i && !$target.hasClassName('selected')) {
            $target.addClassName('selected');
          }
          else if (index != i && $target.hasClassName('selected')) {
            $target.removeClassName('selected');
          }
        }
      );
    },
    'chastise': function ($super) {
      $super();
      // create accordion
      this.bars = this.target.select('a.bar');
      this.sections = this.target.select('div.section');
      this.accordion = new Accordion(
        this.bars, 
        this.sections.invoke('show'), {
          'start': 'none'
        }
      );
      this.target.observe('accordion:state:changed',
        this.handle_accordion_state_change.bindAsEventListener(this)
      );
      // cache all identified elements
      this.dom = new ElementCache(this.target);
      // catch sub menu clicks
      var handle_sub_menu_click = this.handle_sub_menu_click.bindAsEventListener(this);
      this.dom.get('header-sub-menu').select('a').invoke('observe', 'click', handle_sub_menu_click);
      // main forms
      var options = {
        'notify_section_resize': true,
        'highlighting_mode': 'border'
      };
      new NamedFormHandler('forgot-password', options);
      new NamedFormHandler('registration', options);
      new NamedFormHandler('contact', options);
      var handle_login_form_submit = this.handle_login_form.bindAsEventListener(this);
      // login-form
      var lf = this.dom.get('login-form');
      if (lf) {
        lf.observe('submit', handle_login_form_submit);
      }
      // login submit
      var ls = this.dom.get('login-form-submit');
      if (ls) {
        ls.observe('click', handle_login_form_submit);
      }
      // cache generic error message
      var lfe = $('login-form-errors');
      if (lfe) {
        this.generic_login_error_message = lfe.innerHTML;
      }
      // show forgot password form link
      var sfpl = this.dom.get('show-forgot-password-link');
      if (sfpl) {
        sfpl.observe('click', 
          this.handle_show_forgot_password_form.bindAsEventListener(this)
        );
      }
      // open signup form
      var sfaa = this.dom.get('signup-for-an-account-link');
      if (sfaa) {
        sfaa.observe('click',
          this.handle_open_signup_panel.bindAsEventListener(this)
        );
      }
      // open login form
      var ll = this.dom.get('login-link');
      if (ll) {
        ll.observe('click',
          this.handle_open_login_panel.bindAsEventListener(this)
        );
      }
      // close links
      this.dom.get('slideBox').select('a.closeLink').invoke(
        'observe', 
        'click',
        this.handle_close_panel.bindAsEventListener(this)
      );
      // finally a nasty js css hack fix for webkit
      if (Prototype.Browser.WebKit) {
        var hsm = $('header-sub-menu');
        if (hsm) {
          var username = hsm.select('.username').first();
          if (username) {
            username.setStyle({
                'background': 'none'
              }
            );
          }
        }
      }
    } 
  }
);

// init.js
observe('dom:loaded', 
  function () {
    var debug = false;
    if (window.location.href.indexOf(':8080') > -1) {
      debug = true;
    }
    Logger.addMethods({'DEBUG': debug});
    var client = new Client();
  }
);

// ListingsManager.js
var ListingsManager = Class.create({
    '_handle_hover_swapper_state_change': function (event) {
      new Ajax.Request('/record_hover_swap_state.ajax', {
          'parameters': event.memo
        }
      );
    },
    '_handle_batch_click': function (event) {
      event.stop();
      var target = event.findElement('a');
      if (target && target.readAttribute('href')) {
        var page = target.readAttribute('href');
        if (Prototype.Browser.IE) {
          page = page.sub(window.location.href, '');
        }
        var number = parseInt(page.sub('#page', ''));
        this.update_listings({'page': number});
      }
    },
    '_handle_search_submit': function (event) {
      event.stop();
      var keyword = $('search').getValue();
      var params = {};
      if (keyword) {
        params['search'] = keyword;
      }
      this.update_listings(params);
    },
    '_handle_filter_click': function (event) {
      event.stop();
      var a = event.findElement('a');
      var href = a.readAttribute('href');
      var params = {};
      if (href.indexOf('/categories') > -1) {
        var parts = href.split('/');
        params['category'] = unescape(parts.last());
      }
      else if (href.indexOf('/organisations') > -1) {
        var parts = href.split('/');
        params['organisation'] = unescape(parts.last());
      }
      this.update_listings(params);
    },
    'update_listings': function ($params) {
      new Ajax.Updater('video-on-demand-listings-container', 
        '/get_listings.xml', {
          'parameters': $params,
          'onComplete': function () { 
            var hs = new HoverSwapper('video-on-demand-listings', {});
            var lm = new ListingsManager('video-on-demand-listings', {});
          }
        }
      );
    },
    'initialize': function () { 
      var handle_filter_click = this._handle_filter_click.bindAsEventListener(this);
      $$('a.listings-filter-link').invoke('observe', 'click', handle_filter_click);
      $('searchForm').observe('submit', this._handle_search_submit.bindAsEventListener(this));
      var batch_links_container_id = 'navigation'; // counter intuitive!
      $(batch_links_container_id).observe('click', this._handle_batch_click.bindAsEventListener(this));
      // make the listing lil UIs in themselves ;)
      $$('.thumb-icon').each(
        function ($target) {
          var foo = new VideoListingSequenceViewer($target, {
              'increment_type': 'request_parameter'
            }
          );
        }
      );
      // event from the hoverswapper 
      observe('hover-swapper:state-changed', this._handle_hover_swapper_state_change.bindAsEventListener(this));
    }
  }
);

// Player.js
// Player.js
var Player = Class.create(
  VisualSlot, {
    'templates': {
      'info_window': new Template(
        '<div id="info-#{id}" class="descriptionText info-window">\
          <h5>\
            #{title}\
          </h5>\
          <p>\
            #{description}\
            <span class="time">\
              Duration: \
              #{duration}\
            </span>\
          </p>\
        </div>'
      ),
      'listing': new Template(
        '<a href="#{id}" class="point">\
          <div class="thumbnail">\
            <img src="/videos/#{id}/thumbnail.png" class="img-thumbnail" alt="#{title}" />\
          </div>\
          <span class="thumbTitle">\
            #{title}\
          </span>\
          <span>\
            #{duration}\
          </span>\
          <span class="clear">&#160;</span>\
        </a>'
      )
    },
    'stacked_video': '',
    'current_info_window': null,
    'index_of_the_listings_that_was_clicked_on': -1,
    '_supports_flash': function () {
      var v = deconcept.SWFObjectUtil.getPlayerVersion();
      if (v.major > 9 || (v.major == 9 && (v.minor > 0 || v.rev >= 97))) {
        return true;
      }
      return false;
    },
    '_embed_flash': function () {
      var img = this.target.down('img');
      var dims = img.getDimensions();
      var w = dims.width + 'px';
      var h = dims.height + 'px';
      // webkit fails to load the img sometimes
      if (w == '0px') {
        if (this.id == 'player') {
          w_ = '624';
        }
        else {
          w_ = '512'
        }
        var h_ = w_ / 16.0 * 9.0;
        w = w_ + 'px';
        h = h_ + 'px';
      }
      var so = new SWFObject('/++resource++ngo/swf/player.swf', 'flash', w, h, '9.0.97', '#000000');
      so.addParam('swliveconnect', 'true');
      so.addParam('allowScriptAccess', 'always');
      so.addParam('allowfullscreen', 'true');
      so.addParam('quality', 'autohigh');
      so.write(this.id);
    },
    '_add_new_listing_item': function (data) {
      // write a new hidden info div
      var new_info_window = this.templates.info_window.evaluate(data);
      $('info-windows').insert(new_info_window);
      $('info-' + data.id).hide();
      // write new video into schedule
      var new_listing = this.templates.listing.evaluate(data);
      $('scrollBox').insert(new_listing);
      /*
      var foo = new VideoListingSequenceViewer(
        $('scrollBox').select('.img-thumbnail').last(), {
          'increment_type': 'request_parameter'
        }
      );
      */
    },
    '_complete_applying_dyanmics': function (event) {
      event.stop();
      var target = event.findElement('a');
      target.stopObserving('mouseout');
      target.observe('mouseover', this.handle_listing_over);
      target.observe('mouseout', this.handle_listing_out);
    },
    '_apply_dynamics': function () {
      var listings = $('scrollBox').select('.point');
      listings.each(
        function ($target) {
          var this_index = $target.up().childElements().indexOf($target);
          if (this_index == this.index_of_the_listings_that_was_clicked_on) {
            $target.observe('mouseout', this._complete_applying_dyanmics.bindAsEventListener(this));
          }
          else {
            $target.observe('mouseover', this.handle_listing_over);
            $target.observe('mouseout', this.handle_listing_out);
          }
          $target.observe('click', this.handle_listing_click);
        }.bind(this)
      );
    },
    '_handle_listing_over': function (event) { 
      event.stop();
      var point = event.findElement('a');
      /*
      var target = event.element();
      log('over'); log(target);
      var thumbnail = point.select('.thumbnail').first();
      if (thumbnail) {
        if (thumbnail == target || thumbnail.descendants().include(target)) {
          log('ignoring');
          return;
        }
      }
      log('handling');
      */
      var id = point.readAttribute('href');
      if (Prototype.Browser.IE) {
        id = id.sub(window.location.href, '');
      }
      var target_info_window = $('info-' + id);
      // if this is a 'new' over 
      if (!target_info_window.visible()) {
        // hide the current info window
        this.current_info_window = $('info-windows').select('.current').first();
        this.current_info_window.hide();
        // show the target info window
        target_info_window.show();
      }
    },
    '_handle_listing_out': function (event) { 
      event.stop();
      var point = event.findElement('a');
      /*
      var target = event.element();
      log('out'); log(target);
      var thumbnail = point.select('.thumbnail').first();
      if (thumbnail) {
        if (thumbnail == target || thumbnail.descendants().include(target)) {
          log('ignoring');
          return;
        }
      }
      log('handling');
      */
      var id = point.readAttribute('href');
      if (Prototype.Browser.IE) {
        id = id.sub(window.location.href, '');
      }
      var target_info_window = $('info-' + id);
      if (target_info_window.visible()) {
        // hide the target info window
        target_info_window.hide();
        // show the current info window
        this.current_info_window = $('info-windows').select('.current').first();
        this.current_info_window.show();
      }
    },
    '_handle_listing_click': function (event) { /*
        
        1. trigger a request for data on each new video item
        required to re-populate the list, given that we're
        jumping ahead to this video
        
        
      */
      event.stop();
      var target = event.findElement('a');
      // a little tweak to capture the current pos in the list
      // referenced when applying dyanmics
      this.index_of_the_listings_that_was_clicked_on = target.up().childElements().indexOf(target);
      var video_id = target.readAttribute('href');
      if (Prototype.Browser.IE) {
        video_id = video_id.sub(window.location.href, '');
      }
      // work out how many videos to jump ahead
      var listings = $('scrollBox').childElements();
      var listings_to_skip = [];
      
      var i = 0;
      var n = listings.length;
      for (i; i < n; ++i) {
        var target_listing = listings[i];
        if (target_listing == target) {
          break;
        }
        listings_to_skip.push(target_listing);
      }
      
      new Ajax.Request(
        'get_next_videos.ajax', { /*
            
            3. once the request returns
            
          */
          'parameters': {
            'n': listings_to_skip.length + 1
          },
          'onSuccess': function (transport) { 
            var response = transport.responseText;
            var items = response.evalJSON(true); /* [{
                    "id": "v2", 
                  "title": "Video 2", 
                  "description": "lorum foo bar fkldk fl", 
                  "full_description": "lorum foo bar fkldk fl", 
                  "producer": "james", 
                  "duration": "00:00", 
                  "digest": "f03c2ac96ac9f9101024b712b02382d898a1472a"
                },
                ...
                
              ]
              
              
            */
            // for each of the new videos being appended to the listings
            items.each(this._add_new_listing_item.bind(this));
            this._apply_dynamics.bind(this).delay(1.5);
          }.bind(this)
        }
      ); /*
        
        2. whilst the request is being made
        
        
      */
      // delete redundant markup
      var current_info_window = $('info-windows').select('.current').first();
      current_info_window.remove();
      listings_to_skip.each(
        function ($target) {
          // read the id
          var id = $target.readAttribute('href');
          if (Prototype.Browser.IE) {
            id = id.sub(window.location.href, '');
          }
          // delete the corresponding info window
          $('info-' + id).remove();
          // delete the listing
          $target.stopObserving();
          $target.remove();
        }
      );
      // don't forget to remove the listing that's gonna now be playing
      target.stopObserving();
      target.remove();
      // park the mouseover mouseout for a sec
      var listings = $('scrollBox').select('.point');
      listings.invoke('stopObserving', 'mouseover');
      listings.invoke('stopObserving', 'mouseout');
      // use id to mark new info div as current
      var next_info_window = $('info-' + video_id);
      next_info_window.addClassName('current');
      next_info_window.show();
      // fire to play new id
      fire('play:video', {
          'video_id': video_id
        }
      );
    },
    'handle_play_video': function (event) {
      event.stop();
      var video_id = event.memo.video_id;
      var source = '/videos/' + video_id + '/content.flv';
      this.play(source);
    },
    'handle_playback_completed': function (event) { /*
        
        1. trigger a request for the next video data
        
        
      */
      event.stop();
      new Ajax.Request(
        'get_next_video.ajax', { /*
            
            3. once the request returns
            
          */
          'onSuccess': function (transport) { 
            var response = transport.responseText;
            var data = response.evalJSON(true); /* {
                "id": "v2", 
                "title": "Video 2", 
                "description": "lorum foo bar fkldk fl", 
                "full_description": "lorum foo bar fkldk fl", 
                "producer": "james", 
                "duration": "00:00", 
                "digest": "f03c2ac96ac9f9101024b712b02382d898a1472a"
              }
              
            */
            // write new hidden info div
            this._add_new_listing_item(data);
            var new_item = $('scrollBox').childElements().last();
            new_item.observe('mouseover', this.handle_listing_over);
            new_item.observe('mouseout', this.handle_listing_out);
            new_item.observe('click', this.handle_listing_click);
          }.bind(this)
        }
      ); /*
        
        2. whilst the request is being made
      
      
      */
      // delete currect info div
      var current_info_window = $('info-windows').select('.current').first();
      current_info_window.remove();
      // remove top video in schedule list
      // grabbing id on the way
      var top_listing = $('scrollBox').childElements().first();
      var next_video_id = top_listing.readAttribute('href');
      if (Prototype.Browser.IE) {
        next_video_id = next_video_id.sub(window.location.href, '');
      }
      top_listing.stopObserving();
      top_listing.remove();
      // use id to mark new info div as current
      var next_info_window = $('info-' + next_video_id);
      next_info_window.addClassName('current');
      next_info_window.show();
      // fire to play new id
      fire('play:video', {
          'video_id': next_video_id
        }
      );
    },
    'handle_flash_loaded': function () {
      this.flash = $('flash');
      if (this.stacked_video) {
        this.play(this.stacked_video);
      }
    },
    'play': function (source) {
      if (this.flash) {
        this.flash.play_new_video(source);
      }
      else {
        this.stacked_video = source;
      }
    },
    'chastise': function ($super) {
      $super();
      this.handle_listing_over = this._handle_listing_over.bindAsEventListener(this);
      this.handle_listing_out = this._handle_listing_out.bindAsEventListener(this);
      this.handle_listing_click = this._handle_listing_click.bindAsEventListener(this);
      if ($('info-windows')) {
        /*
        $('scrollBox').select('.img-thumbnail').each(
          function ($target) {
            var foo = new VideoListingSequenceViewer(
              $target, {
                'increment_type': 'request_parameter'
              }
            );
          }
        );
        */
        $('info-windows').rehide('.hide-to-begin-with');
        this._apply_dynamics();
      }
      observe('flash:loaded', this.handle_flash_loaded.bindAsEventListener(this));
      observe('play:video', this.handle_play_video.bindAsEventListener(this));
      if (this.id == 'player') { // only handle onPlaybackComplete if in now playing mode...
        observe('playback:completed', this.handle_playback_completed.bindAsEventListener(this));
      }
      if (this._supports_flash()) {
        this._embed_flash();
      }else{
        // we don't have the correct flash version
        var v = deconcept.SWFObjectUtil.getPlayerVersion();

        if (v.major > 0 ) {
          // flash is old change the message
          $("invalid_flash_title").update("Your flash player is out of date");
          $("invalid_flash_msg").update("Get the latest flash player here")
        }
      }
    }
  }
);

// VideoListingSequenceViewer.js
var VideoListingSequenceViewer = Class.create({
    'loading_started': false,
    'loading_completed': false,
    'cancel_build_and_render': false,
    'ui_visible': false,
    'default_source': '',
    'images_': new Array(),
    '__update_source': function ($url) { 
      this.target.src = $url;
    },
    '__reset_source': function () { 
      this.__update_source(this.default_source);
    },
    '__build_and_render_ui': function () { 
      // create and insert markup
      var dims = this.target.getDimensions();
      this.wrapper = this.target.wrap('div', {
          'id': this.id + '-wrapper',
          'class': 'sequence-thumbnail-wrapper',
          'style': 'display: block; \
                    width: ' + dims.width + 'px; \
                    height: ' + dims.height +  'px;'
        }
      );
      if (Prototype.Browser.IE) {
        this.target.wrap('a', {
            'href': this.target.up('a').readAttribute('href')
          }
        );
      }
      var cell_content = '';
      if (Prototype.Browser.WebKit) {
        cell_content = '&nbsp;';
      }
      this.wrapper.insert({
          'top': '\
            <div id="' + this.id + '-sequence-ui">\
              <table width="' + dims.width + 'px">\
                <thead>\
                </thead>\
                <tbody>\
                  <tr>\
                    <td index="0">' + cell_content + '</td>\
                    <td index="1">' + cell_content + '</td>\
                    <td index="2">' + cell_content + '</td>\
                    <td index="3">' + cell_content + '</td>\
                    <td index="4">' + cell_content + '</td>\
                    <td index="5">' + cell_content + '</td>\
                    <td index="6">' + cell_content + '</td>\
                    <td index="7">' + cell_content + '</td>\
                  </tr>\
                </tbody>\
              </table>\
            </div>\
          '
        }
      );
      this.sequence_ui = $(this.id + '-sequence-ui')
      this.sequence_ui.hide();
      var table = this.sequence_ui.select('table').first();
      var cells = this.sequence_ui.select('td');
      this.sequence_ui.setStyle({
          'marginTop': (dims.height - ((dims.height / 8) + 7)) + 'px',
          'position': 'absolute',
          'display': 'block',
          'zIndex': 2000
        }
      );
      table.setStyle({
          'border-collapse': 'collapse',
          'empty-cells': 'show',
          'zIndex': 2000
        }
      );
      this.target.setStyle({
          'zIndex': 1
        }
      );
      // this.target.stopObserving('mouseout', this.teardown);
      this.wrapper.observe('mouseout', this.teardown);
      this.alpha = 100;
      if (Prototype.Browser.WebKit) {
        this.alpha = 50;
      }
      cells.invoke('setStyle', {
          'backgroundImage': 'url(/++resource++ngo/img/grey_' + this.alpha + '_alpha.png)',
          'height': (dims.height / 8) + 'px',
          'marginTop': '-1px',
          'zIndex': 2000
        }
      );
      cells.invoke('observe', 'mouseover', this.handle_td_mouseover);
      cells.invoke('observe', 'mouseout', this.handle_td_mouseout);
    },
    '__show_ui': function () { 
      this.sequence_ui.show();
      this.ui_visible = true;
      observe('mouseout', this.teardown);
    },
    '__hide_ui': function () { 
      this.sequence_ui.hide();
      this.ui_visible = false;
      stopObserving('mouseout', this.teardown);
    },
    '__load_images': function () { 
      this.loading_started = true;
      this.images_.push(this.default_source);
      // the url structure for the images is determined by the $options
      var type = this.options['increment_type'];
      var i = 1, n = 8, images = [];
      for (i; i < n; ++i) {
        if (type == 'request_parameter') {
          url = this.default_source + '?i=' + i;
        }
        else if (type == 'index') {
          var ext = this.options['extension'];
          url = this.default_source.split('.' + ext).first() + i + '.' + ext;
        }
        else {
          warn('unsupported increment type: ' + type);
        }
        images.push(url);
        this.images_.push(url);
      }
      var preloader = new ImagePreloader(this.id, images, true);
    },
    '_handle_td_mouseover': function (event) { 
      event.stop();
      var target = event.findElement('td');
      target.setStyle({
          'backgroundImage': 'url(/++resource++ngo/img/orange_' + this.alpha + '_alpha.png)'
        }
      );
      var index = target.readAttribute('index');
      log(index);
      var i = parseInt(index);
      this.__update_source(this.images_[i]);
    },
    '_handle_td_mouseout': function (event) {
      event.stop();
      var target = event.findElement('td');
      target.setStyle({
          'backgroundImage': 'url(/++resource++ngo/img/grey_' + this.alpha + '_alpha.png)'
        }
      );
    },
    '_handle_images_loaded': function (event) { 
      this.loading_completed = true;
      this.__build_and_render_ui();
      if (!this.cancel_build_and_render) {
        this.__show_ui();
      }
      else {
        log('build_and_render was cancelled');
      }
    },
    '_setup': function () { 
      if (this.loading_completed) { 
        this.__show_ui();
      }
      else if (this.loading_started) { 
        this.cancel_build_and_render = false;
      }
      else {
        this.__load_images();
      }
    },
    '_teardown': function (event) { 
      event.stop();
      if (this.ui_visible) { 
        var trigger = event.element();
        var descendants = this.wrapper.descendants();
        if (!descendants.include(trigger)) {
          // the mouseover was triggered by an element outside of
          // out lil sequence so we know to teardown proper
          this.__hide_ui();
          this.__reset_source();
        } 
      }
      else { 
        this.cancel_build_and_render = true;
      }
    },
    'initialize': function ($target, $options) { log('@@')
      this.target = $target;
      this.options = $options;
      this.id = $target.identify();
      this.images_ = new Array();
      this.default_source = $target.readAttribute('src');
      this.handle_images_loaded = this._handle_images_loaded.bindAsEventListener(this);
      this.handle_td_mouseover = this._handle_td_mouseover.bindAsEventListener(this);
      this.handle_td_mouseout = this._handle_td_mouseout.bindAsEventListener(this);
      this.teardown = this._teardown.bindAsEventListener(this);
      this.target.observe('mouseover', this._setup.bindAsEventListener(this));
      this.target.observe('mouseout', this.teardown);
      observe(this.id + ':preloading:completed', this.handle_images_loaded);
    }
  }
);

