function OffsetPathModifier(){
}
extendPrototype([ShapeModifier], OffsetPathModifier);

OffsetPathModifier.prototype.initModifierProperties = function(elem, data) {
    this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
    this.lineJoin = data.lj;
    this.getValue = this.processKeys;
};

OffsetPathModifier.prototype.addPathToCommands = function(path, transformers, level, commands) {
	var i, len = path._length;
	var pt1, pt2, pt3;
	pt1 = this.transformPoint(path.v[0], transformers, level);
	commands.push([Module.MOVE_VERB, pt1[0], pt1[1]]);
	for(i = 0; i < len - 1; i += 1) {
		pt1 = this.transformPoint(path.o[i], transformers, level);
		pt2 = this.transformPoint(path.i[i + 1], transformers, level);
		pt3 = this.transformPoint(path.v[i + 1], transformers, level);
		commands.push([Module.CUBIC_VERB, pt1[0], pt1[1], pt2[0], pt2[1], pt3[0], pt3[1]]);
	}
	if(path.c) {
		pt1 = this.transformPoint(path.o[len - 1], transformers, level);
		pt2 = this.transformPoint(path.i[0], transformers, level);
		pt3 = this.transformPoint(path.v[0], transformers, level);
		commands.push([Module.CUBIC_VERB, pt1[0], pt1[1], pt2[0], pt2[1], pt3[0], pt3[1]]);
		commands.push([Module.CLOSE_VERB]);
	}
}

OffsetPathModifier.prototype.transformPoint = function(point, transformers, level) {
	var matrix;

    var iterations = level - this.level;
    var k = transformers.length-1;

    while(iterations) {
		matrix = transformers[k].mProps.v;
		point = matrix.applyToPointArray(point[0], point[1], 0);
        iterations --;
        k --;
    }
	return point;
}

OffsetPathModifier.prototype.addShapeToCommands = function(shape, transformers, level, commands) {
	var i, len = shape.paths._length;
	for(i = 0; i < len; i += 1) {
		this.addPathToCommands(shape.paths.shapes[i], transformers, level, commands);
	}
}

OffsetPathModifier.prototype.removeInnerShape = function(commands) {
	var i = 0, len = commands.length;
	while(false && i < len) {
		if(commands[i][0] === 5) {
			commands.length = i + 1;
			break;
		}
		i += 1;
	}
	return commands;
}

OffsetPathModifier.prototype.processShapes = function(_isFirstFrame) {
    var shapePaths;
    var i, len = this.shapes.length;
    var amount = this.amount.v;
    if(amount === 0){
		return;
    }
	var commands = [];
	var skPath, offsettedSkPath;

	for(i = 0; i < len; i += 1) {
		shapeData = this.shapes[i];
		if(!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)){
			shape = shapeData.shape;
			commands.length = 0;
			this.addShapeToCommands(shape, shapeData.data.transformers, shapeData.data.lvl, commands);

			skPath = skpaths_factory.createFromCommands(commands);
			if(amount < 0) {
				skPath = skPath.opAndReplace(Module.PathOp.UNION);
				// skPath = skpaths_factory.replaceFromBooleanOperation(skPath, skPath, Module.PathOp.UNION);
			}
			var joinType, strokeCap;
			switch(this.lineJoin) {
				case 2:
				joinType = Module.StrokeJoin.ROUND;
				strokeCap = Module.StrokeCap.ROUND;
				break;
				default: 
				joinType = Module.StrokeJoin.MITER;
				strokeCap = Module.StrokeCap.BUTT;
				break;
			}
			if(commands[commands.length - 1][0] === 5) {
				offsettedSkPath = skPath.stroke(Math.abs(amount) * 2, joinType, strokeCap);
				let operation = amount < 0 ? Module.PathOp.REVERSE_DIFFERENCE : Module.PathOp.UNION;
				skPath = offsettedSkPath
					.opAndReplace(operation, skPath)
					.simplifyAndReplace();
			} else {
				skPath = skPath
				.strokeAndReplace(Math.abs(amount) * 2, joinType, strokeCap)
				// .opAndReplace(Module.PathOp.UNION)
				.setFillType(Module.FillType.EVENODD)
				.simplifyAndReplace();
			}
		  	commands = skPath.toCmds();
		  	// commands.length = 44;
			//skPath.destroy();
	        localShapeCollection = shapeData.localShapeCollection;
	        localShapeCollection.releaseShapes();
	        localShapeCollection = this.createPathFromCommands(commands, localShapeCollection);
	        shapeData.shape._mdf = true;
		}
        shapeData.shape.paths = shapeData.localShapeCollection;
	}

    if(!this.dynamicProperties.length){
        this._mdf = false;
    }
};

