
/* Valid border codes: ("sloppy" is same as "black_sloppy")
 * Bleed, White_Sloppy, Thin_White, Thick_White, White_Keyline, 
 * Black_Sloppy, Thin_Black, Thick_Black, Black_Keyline, 
 * Art_Proof_Bleed_White, Art_Proof_Black, Art_Proof_Bleed_Black, Art_Proof_White, Sloppy
 */

function BorderManager(borderThickness){
	try{
		this.borderFiles = new Object();
		this.borderThickness = borderThickness;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BorderManager]</B> ' + e + '</FONT>' ); return false; } 
}


BorderManager.prototype.addBorder = function(id, fileName, width, height){
	try{
		if ( !this.borderFiles[id] )
			this.borderFiles[id] = new Array();
		this.borderFiles[id].push(new BorderInfo(id, fileName, width, height));
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BorderManager.addBorder]</B> ' + e + '</FONT>' ); return false; } 
}

BorderManager.prototype.getBorderObject = function( borderCode, width, height){
	try{
		switch (borderCode){
			case "Bleed": return new BleedBorder(borderCode, width, height, "black", this.borderThickness.keyline, this);
			case "Art_Proof_Bleed_White": return new SloppyBorder(borderCode, width, height, "white", this.borderThickness.sloppy, this);
			case "Art_Proof_Bleed_Black": return new SloppyBorder(borderCode, width, height, "black", this.borderThickness.sloppy, this);
			case "Art_Proof_White_Keyline": return new SloppyBorder(borderCode, width, height, "white", this.borderThickness.sloppy, this);
			case "Art_Proof_Black_Keyline": return new SloppyBorder(borderCode, width, height, "black", this.borderThickness.sloppy, this);
			case "White_Sloppy": return new SloppyBorder(borderCode, width, height, "black", this.borderThickness.sloppy, this);
			case "Thin_White": return new ThinBorder(borderCode, width, height, "white", this.borderThickness.thin, this);
			case "Thick_White": return new ThickBorder(borderCode, width, height, "white", this.borderThickness.thick, this);
			case "White_Keyline": return new KeylineBorder(borderCode, width, height, "white", this.borderThickness.keyline, this);
			case "Sloppy":
			case "Black_Sloppy": return new SloppyBorder(borderCode, width, height, "white", this.borderThickness.sloppy, this);
			case "Thin_Black": return new ThinBorder(borderCode, width, height, "black", this.borderThickness.thin, this);
			case "Thick_Black": return new ThickBorder(borderCode, width, height, "black", this.borderThickness.thick, this);
			case "Black_Keyline": return new KeylineBorder(borderCode, width, height, "black", this.borderThickness.keyline, this);
			case "Art_Proof_White": return new SloppyBorder(borderCode, width, height, "white", this.borderThickness.sloppy, this);
			case "Art_Proof_Black": return new SloppyBorder(borderCode, width, height, "black", this.borderThickness.sloppy, this);
			
			default : throw "unrecognized border ( "+borderCode+" ) exception";
		}
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BorderManager.getBorderObject]</B> ' + e + '</FONT>' ); return false; } 
}


