// ant -f bin/tools.xml class -Dclass.includes=ext/publishing/CustomCadConvert.java

/*

site.xconf entry:

   <!-- Publishing CustomCadConvert-->
   <!-- Orginal: publish.cadconvert.PROE=com.ptc.wvs.server.publish.CadConvertPROE,useworkerdownload\=$(wt.home)$(wvs.dir.sep)auth.properties-->
   <!-- New: ext.publishing.CustomCadConvert,useworkerdownload\=$(wt.home)$(wvs.dir.sep)auth.properties-->
   <Property name="publish.cadconvert.PROE" overridable="true"
             targetFile="codebase/wvs.properties"
             value="ext.publishing.CustomCadConvert,useworkerdownload\=$(wt.home)$(wvs.dir.sep)auth.properties"/>
*/

package ext.publishing;

import java.io.*;
import java.io.File;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.*;
import java.util.*;
import org.apache.log4j.Level;

import com.infoengine.SAK.IeService;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

import com.ptc.windchill.classproxy.ILFileInfo;
import com.ptc.windchill.classproxy.ILGWProxy;
import com.ptc.wvs.common.cadagent.CadProxy;
import com.ptc.wvs.common.util.WVSProperties;
import com.ptc.wvs.server.loader.NavigationHelper;
import com.ptc.wvs.server.loader.PartGenericStructure;
import com.ptc.wvs.server.publish.CadConvert;
import com.ptc.wvs.server.publish.CadConvertACAD;
import com.ptc.wvs.server.publish.CadConvertPROE;
import com.ptc.wvs.server.publish.WVSProcessingJob;
import com.ptc.wvs.server.util.*;

import wt.content.*;
import wt.enterprise.RevisionControlled;
import wt.epm.*;
import wt.epm.build.*;
import wt.epm.structure.*;
import wt.fc.*;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.collections.*;

import wt.method.MethodContext;
import wt.query.*;
import wt.representation.*;
import wt.session.SessionManagerSvr;
import wt.session.SessionServerHelper;
import wt.util.WTStandardDateFormat;
import wt.util.*;

import wt.vc.config.*;
import wt.vc.IterationIdentifier;
import wt.vc.Mastered;
import wt.vc.VersionIdentifier;
import wt.vc.VersionControlHelper;
import wt.vc.struct.StructHelper;
import wt.vc.struct.StructService;

public class CustomCadConvert implements CadConvert {
	protected WVSProcessingJob processingJob;
	protected Representable representable;
	protected String string;
	protected CadConvert cadConverter;
	private static final long serialVersionUID = 5454066616760276474L;

	static String chkFileStg, tmpChkStg, pdfFileStg, objID, drwNmNE, drwNm;
	static String rtnStg, dlPath, dlRtgStg, pdfName, stampTxt, StStg;
	static String modDate, createdDate, revStg1st, revStg, refObjID, tmpPubPath;
	static String dtFormat = "yyyy-MM-dd HH:mm z";

	static EPMDocument epmDoc, epmDoc1st, epmDRW;
	static ConfigSpec configSpec;
	static EPMDocConfigSpec wsConfigSpec;
	static QueryResult navRefQR, refQR, depQR;
	static File finalPdfFileName;

	public void setCadConvertObject(EPMDocument document) {
		if(document.getAuthoringApplication().toString().equals("PROE")) { cadConverter = new CadConvertPROE(); }
	}

