//FitTextFrame.jsx　by（z-） ver_m

///////////////// UIパーツ表示関連 ///////////
function pointSizeFunc(obj){ //UIフォントちっさく
	for(var i=0; i<obj.children.length; i++){
		childObj=obj.children[i];
		if(typeof childObj.children !="undefined"){
			pointSizeFunc(childObj);
			}
		childObj.graphics.font=fontObj;
		}
	}

function boundsFunc(obj){ //UIアイテムつめつめ
	for(var i=0; i<obj.children.length; i++){
		childObj=obj.children[i];
		try{
			childObj.preferredSize[1]-=2;
			childObj.spacing=0;
			}
		catch(e){
			continue;
			}
		if((childObj.reflect.name=="Group") || (childObj.reflect.name=="Panel")){
			boundsFunc(childObj);
			}
		}
	}


function resum(){ //さも一発でサクッとやったかのように見せかける為にundoしまくる関数
	while(doc.undoHistory.length>histObj){
		doc.undo();
		}
	}

function sortFunc(a,b){
	return a-b;
	}
function sortFuncB(a,b){
	return a.baseline-b.baseline;
	}

function unitFunc(untObj){ //ルーラー単位と使用する単位の倍率
	var val="1";
	switch(untObj){
		case 2051106676 : val+="ag"; break;
		case 1514238068 : val+="ap"; break;
		case 2053336435 : val+="cm";break;
		case 2053335395 : val+="c"; break;
		case 1516790048 : val+="H"; break;
		case 2053729891 : val+="in"; break;
		case 2053729892 : val+="in"; break;
		case 2053991795 : val+="mm"; break;
		case 2054187363 : val+="p"; break;
		case 2054188905 : val+="pt"; break;
		case 2054255973 : val+="Q"; break;
		default : val2+="pt";  //カスタムとみなす
		}
	var defaultAnchor = app.activeWindow.transformReferencePoint;
	app.activeWindow.transformReferencePoint=[val, 0];
	var X=app.activeWindow.transformReferencePoint[0];
	app.activeWindow.transformReferencePoint = defaultAnchor;
	return X;
	}

function anchorSwitch(obj, anc){ //戻り値は [新しいアンカー, 90°ごとの補正値]
	if(arguments.length<2){ //引数省略の時はウィンドウのアンカーポイントを使用
		anc=app.activeWindow.transformReferencePoint;
		}
	if(anc==AnchorPoint.CENTER_ANCHOR || anc.reflect.name=="Array") return anc; //中央と任意座標は未処理
	var rot=obj.rotationAngle;
	var anchorAry=[ //左上から時計まわりに
	AnchorPoint.TOP_LEFT_ANCHOR, 
	AnchorPoint.TOP_CENTER_ANCHOR, 
	AnchorPoint.TOP_RIGHT_ANCHOR, 
	AnchorPoint.RIGHT_CENTER_ANCHOR, 
	AnchorPoint.BOTTOM_RIGHT_ANCHOR, 
	AnchorPoint.BOTTOM_CENTER_ANCHOR, 
	AnchorPoint.BOTTOM_LEFT_ANCHOR, 
	AnchorPoint.LEFT_CENTER_ANCHOR ];
	var rotateVal=Math.floor((rot+360+45)/90)*2; //45は見た目対策、*2で90度ぶん
	var newAnc;
	for(var i=0; i<8; i++){
		if(anchorAry[i]==anc){
			newAnc=i;
			break;
			}
		}
	return anchorAry[(newAnc+rotateVal+8)%8];
	}

if(!app.documents.length) exit();
var doc=app.activeDocument;
if(!doc.selection.length) exit();
var sel, sel2=false;
if(doc.selection[0].reflect.name=="TextFrame"){
	sel=doc.selection[0];
	sel2=doc.selection[1];
	}
else{
	if(doc.selection[1].reflect.name=="TextFrame"){
		sel=doc.selection[1];
		sel2=doc.selection[0];
		}
	else{
		alert("テキストフレームが選択されていません\nグループごとの選択には対応していません");
		exit();
		}
	}
