
function slider(elemId, sliderWidth, range1, range2, step, func) {
	var knobWidth = 13;				// ширина и высота бегунка
	var knobHeight = 21;			// изменяются в зависимости от используемых изображений
	var sliderHeight = 21;			// высота slider'а
	
	var offsX,tmp;					// вспомагательные переменные
	var d = document;
	var isIE = d.all || window.opera;	// определяем модель DOM
	var point = (sliderWidth-knobWidth)/(range2-range1);
	// point - количество пикселей на единицу значения
	
	var slider = d.createElement('DIV'); // создаем slider
	slider.id = elemId + '_slider';
	slider.className = 'slider';
	d.getElementById(elemId).appendChild(slider);	
	
	var knob = d.createElement('DIV');	// создаем ползунок
	knob.id = elemId + '_knob';
	knob.className = 'knob';
	slider.appendChild(knob); // добавляем его в документ
	
	knob.style.left = 0;			// бегунок в нулевое значение
	knob.style.width = knobWidth+'px';	
	knob.style.height = knobHeight+'px';
	slider.style.width = sliderWidth+'px';
	slider.style.height = sliderHeight+'px';
	
	var sliderOffset = slider.offsetLeft;			// sliderOffset - абсолютное смещение slider'а
//	tmp = slider.offsetParent;		// от левого края в пикселях (в IE не работает)
//	while(tmp.tagName != 'BODY') {
//		sliderOffset += tmp.offsetLeft;		// тут его и находим
//		tmp = tmp.offsetParent;
//	}
	
	if(isIE)						// в зависимости от модели DOM
	{								// назначаем слушателей событий
		knob.onmousedown = startCoord;		
		slider.onclick = sliderClick;		
		knob.onmouseup = endCoord;		
		slider.onmouseup = endCoord;			
	}
	else {
		knob.addEventListener("mousedown", startCoord, true);		
		slider.addEventListener("click", sliderClick, true);		
		knob.addEventListener("mouseup", endCoord, true);	
		slider.addEventListener("mouseup", endCoord, true);	
	}


// далее подробно не описываю, кто захочет - разберется
//////////////////// функции установки/получения значения //////////////////////////

	function setValue(x)	// установка по пикселям
	{
		if(x < 0) knob.style.left = 0; 
		else if(x > sliderWidth-knobWidth)
		{
		 knob.style.left = (sliderWidth-knobWidth)+'px';
//		alert(knob.style.left);
		}
		else {
			if(step == 0) knob.style.left = x+'px';			
			else knob.style.left = Math.round(x/(step*point))*step*point+'px';
		}
		
		func(getValue());

//		d.getElementById('info').value = getValue();	// это вывод значения для примера
	}
	function setValue2(x)	// установка по значению
	{
		if(x < range1 || x > range2) alert('Value is not included into a slider range!');
		else setValue((x-range1)*point);
		
		func(getValue());

//		d.getElementById('info').value = getValue();
	}

	function getValue() 
	{return Math.round(parseInt(knob.style.left)/point)+range1;}

//////////////////////////////// слушатели событий ////////////////////////////////////

	function sliderClick(e) {	
		var x;
		if(isIE) {
			if(event.srcElement != slider) return; //IE onclick bug
			x = event.offsetX - Math.round(knobWidth/2);
		}	
		else x = e.pageX-sliderOffset-knobWidth/2;
		setValue(x);
	}

	function startCoord(e) {				
		if(isIE) {	
			offsX = event.clientX - parseInt(knob.style.left);
			slider.onmousemove = mov;
		}
		else {				
			slider.addEventListener("mousemove", mov, true);
		}
	}
	
	function mov(e)	{
		var x;	
		if(isIE) x = event.clientX-offsX;
		else x = e.pageX-sliderOffset-knobWidth/2;
		setValue(x);
	}

	function endCoord()	{
		if(isIE) slider.onmousemove = null;	
		else slider.removeEventListener("mousemove", mov, true);
	}

	// объявляем функции setValue2 и getValue как методы класса
	this.setValue = setValue2;
	this.getValue = getValue;
} // конец класса




function readCookie(name)
{
var xname = name + "=";
var xlen = xname.length;
var clen = document.cookie.length;
var i = 0;
while(i < clen)
{
	var j = i + xlen;
	if (document.cookie.substring(i, j) == xname)
		return getCookieVal(j);
	i = document.cookie.indexOf(" ", i) + 1;
	if (i == 0) 
		break;
}
return null;
}

function getCookieVal(n)
{
var endstr = document.cookie.indexOf(";", n);
if (endstr == -1)
	endstr = document.cookie.length;
return unescape(document.cookie.substring(n, endstr));
}


