/*
    Клиентский код HTTP заливки для всех проектов
    Специально для сервера acuploader
    Имена функций переделаны, чтобы не конфликтовать с jQuery
    author: AterCattus
*/

function ac_$( id ) {
	return document.getElementById( id );
}

function ac_$$( tagName ) {
	return document.getElementsByTagName( tagName );
}

function ac_get_xhr() {
	// http://www.codenet.ru/webmast/js/XDomainRequest.php
	// http://www.w3.org/TR/cors/

	if ( typeof ActiveXObject != 'undefined' ) {
		try {
			return new ActiveXObject( 'Msxml2.XMLHTTP' );
		}
		catch (e) {
			try {
				return new ActiveXObject( 'Microsoft.XMLHTTP' );
			}
			catch (e) {}
		}
	}
	if ( typeof XMLHttpRequest != 'undefined' ) {
		try {
			return new XMLHttpRequest();
		}
		catch (e) {}
	}
	return false;
}

function ac_ajax( url, callback_func ) {
	var req = ac_get_xhr();
	if ( !req ) { alert( 'No XMLHttpRequest' ); return false; }

	req.open( "GET", url, true );
	req.setRequestHeader( 'If-Modified-Since', "Sat, 1 Jan 2000 00:00:00 GMT" );

	req.onreadystatechange = function() {
	try {
		if (req.readyState == 4) {
			clearTimeout( acupl_timeoutID );
			callback_func( req.responseText, req.status, req.statusText );
		}
	}
	catch( e ) {}
	};

	req.send( null );

	var acupl_timeoutID = setTimeout( function() { req.abort(); callback_func( '', 408, 'Request Timeout' ) }, 10000 );
}

var acupl_statusTimeoutId = 0;
var acupl_UID = 0;

function upload_status_update_setup() {
	var loc = document.location.toString();
	var pos = loc.indexOf( '?' );
	if ( pos == -1 ) return false; // нету UID
	loc = loc.substr( pos+1 );

	loc = loc.split( '&' );
	for ( var i in loc ) {
		var param = loc[i].split( '=' );
		if ( param[0] == 'uid' ) {
			ac_UID = ( typeof param[1] == 'string' ) ? parseInt( param[1] ) : 0;
			break;
		}
	}

	if ( !ac_UID ) return false; // нету UID

	// запускаю обновление статусов
	upload_status_update();
}

function size2str( size ) {
	// проще конечно с десятичным логарифмом....
	if ( size < 1024*1024 ) size = Math.floor( size/1024 * 100)/100 + 'KB';
	else if ( size < 1024*1024*1024 ) size = Math.floor( size/1024/1024 * 100)/100 + 'MB';
	else size = Math.floor( size/1024/1024/1024 * 100)/100 + 'GB';
	return size;
}

function speed2str( speed ) {
	speed = Math.max( 0, speed );
	if ( speed < 1024 ) speed = speed+'B/s';
	else if ( speed < 1024*1024 ) speed = Math.floor( speed/1024 * 10)/10 + 'KB/s';
	else speed = Math.floor( speed/1024/1024 * 10)/10 + 'MB/s';
	return speed;
}

function time2str( time ) {
	time = Math.max( 0, time );
	if ( time < 60 ) time = time+'s';
	else if ( time < 3600 ) time = Math.ceil( time/60 )+'m '+( time%60 )+'s';
	else time = Math.ceil( time/3600 ) + 'h ' + Math.ceil( (time%3600)/60 )+'m '+( time%60 )+'s';
	return time;
}

function upload_update_stats( stats ) {
	// ужасный код, надо переделать
	if (	(typeof stats.recv_len == 'undefined') ||
			(typeof stats.cont_len == 'undefined') ||
			(typeof stats.now_time == 'undefined') ||
			(typeof stats.start_time == 'undefined') ||
			(typeof stats.filename == 'undefined')  ) return false;

	stats.recv_len = parseInt(stats.recv_len);
	stats.cont_len = parseInt(stats.cont_len);
	stats.recv_len = Math.min(stats.recv_len, stats.cont_len);
	stats.now_time = parseInt(stats.now_time);
	stats.start_time = parseInt(stats.start_time);
	stats.filename = stats.filename.toString().replace(/</g, '&lt;').replace(/>/g, '&gt;');

	ac_$('s_uploaded').innerHTML = size2str( stats.recv_len );
	ac_$('s_total').innerHTML = size2str( stats.cont_len );

	//ac_$('s_time_elapsed').innerHTML = stats.dtime;

	var elaps_time = stats.now_time - stats.start_time;

	var speed = elaps_time ? parseInt( stats.recv_len / elaps_time ) : 0;
	ac_$('s_speed').innerHTML = speed2str( speed );

	var tleft = ( elaps_time && stats.recv_len ) ? parseInt( elaps_time * ( stats.cont_len / stats.recv_len - 1 ) ) : 0;
	if ( tleft < 0 ) tleft = 0;
	ac_$('s_time_left').innerHTML = time2str( tleft );

	// min(100, .. ) из-за того, что сервер считает в общем трафике еще и все заголовки
	var perc = Math.min( 100, Math.ceil( stats.recv_len * 100 / stats.cont_len ) );
	ac_$('progress').style.width = perc+'%';
	ac_$('progress').innerHTML = perc+'%';

	ac_$('s_fname').innerHTML = stats.filename;

	return true;
}

