// viewer is the complete player window
var viewer = function() {
var lesson, articleid, screencam, webcam, articlePath, additionalFiles, ajaxurl, isLesson = false,
selectedNode, fullscreen, nobrowse, loginurl, timer, embed, lessonframeid, win, tabs, share,
east, browser, browsereast, tabitems, tree = null, browsemetapanel, playbutton, pathids,
// video files - secondary is undefined if there is only one
primaryVideo, secondaryVideo,
twoPlayers = false, loggedin=false;


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Utility functions
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Browser independent client area function
function docSize() {
  var width, height;
  
  if(Ext.isIE) {// The usual suspect...
     width = document.documentElement.clientWidth;
     height = document.documentElement.clientHeight;
  
     if(width === 0) {
       width = document.body.clientWidth;
       height = document.body.clientHeight;
     }
  } else { // ...and everybody else
     width = window.innerWidth;
     height = window.innerHeight;
  }
  return { width: width, height: height };
}

function getQueryVariable(variable) { 
  var query = window.location.search.substring(1), 
       vars = query.split("&"); 
  for(var i = 0, end = vars.length; i < end; i++) { 
     var pair = vars[i].split("="); 
     if(pair[0] === variable) {
       return pair[1]; 
     }
  }
} 

//Select all element text (and copy to clipboard on IE)
function copyTag(elem) {
elem.select();
  if(window.clipboardData) {
    window.clipboardData.setData('text', elem.value);
  }
}

//Delete non-numeric characters from the text input field
function filterNumeric(field) {
  field.value = field.value.replace(/[^\d]/g, "");
}

function resize() {
  var size = docSize();
  win.setSize(size.width - 8, size.height - 8); 
}

function enableTabs() {
  var items = tabs.items.items;
  for(var i = 0, end = items.length; i < end; i++) {
    if(items[i].needsLesson) {
      items[i].setDisabled(!isLesson);
    }
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Additional resources
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Display a resource file in a new window
function showResource(index) {
  var options="toolbar,status,menubar,scrollbars,resizable,location,height=600,width=800";
  window.open(additionalFiles[index].url, 'newWin', options);
  return false;
}

// Generate resource form html
function createResourceHtml() {
  var html = '<div><ul class="resources">';
  for(var i = 0, end = additionalFiles.length; i < end; i++) {
    var file = additionalFiles[i];
    var size = file.size ? " " + file.size : "";
    html += '<li onclick="viewer.showResource(\'' + i + '\');" title="' + file.title + '">\n' + 
      '<img src="' + file.icon + '" alt="' + file.alt + '" />' +
      '<span>' + file.link + size + '</span><div class="filler">&nbsp;</div></li>';
  }
  return html + '</ul></div>';
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Lesson browser
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// The user has clicked on a tree node
// enable the play button for leaf nodes and update the metadata
function nodeClick(node, event) {
  nodeSelect(node);
}

// Set play button state and update metadata for the node
function nodeSelect(node) {
  enableTabs();
  showMetadata(node);
  playbutton.setDisabled(!node.leaf);
  
  selectedNode = node;
}

// Ensure that metadata is displayed for the node that we opened on
// As of Ext 2.2.1 tree load events are not fired for leaf nodes (ho hum!)
function showNode(node) {
  var lessonnode = node.findChild("id", articleid);
  if(lessonnode) {
    nodeSelect(lessonnode);
    lessonnode.select();
  }
}

// Create metadata form
function showPlayerMetadata(response) {
  var metadata = Ext.util.JSON.decode(response.responseText),
      metapanel = new Ext.FormPanel({
    frame:true,
    bodyStyle:'padding:5px 5px 0',
    width: 350,
    defaults: {width: 230, readOnly: true},
    defaultType: 'textfield',

    items :[{
      fieldLabel: 'Title',
      value: metadata.text
    },{
      xtype: 'textarea',
      fieldLabel: 'Description',
      value: metadata.description
    },{
      fieldLabel: 'Author',
      value: metadata.author
    },{
      fieldLabel: 'Copyright',
        value: metadata.copyright 
    },{
      fieldLabel: 'Rating',
      value: metadata.rating
    },{
      fieldLabel: 'Created',
      value: metadata.created
    },{
      fieldLabel: 'ID',
      value: metadata.id 
    }]
  });
  
  var about = tabs.getItem('about');
  about.add(metapanel);
}

//Update metadata for current selection
function showMetadata(node)
{
  var form = browsemetapanel.getForm();
  form.findField('btitle').setValue(node.attributes.heading || "");
  form.findField('bdescription').setValue(node.attributes.description || "");
  form.findField('bauthor').setValue(node.attributes.author || "");
  form.findField('bcopyright').setValue(node.attributes.copyright || "");
  form.findField('brating').setValue(node.attributes.rating || "");
  form.findField('bcreated').setValue(node.attributes.created || "");
  form.findField('btype').setValue(node.attributes.nodetype || "");
  form.findField('bid').setValue(node.id || "");
}

// Show the parent node, node, and as many of its children as possible
function showChildren(node) {
  if(node.hasChildNodes()) {
    node.lastChild.ensureVisible();
  }
  node.ensureVisible();
}

// Extract the metadata template from the page
function getMetadataTemplate() 
{
  var template = document.getElementById('metadata-master').innerHTML;
  document.getElementById('metadata-master').innerHTML = "";
  return template;
}

// Replace the id parameter of the iframe src url with the selected node id
function gotoSelected() {
  window.location.href = window.location.href.replace(/([&?])(id=[0-9]+)/, '$1id=' + selectedNode.id);
}

function nodeDblClick(node, event) {
  if(node.leaf) {
    selectedNode = node;
    gotoSelected();
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create the document tree panel
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function createTree() {
  var docRoot, docTree;
  // Extract the root node id
  rootid = articlePath.split('/')[1];
      
  // set the root node
  docRoot = new Ext.tree.AsyncTreeNode({
    text: 'root', 
  id: rootid 
  });
      
  docTree = new Ext.tree.TreePanel({
    animate:true, 
    autoScroll:true,
    containerScroll: true,
    loader: new Ext.tree.TreeLoader({
      url: ajaxurl,
      requestMethod: 'GET',
      baseParams: { articleaction: 'ajax', method: 'getchildren' }
    }),
    root: docRoot,
    rootVisible: false
  });
    
  // render the tree
  docRoot.expand(false, false);
  docTree.on('click', nodeClick);
  docTree.on('dblclick', nodeDblClick);
  docTree.on('expandnode', showChildren);
  docTree.on('load', function(node){ docTree.expandPath(articlePath); showNode(node); }); 
  
  return docTree;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create the player window and its internal Ext components
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function createPlayer(createSecondary) {
  var showWest, sec, additional, west;
  showWest = (additionalFiles.length !== 0 || twoPlayers);
  
  sec = new Ext.Panel ({
    region: 'north',
    html: '<div id="player2" style="width:100%; height:100%"></div>',
    width: 200,
    height: 250,
    split: false,
    margins:'3 0 3 3',
    cmargins:'3 3 3 3'
  });

  // Panel for the centre 
  additional = new Ext.Panel ({
    title: 'Resources',
    region: 'center',
    autoScroll: true,
    html: createResourceHtml()
  });

  // Panel for the west
  if(showWest) {
    west = new Ext.Panel ({
      layout: 'border',
      region: 'west',
      width: 200,
      collapsible: false,
      margins:'3 0 3 3',
      cmargins:'3 3 3 3',
      floatable  : false,
      split: true,
      items: createSecondary ? [sec, additional] : [additional]
    });
  }
  
  // Panel for the main video
  east = new Ext.Panel ({
    layout: 'fit',
    region: 'center',
    collapsible: false,
    margins:'3 0 3 3',
    cmargins:'3 3 3 3',
    floatable  : false,
    html: '<div id="player1" style="width:100%; height:100%"></div>' 
  });

  share = shareform.create(lesson, url, articleid); 
  
  // Browser tree (left-hand browser panel)
  browser = new Ext.Panel ({
    layout: 'fit',
    region: 'center'
  });

  playbutton = new Ext.Button({
    cls:'x-btn-text-icon',
    scale: 'large',
    height: 40,
    width: 100,
    text: '&nbsp;&nbsp;Play&nbsp;&nbsp;',
    iconAlign: 'left',
    icon: 'template/lessonframe/images/play.png',
    disabled: !isLesson,
    listeners: { 
      click: function() { 
        gotoSelected();
      } 
    }
  });
  
  browsemetapanel = new Ext.FormPanel({
    region: 'center',
    frame:true,
    bodyStyle:'padding:5px 5px 0',
    defaults: {width: 230, readOnly: true},
    defaultType: 'textfield',

    items :[{
      fieldLabel: 'Title',
      id: 'btitle'
    },{
      xtype: 'textarea',
      fieldLabel: 'Description',
      id: 'bdescription'
    },{
      fieldLabel: 'Author',
      id: 'bauthor'
    },{
      fieldLabel: 'Copyright',
      id: 'bcopyright'
    },{
      fieldLabel: 'Rating',
      id: 'brating'
    },{
      fieldLabel: 'Created',
      id: 'bcreated'
    },{
      fieldLabel: 'Type',
      id: 'btype'
    },{      
      fieldLabel: 'ID',
      id: 'bid'
    }]
  });
  // Right-hand browser panel
  browsereast = new Ext.Panel ({
    region: 'east',
    split: true, 
    layout: 'border',
    width: 370,
    items: [
      browsemetapanel, {
      xtype: 'toolbar',
      region: 'south',
      height: 45,
      items: playbutton
    }]
  });


  header = new Ext.Panel ({
    region: 'north',
    frame: 'true',
    height: 30,
    autowidth: true,
    items: {
      xtype: 'panel',
      region: 'center',
      html: '<div class="header">' +
              '<div class="left">' +
                '<b>Our Player' + (isLesson ? '  -  Playing: [' + articleid + '] ' + lesson : '') + '</b>' +
              '</div>' + 
              '<div class="right">' +
                ( embed && loggedin ? '<span width="32px" class="float-right">' +
                '<img src="template/lessonframe/images/logout.png" alt="logout" ' +
                'onclick="viewer.logout();" title="Logout" />' +
                '</span>' : '') + 
                ( fullscreen ? '' : '<span width="32px" class="float-right">' +
                '<img src="template/lessonframe/images/fullscreen.png" alt="fullscreen" ' +
                'onclick="viewer.openFullscreen();" title="Open fullscreen" />' +
              '</span>') + 
              '</div>' +
            '</div>'
    } 
  });
  
  tabitems = [{ 
    title: 'Browse',
    id: 'browse',
    needsLesson: false,
    layout: 'border', 
    items: [browser, browsereast],
    listeners: { 
      activate: function() { 
        if(tree === null) {
          tree = createTree();
          browser.add(tree);
        } 
      }
    }
  },{
    title: 'Video',
    id: 'video',
    disabled: !isLesson,
    layout: 'border',
    items: showWest ? [ west, east ] : east
  },{
    title: 'Now Playing',
    disabled: !isLesson,
    id: 'about',
    layout: 'fit'
  },{
    title: 'Sharing',
    disabled: !isLesson,
    layout: 'fit', 
    html:' <div id="sharediv" style="width:100%; height:100%"></div>', 
    listeners: { 
      activate: function() { 
        if(!share.rendered) {
          share.render('sharediv');
        } 
      }
    } 
  },{ 
    title: 'Our Lesson', 
    needsLesson: false,
    html: '<iframe src="http://www.ourlesson.co.uk/advert"' + 
          ' width="100%" height="100%" scrolling="no" style="border:none;"></iframe>' 
  }];
  
  if(nobrowse) {
    tabitems.shift(); 
  }
  
  // tabs for the centre
  tabs = new Ext.TabPanel ({
    region: 'center',
    margins: '3 3 3 0', 
    activeTab: (isLesson || nobrowse) ? 'video' : 'browse',
    items: tabitems
  });

  win = new Ext.Viewport ({
    plain: true,
    layout: 'border',
    items: [header, tabs]
  }); 

  // Create about tab
  Ext.Ajax.request({
    success: showPlayerMetadata,
    url: ajaxurl,
    requestMethod: 'GET',
    params: {
      articleaction: 'ajax',
      method: 'getmetadata', 
      node: articleid
    }
  });
  return win; 
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Open the player
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function showPlayer() {
  if(isLesson) {
    if(screencam) {
    primaryVideo = screencam;
    secondaryVideo = webcam;
    } else {
    primaryVideo = webcam;
    secondaryVideo = null;
    }
  }
  twoPlayers = !!secondaryVideo;

  win = createPlayer(twoPlayers);
  
  if(isLesson) {
    players.setGoogleAnalyticsTracker(window.pageTracker, articleid, lesson);  
    players.load(primaryVideo, secondaryVideo);
    // Setup event tracking

  }
  // if the player is closed then unload the flowplayer instance(s) and remove the 
  // window.onbeforeunload event which will throw if executed with the players already unloaded
  win.on('beforeclose', function () {
    $f("*").each(function() { 
      if(this.isLoaded()) {
        this.unload(); } 
    });
    window.onbeforeunload = function(){};
    return true;
  });

  win.show();
  resize();
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Login & Logout
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function openIDPopupWindow(openid) { 
  var popup = window.open(loginurl + (loginurl.indexOf('?') === -1 ? '?' : '&') + 
		      'articleaction=openid_popup&openid_url='+encodeURIComponent(openid), 'openid_popup', 'width=450,height=500,location=1,status=1,resizable=yes,scrollbars=yes');

  var coords = getCenteredCoords(450,500);
  popup.moveTo(coords[0],coords[1]);
}

function doLogin() {
  var urlparts = window.location.href.split('?');
  var params = '?articleaction=extlogin&returnarticleid=' + lessonframeid;
  if(urlparts.length === 2) {
    params = params + '&' + urlparts[1];
  }
  window.location.href = loginurl + params;
}

function reload() {
	window.location.reload();
}

function logout()
{
	Ext.Ajax.request({
		url: loginurl,
		method: 'GET',
		params: { articleaction: 'logout' },
		success: reload,
		failure: reload
	});
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Initialisation
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Read lesson data ajax response
function getLessonData(response) {
  var lessondata = Ext.util.JSON.decode(response.responseText);
  if(embed && lessondata.fail && lessondata.fail == 'security') {
    doLogin();
  } else {
    url = lessondata.url;
    lesson = lessondata.title;
    isLesson = lessondata.islesson;
    articlePath = lessondata.articlepath;
    screencam = lessondata.screencam;
    webcam = lessondata.webcam;
    additionalFiles = lessondata.additional_files;
    showPlayer();
  }
}

function requestLessonData(response) {
  // get media info
  Ext.Ajax.request({
    success: getLessonData,
    url: ajaxurl,
    requestMethod: 'GET',
    params: {
      targeturl: url,
      articleaction: 'ajax',
      method: 'getlessondata',
      node: articleid
    }
  });
}

function init(_url, _articleid, _loginurl, _fullscreen, _nobrowse, _embed, _lessonframeid, _loggedin) {
  url = _url;                           // url of a lesson article
  articleid = _articleid;               // id of article to display
  ajaxurl = url;                        // url for ajax
  loginurl = _loginurl;                 // url for login
  fullscreen = _fullscreen === 'true';  // fullscreen player
  nobrowse = _nobrowse === 'true';      // hide the browser 
  embed = _embed === 'true';            // embedded player
  lessonframeid = _lessonframeid;       // lessonframe
  loggedin = _loggedin;
  
  requestLessonData();
}

function openFullscreen() {
  if(isLesson) {
	  players.fullscreenPause();
  }
  window.open(window.location.href + (url.indexOf('?') == -1 ? '?' : '&') + "fullscreen=true", "_blank",
              "status=no,toolbar=no,menubar=no,location=no,directories=no, resizable=yes" +
              nobrowse ? "&nobrowse=true" : "");
}

// Publics 
return { 
    init: init, 
    showResource: showResource, 
    openFullscreen: openFullscreen,
    logout: logout
  };
}();


