var CLOTH = {}

CLOTH.STEPS = 9;

CLOTH.buildSizeTable = function (clothes)
{
    var $table = $(element('table'));
    
    //Header
    var $tr = $(element('tr'));
    
    for (i in clothes.size) $tr.append(element('th', s('size-'+ i) ));
    
    if (clothes.part)
        for (i in clothes.part) $tr.append(element('th', s('size-'+ i) ));
        
   $table.append( $(element('thead')).append($tr) );
   
   //Data
   $tbody = $(element('tbody'));
   
   for (i = 0; i < CLOTH.STEPS; i++)
   {
       $tr = $(element('tr'));
       
       for (j in clothes.size) 
           $tr.append(element('td', clothes.size[j].get(i)));
    
       if (clothes.part)
           for (j in clothes.part) 
               $tr.append(element('td', clothes.part[j].get(i)));   
               
       $tbody.append($tr);    
   }
   
   $table.append($tbody);
   
   function element (name, text) {
       if (!text) text = '';
       return $('<'+name+'>'+ text +'</'+name+'>');
   }
   
   return $table;
}

CLOTH.buildSizeList = function (clothes)
{
    var $table = $(element('table')).addClass('data-table'),
        $tbody = $(element('tbody'));
        
    $table.append($tbody);
    
    fillRows(clothes.size);
    if (clothes.part)
    {
        $tbody.append('<tr><td colspan="'+ (CLOTH.STEPS+1) +'"><hr size="1"/></td></td>')
        fillRows(clothes.part);
    }
    $table.append($tbody);
    
    function fillRows (row)
    {
        for (i in row)
        {
            $tr = $(element('tr'));
            $tbody.append($tr);
            $tr.append(
                element('td', s('size-'+ i)).addClass('header')
            );
            for (j = 0; j < CLOTH.STEPS; j++)
                $tr.append(
                    element('td', row[i].get(j).number())
                );
        }
    }
    
    // Highlight row-col cross
	$table.find('td').hover(
		function() 
		{
			var tdIndex = $(this).parent().children().index(this),
			    trIndex = $(this).parent().parent().children().index($(this).parent());			    
			
			if (tdIndex != 0 && (!$(this).attr('colspan') || $(this).attr('colspan') == 1))
			{
			    $table.find('th:eq('+tdIndex+')').addClass('hover');
			    $table.find('tbody tr:lt('+trIndex+')').find('td:eq('+tdIndex+')').addClass('hover-upper');
			    $table.find('tbody tr:gt('+trIndex+')').find('td:eq('+tdIndex+')').addClass('hover-upper');
		    }
		},
		function() 
		{
			var tdIndex = $(this).parent().children().index(this),
			    trIndex = $(this).parent().parent().children().index($(this).parent());
			
			$table.find('th:eq('+tdIndex+')').removeClass('hover');
			$table.find('tbody tr:lt('+trIndex+')').find('td:eq('+tdIndex+')').removeClass('hover-upper');
			$table.find('tbody tr:gt('+trIndex+')').find('td:eq('+tdIndex+')').removeClass('hover-upper');
		}
	);
   
    return $table;
}

