var fs = require('fs'),

	jshint = require('jshint'),
    UglifyJS = require('uglify-js'),

	deps = require('./deps.js').deps,
	hintrc = require('./hintrc.js').config;


function lintFiles(files) {

	var errorsFound = 0,
		i, j, len, len2, src, errors, e;

	for (i = 0, len = files.length; i < len; i++) {

		jshint.JSHINT(fs.readFileSync(files[i], 'utf8'), hintrc);
		errors = jshint.JSHINT.errors;

		for (j = 0, len2 = errors.length; j < len2; j++) {
			e = errors[i];
			console.log(path + '\tline ' + e.line + '\tcol ' + e.character + '\t ' + e.reason);
		}

		errorsFound += len2;
	}

	return errorsFound;
}

function getFiles(compsBase32) {
	var memo = {},
		comps;

	if (compsBase32) {
		comps = parseInt(compsBase32, 32).toString(2).split('');
		console.log('Managing dependencies...')
	}

	function addFiles(srcs) {
		for (var j = 0, len = srcs.length; j < len; j++) {
			memo[srcs[j]] = true;
		}
	}

	for (var i in deps) {
		if (comps) {
			if (parseInt(comps.pop(), 2) === 1) {
				console.log('\t* ' + i);
				addFiles(deps[i].src);
			} else {
				console.log('\t  ' + i);
			}
		} else {
			addFiles(deps[i].src);
		}
	}

	var files = [];

	for (var src in memo) {
		files.push('src/' + src);
	}

	return files;
}

exports.lint = function () {

	var files = getFiles();

	console.log('Checking for JS errors...');

	var errorsFound = lintFiles(files);

	if (errorsFound > 0) {
		console.log(errorsFound + ' error(s) found.\n');
		fail();
	} else {
		console.log('\tCheck passed');
	}
};


function getSizeDelta(newContent, oldContent) {
	if (!oldContent) {
		return 'new';
	}
	var newLen = newContent.replace(/\r\n?/g, '\n').length,
		oldLen = oldContent.replace(/\r\n?/g, '\n').length,
		delta = newLen - oldLen;

	return (delta >= 0 ? '+' : '') + delta;
}

function loadSilently(path) {
	try {
		return fs.readFileSync(path, 'utf8');
	} catch (e) {
		return null;
	}
}

function combineFiles(files) {
	var content = '';
	for (var i = 0, len = files.length; i < len; i++) {
		content += fs.readFileSync(files[i]) + '\n\n';
	}
	return content;
}

exports.build = function (compsBase32, buildName) {

	var files = getFiles(compsBase32);

	console.log('Concatenating ' + files.length + ' files...');

	var copy = fs.readFileSync('src/copyright.js'),
		intro = '(function (window, document, undefined) {',
		outro = '}(this, document));',
	    newSrc = copy + intro + combineFiles(files) + outro,

	    pathPart = 'dist/leaflet' + (buildName ? '-' + buildName : ''),
	    srcPath = pathPart + '-src.js',

	    oldSrc = loadSilently(srcPath),
	    srcDelta = getSizeDelta(newSrc, oldSrc);

	console.log('\tUncompressed size: ' + newSrc.length + ' bytes (' + srcDelta + ')');

	if (newSrc === oldSrc) {
		console.log('\tNo changes');
	} else {
		fs.writeFileSync(srcPath, newSrc);
		console.log('\tSaved to ' + srcPath);
	}

	console.log('Compressing...');

	var path = pathPart + '.js',
	    oldCompressed = loadSilently(path),
	    newCompressed = copy + UglifyJS.minify(newSrc, {
	    	warnings: true,
	    	fromString: true
	    }).code,
	    delta = getSizeDelta(newCompressed, oldCompressed);

	console.log('\tCompressed size: ' + newCompressed.length + ' bytes (' + delta + ')');

	if (newCompressed === oldCompressed) {
		console.log('\tNo changes');
	} else {
		fs.writeFileSync(path, newCompressed);
		console.log('\tSaved to ' + path);
	}
};

@@ -17,18 +17,20 @@
 ('fs'),%0A
-%0A%09
+    
 jshint =
@@ -87,17 +87,20 @@
 -js'),%0A%0A
-%09
+    
 deps = r
@@ -125,17 +125,20 @@
 ).deps,%0A
-%09
+    
 hintrc =
@@ -223,17 +223,20 @@
 d = 0,%0A%09
-%09
+    
 i, j, le
@@ -491,20 +491,24 @@
 ole.log(
-path
+files%5Bi%5D
  + '%5Ctli
@@ -673,17 +673,20 @@
  = %7B%7D,%0A%09
-%09
+    
 comps;%0A%0A
@@ -2039,16 +2039,24 @@
 files%5Bi%5D
+, 'utf8'
 ) + '%5Cn%5C
@@ -2284,13 +2284,24 @@
 .js'
-),%0A%09%09
+, 'utf8'),%0A%09    
 intr
@@ -2350,17 +2350,20 @@
 d) %7B',%0A%09
-%09
+    
 outro = 
@@ -3032,17 +3032,20 @@
  %7B%0A%09    
-%09
+    
 warnings
@@ -3057,17 +3057,20 @@
 e,%0A%09    
-%09
+    
 fromStri

build script fixes and cleanup