/*jshint unused:false*/
// Глобальные методы
/**
* Делает `constructor` подклассом `extendee` и
* копирует свойства прототипов классов из `shallowExtendees` в прототип `contrustor`.
* @param {function} constructor
* @param {function} extendees
* @param {function[]} [shallowExtendees]
* @global
*/
function extend(constructor, extendee, shallowExtendees){
constructor.prototype = Object.create(extendee.prototype);
constructor.prototype.constructor = constructor;
if(!shallowExtendees){
return;
}
var mixins = shallowExtendees.map(function(c){
return c.prototype;
});
mixin(constructor, mixins);
}
/**
* Добавляет методы из `mixins` в прототип `constructor`.
* @param {function} constructor
* @param {object[]} mixins
* @global
*/
function mixin(constructor, mixins){
for(var i = 0; i < mixins.length; i++){
var mix = mixins[i];
for(var key in mix){
if(!mix.hasOwnProperty(key)){
continue;
}
if(key == 'constructor'){
continue;
}
if(constructor.prototype[key]){
console.warn('Overwriting method', key, 'in', constructor, 'prototype');
}
constructor.prototype[key] = mix[key];
}
}
}
/**
* Возвращает прототип прототипа конструктора.
* @param {function} constructor
*
* @return {prototype}
* @global
*/
function supercall(constructor){
return Object.getPrototypeOf(constructor.prototype);
}
/**
* Fisher–Yates Shuffle (перемешивание массивов).
* @global
* @param {array} a массив для перемешивания
*
* @return {array} перемешанный массив (тот же, что и на входе)
*/
function shuffleArray(a){
var currentIndex = a.length,
temporaryValue,
randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = a[currentIndex];
a[currentIndex] = a[randomIndex];
a[randomIndex] = temporaryValue;
}
return a;
}
/**
* Совмещает свойства по умолчанию с неполностью указанными свойствами.
* @global
* @param {object} dest опции по умолчанию, которые нужно перезаписать
* @param {object} source опции, которыми нужно перезаписать
*
* @return {object} Возвращает объект, в котором свойства `dest` заменены на
* свойства `source`, если они существуют и там и там.
*/
function mergeOptions(dest, source){
if(typeof dest != 'object'){
console.error('Can\'t merge options: no destination provided');
return;
}
if(typeof source == 'object'){
for(var o in source){
if(source.hasOwnProperty(o) && dest.hasOwnProperty(o)){
dest[o] = source[o];
}
}
}
return dest;
}
/**
* Возвращает функцию, которая будет добавлять действие в последовательность указанного {@link Sequencer}'a.
* @param {Sequencer} sequencer
* @param {any} obj объект, к которому принадлежит метод
* @param {string} key название метода на объекте
*
* @return {function}
*/
function getSequentialMethod(sequencer, obj, key){
var method = obj[key];
return function(){
var args = [obj],
len = arguments.length;
for(var i = 0; i < len; i++) {
args[i + 1] = arguments[i];
}
var binded = method.bind.apply(method, args);
sequencer.queueUp(binded, 0);
};
}
/**
* Добавляет нули перед строкой до указанного кол-ва.
* @global
* @param {string} str строка
* @param {number} [len=2] желаемая длина строки длина
*
* @return {string} Полученная строка с нулями.
*/
function leadWithZeros(str, len){
len = len || 2;
return (Array(len).join('0') + str).slice(-len);
}
/**
* Конвертирует число в строку по типу `#000000`.
* @global
* @param {number} number число
*
* @return {string} Строка по типу `#000000`.
*/
function numberToHexColor(number){
var string = leadWithZeros(number.toString(16), 6);
string = '#' + string;
return string;
}
// TEST AND DEBUG FUNCTIONS
var getCard,
getCards;
/**
* Выводит в консоль имена слоев интерфейса и сами слои
* @type {function}
* @global
* @see {@link UI.Layers#getOrder}
*/
function printLayers(){
console.table(ui.layers.getOrder());
}
/**
* Переносит самую левую карту в руке игрока на стол с задержкой.
* @param {number} [i=0] id поля стола
* @param {number} [delay=3000] задержка
* @global
*/
function moveFirstPlayerCardToTable(i, delay){
if(delay === undefined){
delay = 3000;
}
var c = fieldManager.fields[gameInfo.pid].cards[0];
var ci = {cid: c.id, suit: c.suit, value: c.value};
setTimeout(function(){
fieldManager.moveCards(fieldManager.fields['TABLE' + (i || 0)], [ci]);
}, delay);
}
/* jshint ignore:start */
var animTest = {
eventFeed: function(){
for(var i = 0; i < 20; i++){
eventFeed.newMessage(Math.random(), (20-i)*200);
}
},
countdown: function(i, message){
if(!i || typeof i != 'number' || isNaN(i) || i < 1){
i = 5;
}
if(!message){
message = 'GO!';
}
var start = Date.now();
var last = 0;
var interval = setInterval(function(){
var now = Date.now();
if(now - last >= 1000){
last = now;
switch(i){
case 0:
eventFeed.newMessage(message);
break;
case -1:
eventFeed.clear();
clearInterval(interval);
break;
default:
eventFeed.newMessage(i + '...');
}
i--;
}
}, 50);
}
};