Item.prototype.getCompoundArea = function(area) {
	if (!area) area = 0;
	if (this instanceof Path) return area + this.area;
	else if (this instanceof CompoundPath || this instanceof Group) {
		var child = this.firstChild;
		while (child) {
			area = child.getCompoundArea(area);
			child = child.nextSibling;
		}
	}
	return area;
};

var values = {
	sqGrid: true,
	vertGridSpc: 0,
	horizGridSpc: 0,
	clearWhite: false,
	invert: false,
	source: 'Hide',
	sourceVectors: 'Leave'
};

var components = {
	sqGrid: {
		type: 'checkbox',
		label: 'Use square grid'
	},
	vertGridSpc: {
		type: 'number',
		label: 'Vertical grid gutter',
		units: 'point'
	},
	horizGridSpc: {
		type: 'number',
		label: 'Horizontal grid gutter',
		units: 'point'
	},
	ruler: {
		type: 'ruler'
	},
	clearWhite: {
		type: 'checkbox',
		label: 'Keep white areas clear'
	},
	invert: {
		type: 'checkbox',
		label: 'Invert tones'
	},
	source: {
		type: 'list',
		label: 'Source images',
		options: ['Leave', 'Hide', 'Delete']
	},
	sourceVectors: {
		type: 'list',
		label: 'Source vectors',
		options: ['Leave', 'Hide', 'Delete']
	},
	ruler2: {
		type: 'ruler'
	},
	button: {
		type: 'button',
		value: 'Create',
		onClick: function(){
			var gridSize;
			var colours = [];
			var paths = document.getItems({
			    type: [Path, CompoundPath],
			    selected: true
			});
			var myImages = document.getItems({
				type: Raster,
				selected: true
			});

			if(paths.length > 0 && myImages.length > 0){
				var maxWidth = 0;
				var maxHeight = 0;
				for(i = 0; i < paths.length; i++){
					if(paths[i].bounds.width > maxWidth){
						maxWidth = paths[i].bounds.width;
					}
					if(paths[i].bounds.height > maxHeight){
						maxHeight = paths[i].bounds.height;
					}
				}
				if(values.sqGrid){
					gridSize = new Size(Math.max(maxWidth, maxHeight) + values.horizGridSpc, Math.max(maxWidth, maxHeight) + values.vertGridSpc);
				}else{
					gridSize = new Size(maxWidth + values.horizGridSpc, maxHeight + values.vertGridSpc);
				}
				for(i = 0; i < paths.length; i++){
					colours.push(paths[i].getCompoundArea());
				}
				var maxGray = Math.max.apply(null, colours);
				var minGray = Math.min.apply(null, colours);

				for(i = 0; i < colours.length; i++){
					colours[i] = colours[i] * (1 / maxGray);
				}
				for(m = 0; m < myImages.length; m++){
					var myPaths = [];
					for(i = 0; i < Math.floor(myImages[m].bounds.height / gridSize.height); i++){
						for(j = 0; j < Math.floor(myImages[m].bounds.width / gridSize.width); j++){
							var myFrame = new Path.Rectangle(new Point(myImages[m].bounds.left + j * gridSize.width, myImages[m].bounds.top + i * gridSize.height), gridSize);
							var myCheckColour = myImages[m].getAverageColor(myFrame);
							myCheckColour.convert('gray');
							if(((myImages[m].type != 'gray' && myImages[m].type != 'agray') && values.invert) || ((myImages[m].type == 'gray' || myImages[m].type == 'agray') && !values.invert)){
								myCheckColour.gray = 1 - myCheckColour.gray;
							}
							if(!values.clearWhite || myCheckColour.gray > minGray / 2){
								var myDifference = 1;
								var myColourRef;
								for(k = 0; k < colours.length; k++){
									var grayDifference = Math.abs(myCheckColour.gray - colours[k]);
									if(grayDifference < myDifference){
										myDifference = grayDifference;
										myColourRef = k;
									}
								}
								var newPath = paths[myColourRef].clone();
								newPath.position = myFrame.position;
								myPaths.push(newPath);
							}
							myFrame.remove();
						}
					}
					var pathGroup = new Group(myPaths);
					if(values.source == 'Hide'){
						myImages[m].visible = false;
					}else if(values.source == 'Delete'){
						myImages[m].remove();
					}
				}
				if(values.sourceVectors == 'Hide'){
					for(i = 0; i < paths.length; i++){
						paths[i].visible = false;
					}
				}else if(values.sourceVectors == 'Delete'){
					for(i = 0; i < paths.length; i++){
						paths[i].remove();
					}
				}
			}else{
				Dialog.alert('Please select paths and raster images');
			}
		}
	}
};

var palette = new Palette('Vector Pixels', components, values);