//if(! "parentStory" in sel) exit();
var textStyleAry=[];
textStyleAry[0]=[];
if(! sel.parentStory.characters.length) exit();
if(app.activeWindow.transformReferencePoint.reflect.name=="Array") exit(); //アンカーポイントが任意座標の場合すいません
var hvObj=sel.parentStory.storyPreferences.storyOrientation==StoryHorizontalOrVertical.HORIZONTAL? true : false; //組み方向

var dlg="dialog{text:'FitTextFrame_el', \
G:Group{orientation:'row', \
R1:RadioButton{text:'段落揃えを使用　', value:true}, \
R2:RadioButton{text:'アンカーポイントを使用'}, \
}, \
G2:Group{orientation:'column', alignChildren:'left', \
C1:Checkbox{text:'字送り方向の調整', value:true}\
C2:Checkbox{text:'折り返しが解消するまでフレームを拡張',indent:10,  value:true}, \
C3:Checkbox{text:'行送り方向の調整', value:false}, \
C4:Checkbox{text:'オビの角度はテキストフレームに依存', value:false}, \
C5:Checkbox{text:'別置きオビの調整のみ', value:false}, \
}, \
B:Button{text:'please', properties:{name:'ok'}}\
} "
var win=new Window(dlg);
win.spacing=0;
var fontObj=ScriptUI.newFont(win.graphics.font.family, win.graphics.font.style, 10);
pointSizeFunc(win);
boundsFunc(win);
win.G2.C1.onClick=function(){
	win.G2.C2.enabled=win.G2.C1.value;
	}
var res=win.show();
if(res==2) exit();
if(win.G.R1.value && (sel.parentStory.justification%1000+"").match(/500|955|147/)){ //強制割り付け、ノド揃えはすいません
	alert("未対応の段落揃えです");
	exit();
	}
app.scriptPreferences.enableRedraw=false; //再描画をオフに
var myruler = doc.viewPreferences.rulerOrigin;
if(myruler != RulerOrigin.SPREAD_ORIGIN){ //定規の開始位置をスプレッドに
	doc.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
	}
var defR=sel.rotationAngle; //回転は一旦ナシに
var defaultAnchor = app.activeWindow.transformReferencePoint;
var hvVal=hvObj? 0 : 1; //横組み０、縦組み１
switch(hvVal + sel.parentStory.justification%1000 + sel.textFramePreferences.verticalJustification%1000){ //組み方向と段落揃えと上下配置で分岐（死にたいorz）
	case 948 : //横、左、天
	case 956 : //横、左均等、天
	case 1026 : //横、左、均等
	case 1034 : //横、左均等、均等
	case 1162 : //縦、左、地
	case 1170 : //縦、左均等、地
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_LEFT_ANCHOR; break;
	case 1052 : //横、中、天
	case 1012 : //横、中均等、天
	case 1130 : //横、中、均等
	case 1090 : //横、中均等、均等
	case 1489 : //縦、左、中
	case 1497 : //縦、左均等、中
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_CENTER_ANCHOR; break;
	case 828 :  //横、右、天
	case 1252 :  //横、右均等、天
	case 906 :  //横、右、均等
	case 1330 :  //横、右均等、均等
	case 949 : //縦、左、天
	case 957 : //縦、左均等、天
	case 1027 : //縦、左、均等
	case 1035 : //縦、左均等、均等
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_RIGHT_ANCHOR; break;
	case 1488 :  //横、左、中
	case 1496 :  //横、左均等、中
	case 1266 :  //縦、中、地
	case 1226 :  //縦、中均等、地
					app.activeWindow.transformReferencePoint=AnchorPoint.LEFT_CENTER_ANCHOR; break;
	case 1592 :  //横、中、中
	case 1552 :  //横、中均等、中
	case 1593 :  //縦、中、中
	case 1553 :  //縦、中均等、中
					app.activeWindow.transformReferencePoint=AnchorPoint.CENTER_ANCHOR; break;
	case 1368 :  //横、右、中
	case 1792 :  //横、右均等、中
	case 1053 : //縦、中、天
	case 1013 : //縦、中均等、天
	case 1131 : //縦、中、均等
	case 1091 : //縦、中均等、均等
					app.activeWindow.transformReferencePoint=AnchorPoint.RIGHT_CENTER_ANCHOR; break;
	case 1161 : //横、左、地
	case 1169 : //横、左均等、地
	case 1042 : //縦、右、地
	case 1466 : //縦、右均等、地
					app.activeWindow.transformReferencePoint=AnchorPoint.BOTTOM_LEFT_ANCHOR; break;
	case 1265 :  //横、中、地
	case 1225 :  //横、中均等、地
	case 1369 :  //縦、右、中
	case 1793 :  //縦、右均等、中
					app.activeWindow.transformReferencePoint=AnchorPoint.BOTTOM_CENTER_ANCHOR; break;
	case 1041 : //横、右、地
	case 1465 : //横、右均等、地
	case 829 :  //縦、右、天
	case 1253 :  //縦、右均等、天
	case 907 :  //横、右、均等
	case 1331 :  //横、右均等、均等
					app.activeWindow.transformReferencePoint=AnchorPoint.BOTTOM_RIGHT_ANCHOR; break;
	}