function writeCookie(name, value, expires, path, domain, secure)
{
var c = name + "=" + escape(value) +
((expires) ? "; expires="  + expires.toGMTString() : "") +
((path) ? "; path=" + path : "") +
((domain) ? "; domain=" + domain : "") +
((secure) ? "; secure" : "");

document.cookie = c;
}


var PROXY_ARR = new Array(); // Глобальная очередь Proxy для проверки
var IN_PROGRESS = new Array();
var STATUS_OK_CNT = 0;
var STATUS_ERR_CNT = 0;
var PROXY_LIST_LEN = 0;
var IS_IN_PROGRESS = 0;
function parse_proxy_list()
{
	var proxy_list_str = document.getElementById('proxy_list').value;

	var default_protokol = 'http';
	if (document.getElementById('protokol_socks5').checked)
		default_protokol = 'socks5';

	var regexp = /((?:(?:http|socks5):\/\/)?(?:(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?:(\d|[a-z])+(\-(?!\-+)(\d|[a-z])+)*(\d|[a-z])*\.)+[a-z]{2,5}):\d{2,5})/i;
	var regexp_protokol = /^(?:http|socks5):\/\//i;


	while (regexp.exec(proxy_list_str))
	{
		var proxy = RegExp.$1;
		var index = proxy_list_str.indexOf(proxy);
		proxy_list_str = proxy_list_str.substring(index + proxy.length, proxy_list_str.length);

		if (!regexp_protokol.exec(proxy))
			proxy = default_protokol + '://' + proxy;

		PROXY_ARR.push(proxy);
	};

	PROXY_LIST_LEN = PROXY_ARR.length;
	if (PROXY_LIST_LEN == 0)
	{
		alert('Не указан ни один Proxy сервер для проверки!');
		return;
	}

	clear_results_table();
	disable_poehali_button(true);
	
	IS_IN_PROGRESS = 1;
	for (var i = 0; i < 25; i++)
		check_proxy();

	time_iretation();

//	var p;
//	while(p = PROXY_ARR.shift())
//	{
//		check_proxy(p);
//	}
}


var ind = ['/', '-', '\\', '|'];
var cur_ind = 0;
function time_iretation()
{
	if (IS_IN_PROGRESS == 0)
		return;

	cur_ind++;
	if (cur_ind > 3)
		cur_ind = 0;

	var len = IN_PROGRESS.length;
	for (var i = 0; i < len; i++)
	{
		if (IN_PROGRESS[i] == 0)
			continue;
	
		var ih = IN_PROGRESS[i].innerHTML;
		IN_PROGRESS[i].innerHTML = ih.substr(0, ih.length - 1) + ind[cur_ind];
	}

	setTimeout(time_iretation, 150);
}

function disable_poehali_button(disable)
{
	var poehali = document.getElementById('poehali_button');
	poehali.disabled = disable;
}