	public int storeDrawingRepresentation(boolean paramBoolean, File paramFile) {
		System.out.println("paramFile.getAbsolutePath(): " + paramFile.getAbsolutePath());

		configSpec = new LatestConfigSpec();
		drwNm = getDrawingName();
		int lastPeriodPos = drwNm.lastIndexOf(".");
        drwNmNE = drwNm.substring(0, lastPeriodPos);

		File[] filesStoredFolder = paramFile.listFiles();

		try {
			for (int in2 = 0; in2 < filesStoredFolder.length; in2++) {
				chkFileStg = filesStoredFolder[in2].toString();
				if ( chkFileStg.indexOf(drwNmNE) > 0 && chkFileStg.indexOf("drw") > 0 && chkFileStg.endsWith(".pdf") ) {
					System.out.println("Found Match with "+ filesStoredFolder[in2].toString() +" & "+chkFileStg);

					revStg = epmDRW.getVersionIdentifier().getValue();
					StStg = epmDRW.getLifeCycleState().getDisplay();
					//createdDate = String.valueOf(epmDRW.getCreateTimestamp());
					//createdDate = WTStandardDateFormat.format(epmDRW.getCreateTimestamp(), 3, Locale.getDefault(), WTContext.getContext().getTimeZone());
					createdDate = WTStandardDateFormat.format(epmDRW.getCreateTimestamp(), dtFormat);
					stampTxt = "Created On: "+createdDate+"  +++  Rev.: "+revStg+"  +++  State: "+StStg;

					System.out.println( "\nBEF(Parent DRW): epmDRW - Number: " + epmDRW.getNumber() + " - ID: "+PersistenceHelper.getObjectIdentifier(epmDRW).toString());
					System.out.println( " -Version: " + epmDRW.getVersionIdentifier().getValue() + " - Iteration:"+epmDRW.getIterationIdentifier().getValue());
					System.out.println( "DRW stampTxt: "+stampTxt);

					navRefQR = EPMStructureHelper.service.navigateReferencesToIteration(epmDRW, null, false, configSpec);
					while(navRefQR.hasMoreElements()) {
						if(!navRefQR.hasMoreElements())
							break;

						Persistable apersistable[] = (wt.fc.Persistable[])navRefQR.nextElement();
						Persistable persistable0 = apersistable[0];
						Persistable persistable1 = apersistable[1];

						if((persistable0 instanceof EPMDependencyLink) && (persistable1 instanceof EPMDocument)) {
							EPMDependencyLink epmDepLink = (EPMDependencyLink)persistable0;

							if( epmDepLink.getDepType() == 4 ) {
								epmDoc = (EPMDocument)persistable1;
								System.out.println( "EPMDoc.getNumber() "+epmDoc.getNumber()+" - epmDepLink.getDepType(): "+epmDepLink.getDepType());
								System.out.println( " -Version: " + epmDoc.getVersionIdentifier().getValue() + " - Iteration:"+epmDoc.getIterationIdentifier().getValue());
								finalPdfFileName = filesStoredFolder[in2];
							}
						}
						else if((persistable0 instanceof EPMReferenceLink) && (persistable1 instanceof EPMDocument)) {
							EPMReferenceLink reflink = (EPMReferenceLink)persistable0;

							if ( reflink.getDepType() == 4 ) {
								epmDoc = (EPMDocument)persistable1;
								System.out.println( "EPMDoc.getNumber() "+epmDoc.getNumber()+" - reflink.getDepType(): "+reflink.getDepType());
								System.out.println( " -Version: " + epmDoc.getVersionIdentifier().getValue() + " - Iteration:"+epmDoc.getIterationIdentifier().getValue());
								finalPdfFileName = filesStoredFolder[in2];
							}
						} // end if & else if
					} // end of while query loop

					// original pdf path\original <file name>pdf
					int lastPeriodPos2 = chkFileStg.lastIndexOf("\\");
					pdfFileStg = chkFileStg.substring(lastPeriodPos2+1,chkFileStg.length());
					break;
				} // end if
			} // end of for loop

			revStg = epmDoc.getVersionIdentifier().getValue();
			StStg = epmDoc.getLifeCycleState().getDisplay();
			createdDate = WTStandardDateFormat.format(epmDoc.getCreateTimestamp(), dtFormat);
			stampTxt = "Created On: "+createdDate+"  +++  Rev.: "+revStg+"  +++  State: "+StStg;

			System.out.println( "\nAFT(Child Model):=======================\nEPMDoc - Number: " + epmDoc.getNumber() + "  - ID: "+PersistenceHelper.getObjectIdentifier(epmDoc).toString());
			System.out.println( " -Version: " + epmDoc.getVersionIdentifier().getValue() + " - Iteration:"+epmDoc.getIterationIdentifier().getValue());
			System.out.println( "Initial stampTxt: "+stampTxt);

			QueryResult qr = VersionControlHelper.service.allIterationsOf(epmDoc.getMaster());
			while (qr.hasMoreElements()) {
				epmDoc1st = null;
				epmDoc1st = (EPMDocument)qr.nextElement();
				boolean is1st = VersionControlHelper.service.isFirstIteration(epmDoc1st);

				revStg1st = epmDoc1st.getVersionIdentifier().getValue();
				StStg = epmDoc1st.getLifeCycleState().getDisplay();
				createdDate = WTStandardDateFormat.format(epmDoc1st.getCreateTimestamp(), dtFormat);

				System.out.println( "\nLoop = EPMDoc - Number: " + epmDoc1st.getNumber() + " - ID: "+PersistenceHelper.getObjectIdentifier(epmDoc1st).toString());
				System.out.println( " -Version: " + revStg1st + " -Iteration: "+epmDoc1st.getIterationIdentifier().getValue()+ " - ID: "+PersistenceHelper.getObjectIdentifier(epmDoc1st).toString());

				if (is1st && revStg1st.equals(revStg)) {
					stampTxt = "Created On: "+createdDate+"  +++  Rev.: "+revStg1st+"  +++  State: "+StStg;
					System.out.println( "Final: stampTxt: "+stampTxt);
					break;
				}
			} // end of query loop

			File Tmp_dlFile = new File(paramFile.getAbsolutePath()+"\\"+"Tmp_"+pdfFileStg);
			copyFile(finalPdfFileName,Tmp_dlFile);

			System.out.println( "Copied "+ finalPdfFileName.toString()+"\n to "+ Tmp_dlFile.toString());

			PdfReader reader = new PdfReader(finalPdfFileName.toString());

			int n = reader.getNumberOfPages();
			System.out.println("***Number of pages in reader are: " + n);

			// we create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(Tmp_dlFile));
			int i = 0;
			PdfContentByte over;
			BaseFont bf = BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
			PdfGState gstate = new PdfGState();
			float opacity = 0.90f;
			gstate.setFillOpacity(opacity);
			gstate.setStrokeOpacity(opacity);

			while (i < n) {
				System.out.println("***Got IN Watermark Loop");
				i++;
				Rectangle rect = reader.getCropBox(i);
				float right = rect.getRight();
				float bottom = rect.getBottom();

				System.out.println("***Page :" + i + " of " + n + ",  left : " + right + " bottom : " + bottom);
				over = stamp.getOverContent(i);
				over.saveState();
				over.setGState(gstate);
				over.setColorFill(BaseColor.BLACK);
				over.beginText();
				over.setFontAndSize(bf, 10);
				over.setTextMatrix(30, 10);
				over.showTextAligned(Element.ALIGN_RIGHT, stampTxt, (right - 30) , (bottom + 7) , 0);
				over.endText();
			}

			// closing stamp & reader will generate the new PDF file
			stamp.close();
			reader.close();

			// copy Tmp_<file name>.pdf to <file name>.pdf
			copyFile(Tmp_dlFile,finalPdfFileName);
			System.out.println( "Copied "+Tmp_dlFile.toString()+"(After watermarking)\n to "+ finalPdfFileName.toString());

			if (Tmp_dlFile.exists()) { Tmp_dlFile.delete(); }
		}
		catch(IOException exc) { System.out.println("IOException (ext.publishing.CustomCadConvert.storeDrawingRepresentation()): "+exc.toString()); }
		catch(WTException wtexc) { System.out.println("WTException (ext.publishing.CustomCadConvert.storeDrawingRepresentation()): "+wtexc.toString()); }
		catch(com.itextpdf.text.DocumentException dexc) { System.out.println("DocumentException (ext.publishing.CustomCadConvert.storeDrawingRepresentation()): "+dexc.toString()); }

		return cadConverter.storeDrawingRepresentation(paramBoolean, paramFile);
	} // end of store DRW