if( ! win.G.R1.value){ //アンカーポイントを使用ならアンカーポイントを戻す(?)
	app.activeWindow.transformReferencePoint = defaultAnchor;
	}
if(defR){
	sel.rotationAngle=0;
	}
var histObj=doc.undoHistory.length; //resum()用
var selgb=sel.geometricBounds;
var selX=(selgb[3]+selgb[1])/2;
var selY=(selgb[2]+selgb[0])/2;
var selgb=sel.geometricBounds;
var newgb=sel.geometricBounds;
var tar=sel.duplicate(); //連結対策
var gb=tar.geometricBounds;
var tst=tar.parentStory;
var brObj=tst.contents.match(/[\n\r]/); //マッチ数+1 が伸びきった時の行数とする
var lineLength=brObj==null? 1 : brObj.length+1;
var err=false;
if(tst.lines.length !=lineLength && win.G2.C1.value && win.G2.C2.value){ //行の折り返し解消処理
	var asp=doc.layoutWindows[0].activeSpread;
	var pb1=asp.pages[0].bounds;
	var pb2=asp.pages[-1].bounds;
	gb=[]; //リセット
	gb[0]=Math.min(pb1[0], pb2[0]);
	gb[1]=Math.min(pb1[1], pb2[1]);
	gb[1]=Math.min(gb[1], tar.geometricBounds[1]);
	gb[2]=Math.max(pb1[2], pb2[2]);
	gb[2]=Math.max(gb[2], tar.geometricBounds[2]);
	gb[3]=Math.max(pb1[3], pb2[3]);
	tar.geometricBounds=gb;
	}
try{
	tar.fit(FitOptions.FRAME_TO_CONTENT);
	}
catch(e){
	err=true;
	}
if(tar.overflows){
	err=true;
	}
if(err){
	resum();
	if(defR){
		doc.undo();
		}
	alert("フレームサイズが長くなりすぎる可能性があるため処理を中断しました\nまたは、あやしい改行系文字が含まれている可能性があります");
	app.scriptPreferences.enableRedraw=true; //再描画をオンに
	app.activeWindow.transformReferencePoint = defaultAnchor; //アンカーポイントもどす
	exit();
	}
gb=tar.geometricBounds;
var unitObj=unitFunc(doc.viewPreferences.textSizeMeasurementUnits); //文字サイズの単位補正値
var strokeUnitObj=unitFunc(doc.viewPreferences.lineMeasurementUnits); //線の単位補正値
//フレーム内マージン分の補正用
var insetAry=sel.textFramePreferences.insetSpacing;
if(hvObj){ //横組みなら左右を計測
	gb[1]=tst.insertionPoints.everyItem().horizontalOffset.sort(sortFunc)[0]-insetAry[1]; 
	gb[3]=tst.insertionPoints.everyItem().horizontalOffset.sort(sortFunc).reverse()[0]+(tar.strokeWeight*strokeUnitObj)+insetAry[3]; //線幅補正
	}
else{ //縦組みなら天地を計測
	tst.characterRotation=180;
	var betC=tar.characters[-1];
	for(i=0; i<tar.lines.length; i++){
		if(tar.lines[i].characters[0].baseline<betC.baseline){
			betC=tar.lines[i].characters[0];
			}
		}
	//gb[0]=tst.characters.everyItem().getElements().sort(sortFuncB)[0];
	gb[0]=betC.baseline-(betC.pointSize*unitObj*0.12)-insetAry[0]; //ベースライン最小値から仮想ボディ座標
	doc.undo();
	for(i=0; i<tar.lines.length; i++){
		if(tar.lines[i].characters[-1].baseline>betC.baseline){
			betC=tar.lines[i].characters[-1];
			}
		}
	//gb[2]=tst.characters.everyItem().getElements().sort(sortFuncB).reverse()[0];
	gb[2]=betC.baseline+(betC.pointSize*unitObj*0.12)+(tar.strokeWeight*strokeUnitObj)+insetAry[2]; //ベースラインの最大値
	}