function upload_status_update() {
	if ( acupl_statusTimeoutId ) { clearTimeout( acupl_statusTimeoutId ); acupl_statusTimeoutId = 0; }

	// пока через банальный php-прокси
	ac_ajax( 'http://'+document.location.host+'/acupl_proxy.php?srv='+ACUPL_UPLOAD_SERVER+'&uid='+acupl_UID,
		function( text, statusCode, statusText ) {
			if ( statusCode == 200 ) {
				try {
					eval( 'var stats = '+text );
					if ( typeof stats == 'object' && typeof stats.code != 'undefined' ) {
						if ( ( stats.code == 200 ) && ( typeof stats.link != 'undefined' ) ) {
							if ( stats.link.toString().indexOf( 'http://' ) == 0 ) {
								document.location.replace( stats.link );
								return; // DONE
							}
							else {
								// больше не нужно :)
								//alert( 'Bad answer: ['+stats.link.toString()+']; Full answer: ['+text+']' );
							}
						}
						else {
							upload_update_stats( stats );
						}
					}
					else {
						// полный бред пришел
					}
				} catch (e) {
					// полный бред пришел
				}
			}

			// вновь задаю обработчик
			acupl_statusTimeoutId = setTimeout( 'upload_status_update();', 1000 );
		}
	);
}

function ac_do_submit() {
	// проверка, что хоть какие-то файлы есть на заливку
	var files = ac_$$( 'input' );
	var to_delete = new Array();
	var files_count = 0;
	for ( var i=0; i<files.length; i++ ) {
		if ( files[i].type != 'file' ) continue;
		++files_count;
		if ( !files[i].value.length ) {
			to_delete.push( files[i] );
		}
	}

	if ( to_delete.length == files_count ) {
		alert( sNoFiles ); // текст зависит от перевода
		return false;
	}

	// удаляю поля, в которых нет файлов (небольшая оптимизация)
	for ( var i=0; i<to_delete.length; i++ ) {
		var node = to_delete[i];
		// вместе с полем прибиваю и <br> за ним
		var next = node.nextSibling;
		if ( typeof next == 'object' && next.tagName.toUpperCase() == 'BR' )
			next.parentNode.removeChild( next );
		// прибиваю само поле
		node.parentNode.removeChild( node );
	}

	// генерация случайного UID, не кореллирующего с IP
	acupl_UID = (new Date()).getTime().toString(16).toUpperCase() +
			Math.round( Math.random()*1000000000 ).toString(16).toUpperCase();

	// коррекция action формы заливки
	if ( typeof ACUPL_UPLOAD_SERVER == 'undefined' ) ACUPL_UPLOAD_SERVER = 'http'+parseInt(Math.random()*20+1)+'.letitbit.net:8442';
	ac_$('upload_form').action = 'http://'+ACUPL_UPLOAD_SERVER+'/'+acupl_UID;

	// активирую блок статистики заливки
	ac_$('upload_form').style.display = 'none';
	ac_$('stats_outer').style.display = 'block';

	upload_status_update();

	return true;
}

function upload_file_list_resize( how_much ) {
	if ( !how_much ) return;

	var now_max = 0;
	var now_count = 0;
	var arr = ac_$$( 'input' );
	for ( var i=0; i < arr.length; i++ ) {
		if ( arr[i].type != 'file' ) continue;
		if ( arr[i].name.substr(0,4) != 'file' ) continue;
		var num = parseInt( arr[i].name.substr(4) );
		if (now_max<num) now_max = num;
		now_count++;
	}

	if ( how_much > 0 ) {
		if ( now_count >= 10 ) {
			//alert( sTooMuch ); // текст зависит от перевода
			return;
		}

		how_much = Math.min( 10-now_count, how_much );
		var list = ac_$('fileX_list');

		while ( how_much-- > 0 ) {
			// добавляю <input...><br>
			var input = document.createElement( 'input' );
			input.type = 'file';
			input.size = 40;
			input.name = 'file'+(++now_max);
			input.className = 'input_file';
			list.appendChild( input );
			var br = document.createElement( 'br' );
			list.appendChild( br );
		}
	}
	else {
		how_much = Math.min( -how_much, now_count-1 );
		while ( how_much-- ) {
			var node = null;
			while ( 1 ) {
				var nodes = document.getElementsByName( 'file'+now_max );
				if ( !nodes.length ) {
					if ( now_max ) {
					--now_max;
					continue;
					}
					else break; // нету больше вариантов
				}
				else {
					node = nodes[0];
					break;
				}
			}

			if ( node != null ) {
				// вместе с полем прибиваю и <br> за ним
				var next = node.nextSibling;
				if ( typeof next == 'object' && next.tagName.toUpperCase() == 'BR' )
					next.parentNode.removeChild( next );
				// прибиваю само поле
				node.parentNode.removeChild( node );
			}
			else break;
		}
	}
}
