﻿/*
*   name: master.js
*   description: generic javascript run for pages contained in the master page
*   author: Tiernan Stuart
*
*
*/
var isIE = document.all ? true : false; //browser test


/*
*   Description: prevents text entry not in line with regex
*
*/
function RegexTextEntry(regex, evnt)
{
    //initialise
    var text;
    var charEntered;
    var regValidator = new RegExp(regex,"g");    
    var keyCode;
    
    //get character of current keypress and add to existing text
    if(isIE)
    {
        text = evnt.srcElement.value;
        charEntered = evnt.keyCode;
        text = text + String.fromCharCode(charEntered);
    }
    else
    {
        text = evnt.currentTarget.value;
        charEntered = evnt.charCode;
        text = text + String.fromCharCode(charEntered);
        keyCode = evnt.keyCode;
    }
    
    //don't allow character to be registered if regex fails
    if(!regValidator.test(text))
    {
        if(isIE)
        {
            evnt.returnValue = false;
            return false;
        }
        else
        {            
            if(charEntered != 0)
            {
                evnt.preventDefault();
                return false;
            }
        }
    }
    return true;
}
/*
*   Description: prevents postback
*
*/
function PreventPostBack(evnt)
{
    if(isIE)
    {
        evnt.returnValue = false;
        return false;
    }
    else
    {            
        evnt.preventDefault();
        return false;
    }
    return true;
}

/************************extra date patterns for extjs date object*********************************/
Date.patterns = {
    ISO8601Long:"Y-m-d H:i:s",
    ISO8601Short:"Y-m-d",
    ShortDate: "n/j/Y",
    LongDate: "l, F d, Y",
    FullDateTime: "l, F d, Y g:i:s A",
    MonthDay: "F d",
    ShortTime: "g:i A",
    LongTime: "g:i:s A",
    SortableDateTime: "Y-m-d\\TH:i:s",
    UniversalSortableDateTime: "Y-m-d H:i:sO",
    YearMonth: "F, Y"
};

/*********************************fix for bugs in datefield in version 2.1***************************/

// private
Date.createParser = function(format) {
  var funcName = "parse" + Date.parseFunctions.count++;
  var regexNum = Date.parseRegexes.length;
  var currentGroup = 1;
  Date.parseFunctions[format] = funcName;

  var code = "Date." + funcName + " = function(input){\n"
      + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, o, z, u, v;\n"
      + "input = String(input);var d = new Date();\n"
      + "y = d.getFullYear();\n"
      + "m = d.getMonth();\n"
      + "d = d.getDate();\n"
      + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
      + "if (results && results.length > 0) {";
  var regex = "";

  var special = false;
  var ch = '';
  for (var i = 0; i < format.length; ++i) {
      ch = format.charAt(i);
      if (!special && ch == "\\") {
          special = true;
      }
      else if (special) {
          special = false;
          regex += String.escape(ch);
      }
      else {
          var obj = Date.formatCodeToRegex(ch, currentGroup);
          currentGroup += obj.g;
          regex += obj.s;
          if (obj.g && obj.c) {
              code += obj.c;
          }
      }
  }

  code += "if (u){\n"
      + "v = new Date(u * 1000);\n" // give top priority to UNIX time
      + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0){\n"
      + "v = new Date(y, m, d, h, i, s, ms);\n"
      + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0){\n"
      + "v = new Date(y, m, d, h, i, s);\n"
      + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0){\n"
      + "v = new Date(y, m, d, h, i);\n"
      + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0){\n"
      + "v = new Date(y, m, d, h);\n"
      + "}else if (y >= 0 && m >= 0 && d > 0){\n"
      + "v = new Date(y, m, d);\n"
      + "}else if (y >= 0 && m >= 0){\n"
      + "v = new Date(y, m);\n"
      + "}else if (y >= 0){\n"
      + "v = new Date(y);\n"
      + "}\n}\nreturn (v && (z || o))?" // favour UTC offset over GMT offset
      +     " (Ext.type(z) == 'number' ? v.add(Date.SECOND, (v.getTimezoneOffset() * 60) + z) :" // reset to UTC, then add offset
      +         " v.add(Date.HOUR, (v.getGMTOffset() / 100) + (o / -100))) : v;\n" // reset to GMT, then add offset
      + "}";

  Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i");
  eval(code);
};


if(typeof(Ext) == 'object')
{
// private
Ext.apply(Date.parseCodes, {
    j: {
        g:1,
        c:"d = parseInt(results[{0}], 10);\n",
        s:"(\\d{1,2})" // day of month without leading zeroes (1 - 31)
    },
    M: function() {
        for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); // get localised short month names
        return Ext.applyIf({
            s:"(" + a.join("|") + ")"
        }, Date.formatCodeToRegex("F"));
    },
    n: {
        g:1,
        c:"m = parseInt(results[{0}], 10) - 1;\n",
        s:"(\\d{1,2})" // month number without leading zeros (1 - 12)
    },
    o: function() {
        return Date.formatCodeToRegex("Y");
    },
    g: function() {
        return Date.formatCodeToRegex("G");
    },
    h: function() {
        return Date.formatCodeToRegex("H");
    },
    P: {
      g:1,
      c:[
          "o = results[{0}];",
          "var sn = o.substring(0,1);", // get + / - sign
          "var hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60);", // get hours (performs minutes-to-hour conversion also, just in case)
          "var mn = o.substring(4,6) % 60;", // get minutes
          "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" // -12hrs <= GMT offset <= 14hrs
      ].join("\n"),
      s: "([+\-]\\d{2}:\\d{2})" // GMT offset in hrs and mins (with colon separator)
    }
});

}