//////////////幅と高さを出してアンカーポイントに応じてスライドする処理
var tarWidth=gb[3]-gb[1];
var tarHeight=gb[2]-gb[0];
var hvVal=hvObj? 0 : 1; //横組み０、縦組み１
switch(app.activeWindow.transformReferencePoint){ //設定しておいたアンカーポイントで分岐
	case AnchorPoint.TOP_LEFT_ANCHOR : 
					newgb[2]=selgb[0]+tarHeight;
					newgb[3]=selgb[1]+tarWidth; break;
	case AnchorPoint.TOP_CENTER_ANCHOR :
					newgb[1]=selX-(tarWidth/2);
					newgb[2]=selgb[0]+tarHeight;
					newgb[3]=selX+(tarWidth/2); break;
	case AnchorPoint.TOP_RIGHT_ANCHOR :
					newgb[1]=selgb[3]-tarWidth;
					newgb[2]=selgb[0]+tarHeight; break;
	case AnchorPoint.LEFT_CENTER_ANCHOR :
					newgb[0]=selY-(tarHeight/2);
					newgb[2]=selY+(tarHeight/2);
					newgb[3]=selgb[1]+tarWidth; break;
	case AnchorPoint.CENTER_ANCHOR :
					newgb[0]=selY-(tarHeight/2);
					newgb[1]=selX-(tarWidth/2);
					newgb[2]=selY+(tarHeight/2);
					newgb[3]=selX+(tarWidth/2); break;
	case AnchorPoint.RIGHT_CENTER_ANCHOR :
					newgb[0]=selY-(tarHeight/2);
					newgb[1]=selgb[3]-tarWidth;
					newgb[2]=selY+(tarHeight/2); break;
	case AnchorPoint.BOTTOM_LEFT_ANCHOR :
					newgb[0]=selgb[2]-tarHeight;
					newgb[3]=selgb[1]+tarWidth; break;
	case AnchorPoint.BOTTOM_CENTER_ANCHOR :
					newgb[0]=selgb[2]-tarHeight;
					newgb[1]=selX-(tarWidth/2);
					newgb[3]=selX+(tarWidth/2); break;
	case AnchorPoint.BOTTOM_RIGHT_ANCHOR :
					newgb[0]=selgb[2]-tarHeight;
					newgb[1]=selgb[3]-tarWidth; break;
	}

if((win.G2.C3.value==false && hvObj==true) || (win.G2.C1.value==false && hvObj==false)){
	newgb[0]=selgb[0];
	newgb[2]=selgb[2];
	}
if((win.G2.C1.value==false && hvObj==true) || (win.G2.C3.value==false && hvObj==false)){
	newgb[1]=selgb[1];
	newgb[3]=selgb[3];
	}
resum();
//tar.remove();
if(!win.G2.C5.value){ //オビのみ処理ならスキップ
	sel.geometricBounds=newgb;
	}
if(defR){
	sel.rotationAngle=defR;
	}
if(!sel2){ //別置きオビがなければここまで
	if(myruler != RulerOrigin.SPREAD_ORIGIN){
		doc.viewPreferences.rulerOrigin = myruler;
		}
	app.scriptPreferences.enableRedraw=true; //再描画をオンに
	app.activeWindow.transformReferencePoint = defaultAnchor; //アンカーポイントもどす
	exit();
	}

if( ! win.G.R1.value){
	app.activeWindow.transformReferencePoint = defaultAnchor; 
	}