	public String getAuthenticationString(URLData paramURLData) {
		return cadConverter.getAuthenticationString(paramURLData);
	}

	public boolean getLocalFileContentFromContentItem(ContentItem paramContentItem, File paramFile) {
		return cadConverter.getLocalFileContentFromContentItem(paramContentItem, paramFile);
	}

	public String getLocalFileNameFromContentItem(ContentItem paramContentItem) {
		return cadConverter.getLocalFileNameFromContentItem(paramContentItem);
	}

	public URLConnection getURLDataConnection(URLData paramURLData) {
		return cadConverter.getURLDataConnection(paramURLData);
	}

	public boolean useDistributedCadAgent(String paramString) {
		return cadConverter.useDistributedCadAgent(paramString);
	}

	public String doAssemblyConversion(boolean paramBoolean1, boolean paramBoolean2, int paramInt) {
		return cadConverter.doAssemblyConversion(paramBoolean1, paramBoolean2, paramInt);
	}

	public String doComponentConversion(boolean paramBoolean, int paramInt) {
		return cadConverter.doComponentConversion(paramBoolean, paramInt);
	}

	public String doDrawingConversion(boolean paramBoolean, int paramInt) {
		return cadConverter.doDrawingConversion(paramBoolean, paramInt);
	}

	public int getAssemblyContent(boolean paramBoolean1, boolean paramBoolean2) {
		return cadConverter.getAssemblyContent(paramBoolean1, paramBoolean2);
	}