BorderManager.prototype.getBorderFile = function(borderCode, width, height){
	try{
		//dbg.add("<FONT color='green'><b>ENTERED getBorderFile</b>"+" borderCode: "+borderCode+" width: "+width+" height: "+height+"</FONT>");
		if ( !this.borderFiles[borderCode] )
			return null;
		var sortFunction = function (borderA,borderB){
							var aW = borderA.width; var aH = borderA.height;
							var bW = borderB.width; var bH = borderB.height;
							var a = ( ( aH >= aW ) ? ( aH / aW ) : ( aW / aH ) );
							var b = ( ( bH >= bW ) ? ( bH / bW ) : ( bW / bH ) );
							return a - b;
							}
		this.borderFiles[borderCode].sort(sortFunction);
		var ratio = ( ( height >= width )  ? ( height / width ) : ( width / height ) );
		var currentRatio = 0;
		var i = 0; var lastPos = 0; var currentPos = 0;
		//dbg.add("<FONT color='green'>starting to iterate borders / ratio: "+ratio+"</FONT>");
		while ( (i < this.borderFiles[borderCode].length) && (currentRatio < ratio) ){
			var lastRatio = currentRatio;
			lastPos = currentPos;
			if ( this.borderFiles[borderCode][i].height >= this.borderFiles[borderCode][i].width )
				currentRatio = this.borderFiles[borderCode][i].height / this.borderFiles[borderCode][i].width;
			else
				currentRatio = this.borderFiles[borderCode][i].width / this.borderFiles[borderCode][i].height;
			currentPos = i;
			i++;
			//dbg.add("<FONT color='green'>iter: "+currentPos+" currentRatio: "+currentRatio+"</FONT>");
		}
		if ( Math.abs(currentRatio - ratio) <= Math.abs(ratio - lastRatio) ){
			//dbg.add("<FONT color='green'>USED RATIO: "+currentRatio+"</FONT>");
			return borderCode+ "/" +this.borderFiles[borderCode][currentPos].borderFile;
		}
		else{
			//dbg.add("<FONT color='green'>USED RATIO: "+lastRatio+"</FONT>");
			return borderCode+ "/" + this.borderFiles[borderCode][lastPos].borderFile;
		}
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BorderManager.getBorderFile]</B> ' + e + '</FONT>' ); return false; } 
}

function BorderManagerPGC(borderThickness){
	try{
		this.borderFiles = new Object();
		this.borderThickness = borderThickness;
	}
	catch(e){ return false; } 
}
BorderManagerPGC.prototype = new BorderManager;
BorderManagerPGC.prototype.constructor = BorderManagerPGC;
BorderManagerPGC.superclass = BorderManager.prototype;

BorderManagerPGC.prototype.getBorderFile = function(borderCode, width, height){
	try{
		//dbg.add("<FONT color='green'><b>ENTERED getBorderFile</b>"+" borderCode: "+borderCode+" width: "+width+" height: "+height+"</FONT>");
		if ( !this.borderFiles[borderCode] )
			return null;
		var sortFunction = function (borderA,borderB){
							var aW = borderA.width; var aH = borderA.height;
							var bW = borderB.width; var bH = borderB.height;
							var a = ( ( aH < aW ) ? ( aH / aW ) : ( aW / aH ) );
							var b = ( ( bH < bW ) ? ( bH / bW ) : ( bW / bH ) );
							return a - b;
							}
		this.borderFiles[borderCode].sort(sortFunction);
		var ratio = ( ( height < width )  ? ( height / width ) : ( width / height ) );
		var currentRatio = 0;
		var i = 0; var lastPos = 0; var currentPos = 0;
		//dbg.add("<FONT color='green'>starting to iterate borders / ratio: "+ratio+"</FONT>");
		while ( (i < this.borderFiles[borderCode].length) && (currentRatio < ratio) ){
			var lastRatio = currentRatio;
			lastPos = currentPos;
			if ( this.borderFiles[borderCode][i].height < this.borderFiles[borderCode][i].width )
				currentRatio = this.borderFiles[borderCode][i].height / this.borderFiles[borderCode][i].width;
			else
				currentRatio = this.borderFiles[borderCode][i].width / this.borderFiles[borderCode][i].height;
			currentPos = i;
			i++;
			//dbg.add("<FONT color='green'>iter: "+currentPos+" currentRatio: "+currentRatio+"</FONT>");
		}
		if ( Math.abs(currentRatio - ratio) <= Math.abs(ratio - lastRatio) ){
			//dbg.add("<FONT color='green'>USED RATIO: "+currentRatio+"</FONT>");
			return borderCode+ "/" +this.borderFiles[borderCode][currentPos].borderFile;
		}
		else{
			//dbg.add("<FONT color='green'>USED RATIO: "+lastRatio+"</FONT>");
			return borderCode+ "/" + this.borderFiles[borderCode][lastPos].borderFile;
		}
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BorderManager.getBorderFile]</B> ' + e + '</FONT>' ); return false; } 
}


function BorderInfo(borderId,borderFile, width, height){
	try{
		this.borderId = borderId;
		this.borderFile = borderFile;
		if ( height >= width ){
			this.width = width;
			this.height = height;
		}
		else{
			this.width = height;
			this.height = width;
		}
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BorderInfo]</B> ' + e + '</FONT>' ); return false; } 
}