//別置きオビの処理
var scallingOrientation=hvObj? 0 : 1;
switch(app.activeWindow.transformReferencePoint%1000+scallingOrientation){ //アンカーポイントと組み方向で分岐
	case 652 : //左上　横--
	case 595 : //左　横--
	case 44 : //左下　横--
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_LEFT_ANCHOR; break;
	case 308 : //中央　横--
	case 643 : //上中　横--
	case 35 : //下中　横--
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_LEFT_ANCHOR; break; //中央揃えは暫定的にテキスト先頭方向で判定
	case 658 : //右上 横--
	case 131 : //右　横--
	case 50 : //右下　横--
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_RIGHT_ANCHOR; break;
	case 653 : //左上　縦--
	case 644 : //上　縦--
	case 659 : //右上　縦--
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_RIGHT_ANCHOR; break;
	case 596 : //左　縦--
	case 309 : //中央　縦--
	case 132 : //右　縦--
					app.activeWindow.transformReferencePoint=AnchorPoint.TOP_RIGHT_ANCHOR; break;
	case 45 : //左下　縦--
	case 36 : //下　縦--
	case 51 : //右下　縦--
					app.activeWindow.transformReferencePoint=AnchorPoint.BOTTOM_RIGHT_ANCHOR; break;
	}

defR=win.G2.C4.value? defR : sel2.rotationAngle; //オビの回転角、チェックがなければ置換
var asObj=anchorSwitch(sel2);
if(defR){
	var moyoAngle= defR%90;
	moyoAngle=Math.abs(moyoAngle)>45? (Math.abs(moyoAngle)/moyoAngle*90)-moyoAngle : -moyoAngle;
	var tmObjR=app.transformationMatrices.add(1, 1, 0, moyoAngle, 0, 0); //一旦テキストフレームの水平時の角度に
	sel2.transform (CoordinateSpaces.PASTEBOARD_COORDINATES, asObj, tmObjR);
	}
else{
	moyoAngle=-defR;
	}
var obigb=sel2.geometricBounds;
var scaleVal; //基準サイドの文字との距離
var trAnc; //transformに使うアンカーポイント
switch(app.activeWindow.transformReferencePoint%1000+scallingOrientation){ //アンカーポイントと組み方向で分岐
	case 652 : //左上　横--
	case 595 : //左　横--
	case 44 : //左下　横--
					//trAnc=AnchorPoint.TOP_LEFT_ANCHOR;
					scaleVal=newgb[1]-obigb[1]; break;
	case 308 : //中央　横--
	case 643 : //上中　横--
	case 35 : //下中　横--
					//trAnc=AnchorPoint.TOP_LEFT_ANCHOR;
					scaleVal=newgb[1]-obigb[1]; break; //中央揃えは暫定的にテキスト先頭方向で判定
	case 658 : //右上 横--
	case 131 : //右　横--
	case 50 : //右下　横--
					//trAnc=AnchorPoint.TOP_RIGHT_ANCHOR;
					scaleVal=obigb[3]-newgb[3]; break;
	case 653 : //左上　縦--
	case 644 : //上　縦--
	case 659 : //右上　縦--
					//trAnc=AnchorPoint.TOP_RIGHT_ANCHOR;
					scaleVal=newgb[0]-obigb[0]; break;
	case 596 : //左　縦--
	case 309 : //中央　縦--
	case 132 : //右　縦--
					//trAnc=AnchorPoint.TOP_RIGHT_ANCHOR;
					scaleVal=newgb[0]-obigb[0]; break;
	case 45 : //左下　縦--
	case 36 : //下　縦--
	case 51 : //右下　縦--
					//trAnc=AnchorPoint.BOTTOM_RIGHT_ANCHOR;
					scaleVal=obigb[2]-newgb[2]; break;
	}
var obiSize, tmObj;
if(hvObj){
	tmObj=app.transformationMatrices.add((tarWidth+(scaleVal*2))/(obigb[3]-obigb[1]), sel2.verticalScale/100, 0, -moyoAngle, 0, 0);
	}
else{
	tmObj=app.transformationMatrices.add(sel2.horizontalScale/100, (tarHeight+(scaleVal*2))/(obigb[2]-obigb[0]), 0, -moyoAngle, 0, 0);
	}
sel2.transform (CoordinateSpaces.PASTEBOARD_COORDINATES, asObj, tmObj);

if(myruler != RulerOrigin.SPREAD_ORIGIN){
	doc.viewPreferences.rulerOrigin = myruler;
	}
app.scriptPreferences.enableRedraw=true; //再描画をオンに
app.activeWindow.transformReferencePoint = defaultAnchor; //アンカーポイントもどす