// private
Date.formatCodeToRegex = function(character, currentGroup) {
    // Note: currentGroup - position in regex result array (see notes for Date.parseCodes above)
    var p = Date.parseCodes[character];

    if (p) {
      p = Ext.type(p) == 'function'? p() : p;
      Date.parseCodes[character] = p; // reassign function result to prevent repeated execution      
    }

    return p? Ext.applyIf({
      c: p.c? String.format(p.c, currentGroup || "{0}") : p.c
    }, p) : {
        g:0,
        c:null,
        s:Ext.escapeRe(character) // treat unrecognised characters as literals
    }
};

/**************************extend array to have a contains function***************************************/
Array.prototype.contains = function (element) 
  {
          for (var i = 0; i < this.length; i++) 
       {
              if (this[i][0] == element[0]) 
          {
                      return true;
              }
          }
          return false;
  };
  
 Array.prototype.contains2 = function (element) 
  {
          for (var i = 0; i < this.length; i++) 
       {
              if (this[i] === element) 
          {
                      return true;
              }
          }
          return false;
  }; 
  
/****************************padding functionality*****************************************/
function padleft(val, ch, num)
 {
    var re = new RegExp(".{" + num + "}$");
    var pad = "";
    if (!ch) ch = " ";
    do  {
        pad += ch;
    }while(pad.length < num);
    return re.exec(pad + val);
}
function padright(val, ch, num)
{
    //var re = new RegExp("^.{" + num + "}");
    var pad = val;
    if (!ch) ch = " ";
    do {
        pad += ch;
        
    } while (pad.length < num);
    //return re.exec(val + pad);
    return pad;
}
/****************************Browser Window Size and Position*****************************************/
// copyright Stephen Chapman, 3rd Jan 2005, 8th Dec 2005
function pageWidth() {return window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ?       document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;}
function pageHeight() {return  window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ?  document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null;}
function posLeft() {return typeof window.pageXOffset != 'undefined' ? window.pageXOffset :document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;}
function posTop() {return typeof window.pageYOffset != 'undefined' ?  window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;}
function posRight() {return posLeft()+pageWidth();} function posBottom() {return posTop()+pageHeight();}

/****************************Fixes for assignment grid filtering*****************************************/
function ReturnAbsoluteRootPath()
{
    var absPath = window.location.href;
    var ind = absPath.lastIndexOf('/');
    var rootPath = absPath.substring(0, ind); 
    return rootPath;
}

/*
override needed so that the filters on the assignments table work with newly inserted
records. Without this, filtering will cause any newly added records to be lost from the 
table
*/

if(typeof(Ext) == 'object')
{
Ext.override(Ext.data.Store, {
    /**
     * Inserts Records to the Store at the given index and fires the add event.
     * @param {Number} index The start index at which to insert the passed Records.
     * @param {Ext.data.Record[]} records An Array of Ext.data.Record objects to add to the cache.
     */
    insert : function(index, records){
        var hasSnapshot = this.isFiltered();
        var snapshotInsertIndex = -1;
        records = [].concat(records);
        if(hasSnapshot) {
            var snapshot = this.snapshot;
            var currentCount = this.getCount();
            if(index == 0 || currentCount == 0) {    // Insert at top
                snapshotInsertIndex = 0;
            } else if(index > currentCount) {
                index = currentCount;
            }
            
            // Find the index by record
            if(snapshotInsertIndex == -1) {
                snapshotInsertIndex = snapshot.indexOf(this.getAt(index < currentCount ? index : currentCount-1));
            }
            
            if(index == currentCount) {
                snapshotInsertIndex++
            }
            for(var i = 0, len = records.length; i < len; i++){
                snapshot.insert(snapshotInsertIndex, records[i]);
            }
        }
        for(var i = 0, len = records.length; i < len; i++){
            this.data.insert(index, records[i]);
            records[i].join(this);
        }
        this.fireEvent("add", this, records, index);
    }
});
}


/**************************mobile browser detection********************************/


//Initialize our user agent string to lower case.
var uagent = navigator.userAgent.toLowerCase();

var isIphone = !!(uagent.match(/iPhone/i));
var isBlackberry = !!(uagent.match(/blackberry/i));
var isAndroid = !!(uagent.match(/android/i));
var isIpod = !!(uagent.match(/ipod/i));

var isUAMobile = !!(uagent.match(/(iPhone|iPod|blackberry|android|htc|lg|midp|mmp|mobile|nokia|opera mini|palm|pocket|psp|sgh|smartphone|symbian|treo mini|Playstation Portable|SonyEricsson|Samsung|MobileExplorer|PalmSource|Benq|Windows Phone|Windows Mobile|IEMobile|Windows CE|Nintendo Wii)/i));
var isUATablet = !!(uagent.match(/(iPad|SCH-I800|xoom|kindle)/i)); 