function Border(borderCode, width, height, color, thickness, borderManager){
	try{
		if ( borderManager )
			var fileName = borderManager.getBorderFile(borderCode, width, height);
		this.init(borderCode, width, height, color, thickness, fileName);
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border]</B> ' + e + '</FONT>' ); return false; } 
}


Border.prototype.init = function(borderCode, width, height, color, thickness, fileName){
	try{
		this.borderCode = borderCode;
		this.width = width;
		this.height = height;
		this.color = color;
		this.thickness = thickness;
		this.fileName = fileName;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border.init]</B> ' + e + '</FONT>' ); return false; } 
}


Border.prototype.getColor = function(){
	try{
		return this.color;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border.getColor]</B> ' + e + '</FONT>' ); return false; } 
}

Border.prototype.getBackgroundColor = function(){
	try{
		return null;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border.getBackgroundColor]</B> ' + e + '</FONT>' ); return false; } 
}


Border.prototype.getLineWidth = function(){
	try{
		return this.thickness;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border.getLineWidth]</B> ' + e + '</FONT>' ); return false; } 
}

Border.prototype.isVisible = function(){
	try{
		return true;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border.isVisible]</B> ' + e + '</FONT>' ); return false; } 
}

Border.prototype.isFramed = function(){
	try{
		return Boolean(this.fileName);
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border.isFramed]</B> ' + e + '</FONT>' ); return false; } 
}

Border.prototype.getBorderFile = function(){
	try{
		return this.fileName;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[Border.getBorderFile]</B> ' + e + '</FONT>' ); return false; } 
}


SloppyBorder.prototype = new Border;
SloppyBorder.prototype.constructor = SloppyBorder;
SloppyBorder.superclass = Border.prototype;

function SloppyBorder(borderCode, width, height, color, thickness, borderManager){
	try{
		var fileName = borderManager.getBorderFile(borderCode, width, height);
		this.init(borderCode, width, height, color, thickness, fileName);
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[SloppyBorder]</B> ' + e + '</FONT>' ); return false; } 
}


ThinBorder.prototype = new Border;
ThinBorder.prototype.constructor = ThinBorder;
ThinBorder.superclass = Border.prototype;

function ThinBorder(borderCode, width, height, color, thickness){
	try{
		this.init(borderCode, width, height, color, thickness);
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[ThinBorder]</B> ' + e + '</FONT>' ); return false; } 
}


ThickBorder.prototype = new Border;
ThickBorder.prototype.constructor = ThickBorder;
ThickBorder.superclass = Border.prototype;

function ThickBorder(borderCode, width, height, color, thickness){
	try{
		this.init(borderCode, width, height, color, thickness);
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[ThickBorder]</B> ' + e + '</FONT>' ); return false; } 
}


BleedBorder.prototype = new Border;
BleedBorder.prototype.constructor = BleedBorder;
BleedBorder.superclass = Border.prototype;

function BleedBorder(borderCode, width, height, color, thickness){
	try{
		this.init(borderCode, width, height, color, thickness);
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BleedBorder]</B> ' + e + '</FONT>' ); return false; } 
}

BleedBorder.prototype.isVisible = function(){
	try{
		return false;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[BleedBorder.isVisible]</B> ' + e + '</FONT>' ); return false; } 
}


KeylineBorder.prototype = new Border;
KeylineBorder.prototype.constructor = KeylineBorder;
KeylineBorder.superclass = Border.prototype;

function KeylineBorder(borderCode, width, height, color, thickness){
	try{
		this.init(borderCode, width, height, color, thickness);
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[KeylineBorder]</B> ' + e + '</FONT>' ); return false; } 
}

KeylineBorder.prototype.getBackgroundColor = function(){
	try{
		if ( this.color == 'white' )
			return 'black';
		if ( this.color == 'black' )
			return 'white';
		return null;
	}
	catch(e){ dbg.add ( '<FONT COLOR="red"><B>[KeylineBorder.getBackgroundColor]</B> ' + e + '</FONT>' ); return false; } 
}