OffsetPathModifier.prototype.createPathFromCommands = function(commands, localShapeCollection) {

	var i, len;
  	var i, len = commands.length;
  	var new_path;
  	var node_index = 0;
	var hasClosedPath = false;
	var command, prev_command;
  	for(i = 0; i < len; i += 1) {
  		command = commands[i];
  		if(command[0] === 0) {
  			if(new_path) {
  				if(!hasClosedPath) {
  					prev_command = commands[i - 1];
					new_path.setXYAt(prev_command[prev_command.length - 2], prev_command[prev_command.length - 1], 'o', new_path._length - 1, false);
  				}
  				localShapeCollection.addShape(new_path);
  			}
			hasClosedPath = false;
  			node_index = 0;
			new_path = shape_pool.newElement();
			new_path.setXYAt(command[1], command[2], 'v', node_index, false);
			new_path.setXYAt(command[1], command[2], 'i', node_index, false);
			node_index += 1;
  		} else if(command[0] === 1) {
			prev_command = commands[i - 1];
			new_path.setXYAt(command[1], command[2], 'v', node_index, false);
			new_path.setXYAt(prev_command[prev_command.length - 2], prev_command[prev_command.length - 1], 'o',node_index - 1, false);
			new_path.setXYAt(command[1], command[2], 'i', node_index, false);
			node_index += 1;
  		} else if(command[0] === 2) {
			prev_command = commands[i - 1];
			new_path.setXYAt(command[3], command[4], 'v', node_index, false);
			var cp1_x = prev_command[prev_command.length - 2] + 2 / 3 * (command[1] - prev_command[prev_command.length - 2])
			var cp1_y = prev_command[prev_command.length - 1] + 2 / 3 * (command[2] - prev_command[prev_command.length - 1])
			var cp2_x = command[3] + 2 / 3 * (command[1] - command[3])
			var cp2_y = command[4] + 2 / 3 * (command[2] - command[4])

			new_path.setXYAt(cp1_x, cp1_y, 'o',node_index - 1, false);
			new_path.setXYAt(cp2_x, cp2_y, 'i', node_index, false);
			node_index += 1;
  		} else if(command[0] === 4) {
			new_path.setXYAt(command[5], command[6], 'v', node_index, false);
			new_path.setXYAt(command[1], command[2], 'o', node_index - 1, false);
			new_path.setXYAt(command[3], command[4], 'i', node_index, false);
			node_index += 1;
  		} else if(command[0] === 5) {
			prev_command = commands[i - 1];
			new_path.c = true;
			new_path.setXYAt(prev_command[prev_command.length - 2], prev_command[prev_command.length - 1], 'o', node_index - 1, false);
			node_index += 1;
			hasClosedPath = true;
  		}
  	}
	if(new_path) {
		if(!hasClosedPath) {
			prev_command = commands[i - 1];
			new_path.setXYAt(prev_command[prev_command.length - 2], prev_command[prev_command.length - 1], 'o', new_path._length - 1, false);
		}
		localShapeCollection.addShape(new_path);
	}
	return localShapeCollection;
}

ShapeModifiers.registerModifier('op', OffsetPathModifier);