CLOTH.setCalculator = function (clothes)
{
    var $calculator = element('div').addClass('size-calculator');
    
    if (!clothes.part) return $calculator;
    
    var $table = element('table').addClass('input');
    $calculator
        .append(element('h2').html(s('size in cm') + ' → ' + s('size') + ' ').append(getSelect()))
        .append($table);
    
    function getSelect ()
    {
        var $select = element('select');
        for (i in clothes.size)
            $select.append(
                element('option', clearSize(s('size-'+ i)) ).attr('value', i)
            );
        return $select
    }
    
    for (part in clothes.part)
    {
        var $tr = element('tr');
        $tr.append(element('td', 
                clearSize(s('size-'+ part))
            ))
           .append(element('td', '<input type="text" name="'+ part +'" maxlength="3"/>'));
        $table.append($tr);
    }
    
    function clearSize (str) {return str.replace('<br/>', ' ').replace(/\(.*\)/, '')}
    
    var $td = element('td');
    $td.attr('valign', 'middle').attr('rowspan', $table.find('tr').length).addClass('size');
        
    $table.find('tr:first').append($td);
    
    var $inputs = $table.find('input'),
        sizeStack = {};
    
    var select = $calculator.find('select').get(0);
        
    $inputs.keyup(getSizeByInputs);
    $(select).change(getSizeByInputs);
    
    function getSizeByInputs ()
    {
        var sizeType = select.options[select.selectedIndex].value;
        
        $inputs.each(function () 
        {
            var part = $(this).attr('name'),
                value = $(this).val();                
            
            if ((/^[0-9]+([,.][0-9]+)?$/).test(value))
            {    
                var index = clothes.part[part].getIndexBySize( 
                        parseInt($(this).val())
                    ),
                    size = clothes.size[sizeType].get(index);
                       
                sizeStack[part] = size;
                $(this).css('color', '');
            } else {
                $(this).css('color', 'red')
                sizeStack[part] = '';
            }
        })
        
        $td.html('');
        
        var popularSize = popular(sizeStack)
        
        if (popularSize)
            $td.append(
                element('p', popularSize.number()).addClass('popular-size')
            );
        
        for (part in sizeStack)
            if (sizeStack[part])
            {
                if (sizeStack[part] != popularSize)
                    $td.append(
                        element('p', clearSize(s('size-'+ part)) + ' — ' + sizeStack[part])
                    );
            }
    }
    
    return $calculator;
}

function popular (obj) 
{
    var stack = [], i;
    for (i in obj)
        if (obj[i])
        {        
            if (!stack[ obj[i] ]) 
                stack[obj[i]] = 1;
            else
                stack[obj[i]]++;
        }
               
    var max;
    for (i in stack)
        if (!max || max.val < stack[i]) 
            max = {val: stack[i], ind: i}
        
    return max ?  max.ind : 0;   
}

function element (name, text) {
    if (!text) text = '';
    return $('<'+name+'>'+ text +'</'+name+'>');
}

var Size = function (start, step, interval, separator)
{
    var start = start,
        step = step,
        interval = interval ? interval : 0;
    
    this.get = function (i)
    {
        if (!separator) separator = '—';
        var from = start + step*i;
        
        return interval ? from + separator + (from + interval) : from.toString();
    }
    
    this.getIndexBySize = function (size)
    {
        var ind = (size - start) / step;
        if (ind < 0) ind = 0;
        return Math.floor(ind);
    }
}

var SizeX = function (startX)
{
    var X = ['XXS', 'XS', 'S', 'M', 'L', 'XL', 'XXL'];

	this.get = function (i)
    {
        return X.get(i + offset);
    }
    
    X.get = function (i) {
        return this[i] ? this[i] : (i - 5) + 'XL';
    }
    
    X.indexOf = function (value) {
        var i = 0;
        while (this[i] && this[i] != value) i++;
        return i;
    }
    
    var offset = startX ? X.indexOf(startX) : 0;            
}

var ChildGrowth = function (ageInterval)
{
    var growth = [//in cm
        74, 83, 92, 98, 104, 110, 116, 122, 128, //0..8
        134, 138, 142, 150, 156, 162, 169, 177, 180 //9..16
    ];
    
    this.get = function (age) 
    {
        age = age*ageInterval;
        if (age > 16) age = 16;
        if (age < 0)  age = 0;
        if (age+ageInterval > growth.length - 1) ageInterval = 1;
        
        return growth[age] + '—' + growth[age + ageInterval];
    }
    
    this.getIndexBySize = function (size)
    {
        var i = 0;
        while (growth[i] && growth[i] < size) i++;
        i--;
        return Math.round(i / ageInterval);
    }
}

var ChildHand = function (ageInterval)
{
    var length = [37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, 72, 74, 76, 78, 80],
        step = 5;
    this.get = function (age)
    {
        if (age > 16) age = 16;
        if (age < 0)  age = 0;
        if (age*ageInterval > length.length - 1) ageInterval = 1;
        age *= ageInterval;
        
        return length[age] + '—' + (length[age] + step); 
    }
    this.getIndexBySize = function (size)
    {
        var i = 0;
        while (length[i] && length[i] < size) i++;
        i--;
        return Math.round(i / ageInterval);
    }
}

