var Utils = new function(){};

(function($) {
    $.fn.changeElementType = function(newType) {
        var attrs = {};

        $.each(this[0].attributes, function(idx, attr) {
            attrs[attr.nodeName] = attr.nodeValue;
        });

        this.replaceWith(function() {
            return $("<" + newType + "/>", attrs).append($(this).contents());
        });
    };
})(jQuery);

Utils.clone = function(object) {
  function OneShotConstructor(){}
  OneShotConstructor.prototype = object;
  return new OneShotConstructor();
}

Utils.first = function(obj) {
    for (var a in obj) return a;
}

Utils.ObjectLength = function(obj) {
	var length = 0;
	for (var o in obj) {
		length++;
	}
	return length;
}

Utils.copy = function(o) {
	var temp = o;
	return temp;
}


Utils.zeroWiodace = function(i) {
    return (i < 10) ? '0'+i : i;
}

Utils.getURLParam = function()
{

    url =  window.location.search.substring(0);

    var result = {};
                var searchIndex = url.indexOf("?");
                if (searchIndex == -1 ) return result;
    var sPageURL = url.substring(searchIndex +1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++)
    {    	
        var sParameterName = sURLVariables[i].split('=');      
        result[sParameterName[0]] = sParameterName[1];
    }
    return result;
}

Utils.getRandomArrayElements = function(arr, count) {
    var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
    while (i-- > min) {
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
    }
    return shuffled.slice(min);
}



Utils.createCookie = function(name, value, days) {
    var expires;

    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toGMTString();
    } else {
        expires = "";
    }
    document.cookie = escape(name) + "=" + escape(value) + expires + "; path=/;domain=darkan1.website.pl";
}

Utils.readCookie = function(name) {
    var nameEQ = escape(name) + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) === ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) === 0) return unescape(c.substring(nameEQ.length, c.length));
    }
    return null;
}

Utils.eraseCookie = function(name) {
    createCookie(name, "", -1);
}


var Debug = function() {
	this.debugMode = true;
}

Debug.prototype.log = function(msg) {
	if (this.debugMode) {
        if (console && console.log) {
            console.log(msg);
        }
	}
};

var debug = new Debug();

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/) {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}


Utils.cloneCanvas = function(oldCanvas) {

    //create a new canvas
    var newCanvas = document.createElement('canvas');
    var context = newCanvas.getContext('2d');

    //set dimensions
    newCanvas.width = oldCanvas.width;
    newCanvas.height = oldCanvas.height;

    //apply the old canvas to the new one
    context.drawImage(oldCanvas, 0, 0);

    //return the new canvas
    return newCanvas;
}



Utils.arrayAreEqual = function(array1, array2){
  return array1.length == array2.length && array1.every(function(element, index) {
    return element === array2[index]; 
  });
}

Utils.isIE = function() {
  var myNav = navigator.userAgent.toLowerCase();
  return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
}

function isUndefined(ob) {
  return typeof ob === "undefined";
}
function isObject(ob) {
  return typeof ob === "object" && ob !== null;
}
function isNumber(ob) {
  return typeof ob === "number" && !isNaN(ob);
}
function isString(ob) {
  return typeof ob === "string";
}
function isFunction(ob) {
  return typeof ob === "function";
}
function isBoolean(ob) {
  return typeof ob === "boolean";
}

/* DARKAN API */

var Darkan_API_Class = function() {
  // init
}

Darkan_API_Class.prototype.getData = function() {
  var _that = this;

  var course_status = 'incomplete';

  switch(CM.course.user.courseStatus) {
    case 'nc':
      course_status = 'incomplete';
      break;
    case 'c':
      course_status = 'completed';
      break;
    case 'f':
      course_status = 'failed';
      break;
  }

  var data = {
    score_raw: CM.course.user.score,
    score_max: CM.course.opts.score.max,
    score_required: CM.course.opts.score.required,
    course_status: course_status,
    lesson_location: (CM.course.user.lesson_location+1)
  }

  return data;
};

var Darkan_API = new Darkan_API_Class();


var scaleFactor = 1;

function isUndefined(ob) {
  return typeof ob === "undefined";
}
function isObject(ob) {
  return typeof ob === "object" && ob !== null;
}
function isNumber(ob) {
  return typeof ob === "number" && !isNaN(ob);
}
function isString(ob) {
  return typeof ob === "string";
}
function isFunction(ob) {
  return typeof ob === "function";
}
function isBoolean(ob) {
  return typeof ob === "boolean";
}

function watch(target, prop, handler) {
    if (target.__lookupGetter__(prop) != null) {
        return true;
    }
    var oldval = target[prop],
        newval = oldval,
        self = this,
        getter = function () {
            return newval;
        },
        setter = function (val) {
            if (Object.prototype.toString.call(val) === '[object Array]') {
                val = _extendArray(val, handler, self);
            }
            oldval = newval;
            newval = val;
            handler.call(target, prop, oldval, val);
        };
    if (delete target[prop]) { // can't watch constants
        if (Object.defineProperty) { // ECMAScript 5
            Object.defineProperty(target, prop, {
                get: getter,
                set: setter,
                enumerable: false,
                configurable: true
            });
        } else if (Object.prototype.__defineGetter__  && Object.prototype.__defineSetter__) { // legacy
            Object.prototype.__defineGetter__.call(target, prop, getter);
            Object.prototype.__defineSetter__.call(target, prop, setter);
        }
    }
    return this;
};

function unwatch(target, prop) {
    var val = target[prop];
    delete target[prop]; // remove accessors
    target[prop] = val;
    return this;
};