	public String getAssemblyName() {
		return cadConverter.getAssemblyName();
	}

	public int getAssemblyType() {
		return cadConverter.getAssemblyType();
	}

	public int getComponentContent(boolean paramBoolean) {
		return cadConverter.getComponentContent(paramBoolean);
	}

	public String getComponentName() {
		return cadConverter.getComponentName();
	}

	public int getDrawingContent(boolean paramBoolean) {
		return cadConverter.getDrawingContent(paramBoolean);
	}

	public String getDrawingName() {
		return cadConverter.getDrawingName();
	}

	public int getType(boolean paramBoolean, boolean paramBoolean2) {
		return cadConverter.getType(paramBoolean, paramBoolean2);
	}

	public boolean init(WVSProcessingJob paramProcessingJob, EPMDocument paramEPMDocument, Representable paramRepresentable, String paramString) {
		this.processingJob = paramProcessingJob;
		this.epmDRW = paramEPMDocument;
		this.representable = paramRepresentable;
		this.string = paramString;
		setCadConvertObject(epmDRW);

		return cadConverter.init(paramProcessingJob, paramEPMDocument, paramRepresentable, paramString);
	}

	public int storeAssemblyRepresentation(boolean paramBoolean1, boolean paramBoolean2, File paramFile) {
		return cadConverter.storeAssemblyRepresentation(paramBoolean1, paramBoolean2, paramFile);
	}

	public int storeComponentRepresentation(boolean paramBoolean, File paramFile) {
		return cadConverter.storeComponentRepresentation(paramBoolean, paramFile);
	}

	public static void copyFile(File sourceFile, File destFile) throws IOException {
		FileChannel source = null;
		FileChannel destination = null;

		try {
			source = new FileInputStream(sourceFile).getChannel();
			destination = new FileOutputStream(destFile).getChannel();
			destination.transferFrom(source, 0, source.size());
		}
		finally {
			if(source != null) {
				source.close();
			}
			if(destination != null) {
				destination.close();
			}
		}
	}
}