var ChildLeg = function (ageInterval)
{
    var length = [45, 49, 54, 58, 62, 67, 72, 76, 80, 83, 87, 90, 94, 97, 101, 104, 108],
        step = 8;
    this.get = function (age)
    {
        if (age > 16) age = 16;
        if (age < 0)  age = 0;
        if (age*ageInterval > length.length - 1) ageInterval = 1;
        age *= ageInterval;
        
        return length[age] + '—' + (length[age] + step); 
    }
    this.getIndexBySize = function (size)
    {
        var i = 0;
        while (length[i] && length[i] < size) i++;
        i--;
        return Math.round(i / ageInterval);
    }
}

/*
 * Size data
 */
CLOTH.Data = {}; 

CLOTH.Data.Outerwear = {}

CLOTH.Data.Outerwear.Women = 
{
    size: {
        ru: new Size (42, 2),
        us: new SizeX (),
        de: new Size (36, 2),
        en: new Size (4, 2),
        fr: new Size (36, 2),
        it: new Size (36, 2)
    },
    part: {
        growth    : new Size (160, 2, 3),
        neck      : new Size (34, 1),
        shoulders : new Size (36, 1),
        chest     : new Size (82, 4, 3),
        waist     : new Size (58, 3, 4),
        hip       : new Size (86, 3, 4),
        hand      : new Size (72.5, 2.5),
        leg       : new Size (101, 1, 3)
    }
}

CLOTH.Data.Outerwear.Men =
{
    size: {
        ru: new Size (42, 2),
        us: new SizeX (),
        eu: new Size (42, 2)
    },
    part: {
        growth    : new Size (167, 3, 3),
        shoulders : new Size (41, 1.5),
        chest     : new Size (84, 4, 3),
        waist     : new Size (72, 4, 3),
        hip       : new Size (88, 4, 3),
        hand      : new Size (77, 2),
        leg       : new Size (99, 2, 3)
    }
}

CLOTH.Data.Outerwear.Child = //age is iterator
{
    size: {
        ru: new Size (30, 2, 2, '/'),
        eu: new Size (4, 2),
        en: new Size (4, 2),
        us: new Size (3, 2)
    },
    part: {
        growth : new ChildGrowth (2),
        age    : new Size (1, 2, 2),
        head   : new Size (48, 2),
        chest  : new Size (50, 3, 5),
        waist  : new Size (50, 2, 4),
        hip    : new Size (53, 5, 4),
        hand   : new ChildHand (2),
        leg    : new ChildLeg (2)
    }
}

CLOTH.Data.Underwear= {}

CLOTH.Data.Underwear.Women =
{
    size: {
        ru: new Size (42, 2),
        us: new Size (8, 2),
        de: new Size (36, 2),
        fr: new Size (36, 2),
        en: new Size (6, 2),
        it: new Size (36, 2)
    }
}

CLOTH.Data.Underwear.Men = 
{
    size: {
        ru: new Size (44, 2),
        us: new SizeX ('S'),
        fr: new Size (2, 1),
        en: new Size (32, 2),
        de: new Size (3, 1)
    }
}

CLOTH.Data.Socks = {}

CLOTH.Data.Socks.Men =
{
    size: {
        ru: new Size (38, 1),
        us: new Size (9, 0.5),
        en: new Size (9, 0.5)
    }
}

CLOTH.Data.Shirts = {}

CLOTH.Data.Shirts.Men = 
{
    size: {
        ru: new Size (36, 1),
        us: new Size (14, 0.5), //S
        en: new Size (34, 2),
        eu: new Size (36, 1)
    }
}

CLOTH.Data.footwear = {}

CLOTH.Data.footwear.Women = 
{
    size: {
        ru: new Size(34, 1),
        us: new Size(4, 0.5),
        en: new Size(2, 0.5),
        eu: new Size(35, 1)
    }
}

CLOTH.Data.footwear.Men = 
{
    size: {
        ru: new Size(38, 1),
        us: new Size(6, 1),
        en: new Size(5, 1),
        eu: new Size(39, 1)
    }
}

CLOTH.Data.footwear.Child = 
{
    size: {
        ru: new Size(17, 0.5),
        us: new Size(24, 1),
        en: new Size(7, 1),
        eu: new Size(8, 1)
    }
}

/*
 * Array.indexOf (for cutted browsers)
 */
 
if(!Array.indexOf) 
{
    Array.prototype.indexOf = function(obj) 
    {
        for(var i = 0; i < this.length; i++)
            if (this[i] == obj) return i;
        return -1;
    }
}