function get_xml_http_request()
{
	var xmlHttp = false;
	
	try
	{
		xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch (e)
	{
		try
		{
			xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch (e2)
		{
			xmlHttp = false;
		}
	}

	if (!xmlHttp && window.XMLHttpRequest)
	{
		xmlHttp = new XMLHttpRequest();
		if (xmlHttp.overrideMimeType)
		{
			xmlHttp.overrideMimeType('text/xml');
        }
	}
	
	return xmlHttp;
}



function check_proxy ()
{
	var ft = document.getElementById("form_table");
    var cr = document.getElementById("check_results");

	var proxy = PROXY_ARR.shift();
	if (PROXY_LIST_LEN == STATUS_ERR_CNT + STATUS_OK_CNT) // Если очередь проверки закончилась
	{
		var row = cr.insertRow(cr.rows.length);
		var cell = row.insertCell(0);
        cell.colSpan = cr.rows[0] ? cr.rows[0].cells.length : 1;
		cell.innerHTML = 'Итого проверено: <b>' + PROXY_LIST_LEN + '</b>, успешно: <b>' + STATUS_OK_CNT + '</b>, ошибок: <b>' + STATUS_ERR_CNT + '</b>';
		cell.width = ft.offsetWidth;
		disable_poehali_button(false);
		IS_IN_PROGRESS = 0;
		
		refresh_sort();
		
		return;
	}
	
	if (!proxy)
		return;

    var row = cr.insertRow(cr.rows.length);
    var wait_cell = row.insertCell(0);
    wait_cell.colSpan = cr.rows[0] ? cr.rows[0].cells.length : 1;
    wait_cell.innerHTML = proxy + '...  ';
    wait_cell.width = ft.offsetWidth;
    var wait_cell_index = IN_PROGRESS.length;
    IN_PROGRESS[wait_cell_index] = wait_cell;

	var xmlHttp = get_xml_http_request();

	if (!xmlHttp)
	{
		alert('Ошибка создания клиента для отправки AJAX-запроса на сервер');
		return false;
	}
			
	// Создать URL для подключения
	var timeout = document.getElementById('timeout_slider_value').value;
	var url = "/wm/proxy-checker/check.fcgi?p=" + escape(proxy) + '&timeout=' + timeout +  "&rnd=" + Math.random();

	// Установить функцию для сервера, которая выполнится после его ответа
	xmlHttp.onreadystatechange = function ()
	{
		if (xmlHttp.readyState == 4)
		{
			IN_PROGRESS[wait_cell_index] = 0;
		    var cr = document.getElementById("check_results");
			//cr.deleteRow(cr.rows.length - 1);

			var list = xmlHttp.responseXML.childNodes;
			var ok_node, er_node;
			
			for (var i = 0; i < list.length; i++)
			{
				var nn = list[i].nodeName;
				if (nn == 'ok')
					ok_node = list[i];
				else if (nn == 'er')
					er_node = list[i];
			}

			if (!ok_node && !er_node)
			{
				//var row = cr.insertRow(cr.rows.length);
				row.deleteCell(0);
				var cell = row.insertCell(0);
                cell.colSpan = cr.rows[0] ? cr.rows[0].cells.length : 1;
				cell.innerHTML = 'Ошибка проверки статуса proxy: ' + proxy;
				cell.width = ft.offsetWidth;

				STATUS_ERR_CNT++;
				check_proxy();
			}

			var ip, name, port, prot, wait, xfwd_for, http_via, code, text;
			
			var list = ok_node ? ok_node.childNodes : er_node.childNodes;
			for (var i = 0; i < list.length; i++)
			{
				var cn = list[i];
				var n = cn.nodeName;
				var v = cn.childNodes[0] ? cn.childNodes[0].nodeValue : '';
				
				if (n == 'ip')
					ip = v;
				else if (n == 'domain')
					name = v;
				else if (n == 'port')
					port = v;
				else if (n == 'protocol')
					prot = v;
				else if (n == 'time')
					wait = v;
				else if (n == 'http-forwarded-for')
					xfwd_for = v;
				else if (n == 'http-via')
					http_via = v;
				else if (n == 'code')
					code = v;
				else if (n == 'text')
					text = v;
			}

			if (er_node && !port && !ip && !port) // Если ошибка
			{
				//var row = cr.insertRow(cr.rows.length);
				row.deleteCell(0);
				var cell = row.insertCell(0);
                cell.colSpan = cr.rows[0] ? cr.rows[0].cells.length : 1;
				if (code == '001')
					cell.innerHTML = 'Некорретный формат адреса proxy сервера: ' + proxy;
				else if (code == '002')
					cell.innerHTML = 'Невозможно определить IP адрес по доменному имени: ' + proxy;
				else
					cell.innerHTML = text;

				STATUS_ERR_CNT++;
				check_proxy();

				return;
			}

			// Если получен ответ о проверке
			//var row = cr.insertRow(cr.rows.length);
			row.deleteCell(0);
			var cell = row.insertCell(0);
			
			var to = 6 - prot.length;
			for (var i = 0; i < to; i++)
				prot = '&nbsp;' + prot;
			
			cell.innerHTML = '<span class="small"><code>' + prot + '://' + ip + ':' + port + '</code></span>';
			cell = row.insertCell(1);
			cell.innerHTML = '<span class="small">' + name + '</span>';
			cell = row.insertCell(2);
			if (ok_node)
			{
				cell.innerHTML = 'http ok';
			
				if (xfwd_for == 0 && http_via == 0)
					cell.innerHTML = 'http elite';
				else if (xfwd_for == 0 || xfwd_for == 1)
					cell.innerHTML = 'http anonymous';
				
				if (prot.match('^socks5'))
					cell.innerHTML = 'socks5 ok';
				
				STATUS_OK_CNT++;			
			}
			else
			{
				cell.innerHTML = 'error';
				STATUS_ERR_CNT++;			
			}
			cell = row.insertCell(3);
			cell.innerHTML = wait;

			check_proxy();
		}
	};
			
	// Открыть соединение с сервером
	xmlHttp.open("GET", url, true);

	// Передать запрос
	xmlHttp.send(null);
}

function clear_results_table()
{
	var cr = document.getElementById("check_results");
	while (cr.rows.length != 1)
		cr.deleteRow(1);

	cr.style.display = 'block';
	
	var status_header = document.getElementById('status_header');
	if (status_header)
		status_header.className = 'theader';
		
	var time_header = document.getElementById('time_header');
	if (time_header)
		time_header.className = 'theader';

	STATUS_OK_CNT = 0;
	STATUS_ERR_CNT = 0;
	
	lock_sort();
}


