//
//  GeneratePdf.m
//
//  Created by AIG-Soft on 2011/04/05.
//  Copyright 2011 AIG-Soft. All rights reserved.
//
// from DrawingPrintingiOS.pdf;ただし、バグがあるので修正

#import "GeneratePdf.h"
#import "SnapShot.h"
#import <CoreText/CoreText.h>	// CoreText.frameworkが必要
#import "libs.h"

@implementation GeneratePdf

// CoreTextを使用して、ページ上のフレームにテキストを描画する
- (CFRange)renderPage:(CFRange)currentRange andFramesetter:(CTFramesetterRef)framesetter
{
	// グラフィックスコンテキストを取得する
	CGContextRef currentContext = UIGraphicsGetCurrentContext();
	// テキスト行列を既知の状態にする。これによって古い拡大縮小倍率が残っていないことが保証される
	CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
	// テキストを囲むパスオブジェクトを作成する。テキストの周囲のマージンを72ポイントに設定する 
	CGRect			 frameRect = CGRectMake(PDF_POINT,PDF_POINT,PDF_WIDTH-PDF_POINT*2,PDF_HEIGHT-PDF_POINT*2); // 内側の描画領域
	CGMutablePathRef framePath = CGPathCreateMutable();
	CGPathAddRect(framePath, NULL, frameRect);
	// レンダリングを実行するフレームを取得する
	// currentRange変数は、開始位置だけを指定する。framesetterはフレームに入る分量のテキストを配置する
	CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
	CGPathRelease(framePath);
	// CoreTextは左下角から上に向かって描画する。
	// このため、描画する前に現在の変換を反転する。
	CGContextTranslateCTM(currentContext, 0, PDF_HEIGHT);
	CGContextScaleCTM(currentContext, 1.0, -1.0);
	// フレームを描画する 
	CTFrameDraw(frameRef, currentContext);
	// 描画結果に基づいて、現在の範囲を更新する
	currentRange = CTFrameGetVisibleStringRange(frameRef);
	currentRange.location += currentRange.length;
	currentRange.length = 0;
	CFRelease(frameRef);
	return currentRange;
}

// ページ番号描画
// Localizable.stringsに"PAGE"の設定が必要
void drawPDFpageNumber(NSInteger pageNum,CGFloat pdf_width,CGFloat pdf_height)
{
	NSString *pageString  = [NSString stringWithFormat:NSLocalStr(@"PAGE"), pageNum];
	UIFont	 *theFont	  = [UIFont systemFontOfSize:12];
	CGSize maxSize		  = CGSizeMake(pdf_width,PDF_POINT);
	CGSize pageStringSize;
	NSMutableParagraphStyle *pstyle=[[NSMutableParagraphStyle alloc]init];
	pstyle.lineBreakMode=NSLineBreakByClipping;
	NSAttributedString *attributedText =[[NSAttributedString alloc]initWithString:pageString attributes:@{NSFontAttributeName:theFont,NSParagraphStyleAttributeName:pstyle}];
	CGRect rect = [attributedText boundingRectWithSize:maxSize
											   options:NSStringDrawingUsesLineFragmentOrigin
											   context:nil];
	pageStringSize = rect.size;

	CGRect stringRect	  = CGRectMake( /* 中央下部に表示 */
									   ((pdf_width - pageStringSize.width) / 2.0),
									   (pdf_height-PDF_POINT) + ((PDF_POINT-pageStringSize.height) / 2.0),
									   pageStringSize.width,
									   pageStringSize.height);
	[pageString drawInRect7NoReturn:stringRect withFont:theFont withColor:[UIColor blackColor]]; // X-BASICではリスト出力だけなので白地に黒文字で良い
}

// テキスト描画用PDF作成
- (void)savePDFFileWithText:(NSString *)text fname:(NSString *)pdfname
{
	// CoreText Framesetterで使うテキストを準備する
	CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, (CFStringRef)text, NULL);
	if (!currentText) {
		nslog(@"framesetterのための属性付き文字列が生成できません");
		return;
	}
	//
	CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
	if (framesetter) {
		// Create the PDF context using the default page size of PDF_WIDTH * PDF_HEIGHT
		UIGraphicsBeginPDFContextToFile(pdfname, CGRectZero, nil); // CGRectZeroはデフォルトサイズを使う指定
		CFRange currentRange = CFRangeMake(0, 0);
		NSInteger currentPage = 0;
		do {
			// 新しいページの始まり
			UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, PDF_WIDTH, PDF_HEIGHT), nil);
			// 各ページの先頭にページ番号を描画する
			drawPDFpageNumber(++currentPage, PDF_WIDTH, PDF_HEIGHT);
			// Render the current page and update the current range to point to the beginning of the next page.
			currentRange = [self renderPage:currentRange andFramesetter:framesetter];
			// テキストの終わりまで来たらループを抜ける
		} while (currentRange.location != CFAttributedStringGetLength((CFAttributedStringRef)currentText));
		// PDF contextを閉じ、内容を書き出す.
		// text中に\nが含まれていると↓ここで"<Error> unsupported 'Zapf' version 00020000"が出る。が、実害はないので無視する。
		UIGraphicsEndPDFContext();
		// framesetterのrelease
		CFRelease(framesetter);
	} else {
		nslog(@"属性付き文字列のレイアウトに必要なframesetterを生成できません");
	}
	//
	// 属性付き文字列のRelease
	CFRelease(currentText);
}

-(void)savePDFFileWithImage:(UIImage *)image fname:(NSString *)pdfname
// UIImageからPDF作成
{
	CGRect frame={{0,0},image.size};
	UIGraphicsBeginPDFContextToFile(pdfname, frame, nil);
	UIGraphicsBeginPDFPageWithInfo(frame, nil);
	//
	CGContextRef context2 = UIGraphicsGetCurrentContext();
	UIImageView *imgView=[[UIImageView alloc]initWithImage:image];
	snapShot1(context2,imgView);
	
	// PDF contextを閉じ、内容を書き出す.
	UIGraphicsEndPDFContext();
}

@end
