/*	りまぴん・ユーティリティー関数群	*/
/*						*/
/*						*/
/*						*/
/*						*/
//フットスタンプクリア
clearFS=function(){
	if(FootMark){xUI.footstampClear()};
};
//タイムライン消去
clearTL=function(flg){
	var bkPos=xUI.Select.join("_");//現在のカーソルを記録
//フラグによる指定があった場合タイムラインの選択状態を調整する
switch(flg){
case	"all"	:xUI.selectCell("0_"+xUI.Select[1]);xUI.selection((XPS.xpsBody.length-1)+"_"+xUI.Select[1]);break;
case	"left"	:xUI.selection("0_"+xUI.Select[1]);break;
case	"right"	:xUI.selection((XPS.xpsBody.length-1)+"_"+xUI.Select[1]);break;
};
//消去対象を選択状態から取得
	var minID=(xUI.Selection[0]<0)?xUI.Select[0]+xUI.Selection[0] : xUI.Select[0];
	var maxID=(xUI.Selection[0]<0)?xUI.Select[0]+1 : xUI.Select[0]+xUI.Selection[0]+1;

	for(tId=minID;tId<maxID;tId++){
		xUI.selectCell(tId+"_0");//冒頭データに移動
		xUI.selection(tId+"_"+(XPS.duration()-1));//タイムライン末尾を選択
		xUI.cut();	//削除
//		if (xUI.edchg){xUI.put(this.eddt);}//更新
		if(xUI.getid("Selection")!="0_0") {xUI.selection();xUI.spinHi();};
//		選択範囲解除
		if(xUI.Focus) {xUI.focusCell();};
	};
	xUI.selectCell(bkPos);	//バックアップ位置へ復帰
	document.getElementById("iNputbOx").focus();
};
//タイムライン整形
/*
	タイムラインを標準シート表記にリフォーマットします。
	標準シート表記は以下のとおり
timing
-タイムシートセルには、そのフレームで使用する動画番号を記述すること。
-同じ動画番号が連続して記述される場合は動画番号を重複記述しないで縦線をひいて省略すること。
-動画を使用しないシートセルには「×」印を打って「カラセル」である事を明示すること。
-カラセルが連続する場合は波線で連続を表記すること。
-2コマおよび3コマ連続して同じ動画番号またはカラセルを指定する場合は、記述の簡略化と読みやすさの為、連続の縦線または波線自体を省略すること。
-空白コマおよび縦線で同要素の省略をしたシートセルは、動画入れ替えと紛らわしくない場合に限り注釈を書き込むことが出来る。
-原画番号は可能な限り丸囲い(または同等の強調表示)をする。
-数字の1は縦棒線と紛らわしいので原画番号でなくとも丸囲い（または相当する強調表示）をする。
2015拡張
次回フォーマットでは、機種依存文字の制限を緩和する。少なくとも丸囲い文字を開放①～㊿をサポート　切り替えは付ける


dialog
-台詞は、ダイアログ開始マーカと終了マーカーの間に置かれる
-ダイアログ開始マーカーはダイアログ開始前のフレームに置き、ダイアログ終了マーカーはダイアログ区間の後方フレームに置かれる。
-テキスト表現のマーカーは。「カギカッコ」"引用符" 又は　[-|_]　3個以上の連続とする。シート上の表記は、これらを横線に置き換える。
-ダイアログ内の注釈データは(丸括弧)でエスケープされる
-マーカー外の記述は、すべて注釈である
-マーカー内の記述は、注釈以外は一連の内容テキストとして配置される。空白及びヌル文字は取り除かれる。
camera
ジオメトリを持つプロパティがこれに相当する　カメラワーク／セルワークがこれにあたる
-以下の有効記述がある
	-登録されたキーフレーム（値を持つ）角括弧による指定がない場合はこれを補う
	-[角括弧]でキーフレーム指定が行われた記述 MAPにエントリーがない場合は、入力を促す
	-区間開始マーカー(ダイアログマーカーと異なり区間内に含まれる)　▼▽（慣例的に三角が標準）
	-区間終了マーカー(ダイアログマーカーと異なり区間内に含まれる)　▲△
	-中間値生成記述　|(バーチカルバー)　・（中黒）-(ハイフン)
-有効記述以外はすべて注釈でありデータ解析上の意味は前方データの継承。
	一部後方参照が行われる。
	具体的には、開始時点の暗黙の初期値がこれに当たる
	第一フレームが値を持たない場合、値の保留が発生して最初に現れたエントリから値を継承する。
	値を持たない有効記述が最初に現れた場合は、初期値（デフォルトのジオメトリ）が適用されるものとする
	効果区間が連続する場合は、その開始マーカーに対して値の保留が発生する。
	終了マーカーの直後の有効値記述は開始マーカーを兼ねることが可能である。
-データ成形上は、区間開始マーカーと終了マーカーの間に記述がない場合、シングルフレームの補間を補う
	区間の補間方法（タイミング指定）は別インターフェースで行う。
	記録はXPSでなくMAPエントリに対して行われる（MAP対応必須）
	有効値は、値とともにタイミングを保持する

effect
ジオメトリを持たないプロパティがこれに相当する　フェード・中OL（二重フェード）・透過光・レイヤートレーラーの合成モードなどがこれにあたる
-以下の有効記述がある
	-登録されたキーフレーム（値を持つ）矢括弧による指定がない場合はこれを補う
	-<矢括弧>でキーフレーム指定が行われた記述 MAPにエントリーがない場合は、入力を促す
	-区間開始マーカー(ダイアログマーカーと異なり区間内に含まれる)　（慣例的に三角が標準）
	-区間終了マーカー(ダイアログマーカーと異なり区間内に含まれる)　▲△
	-補間値生成マーカー　|(バーチカルバー)　・（中黒）-(ハイフン)
		中間値生成区間内では、有効記述が補間値生成マーカーとして働く
-有効記述以外はすべて注釈でありデータ解析上の意味は前方データの継承。
	一部後方参照が行われる具体的には、開始時点の暗黙の初期値がこれに当たる
	第一フレームに値がない場合、値の保留が発生して最初に現れたエントリから値を継承する。
	値を持たない有効記述が最初に現れた場合、初めて初期値（デフォルトのジオメトリ）が適用されるものとする
-データ成形上は、区間開始マーカーと終了マーカーの間に記述がない場合、シングルフレームの補間を補う
	区間の補間方法は別インターフェースで行う。記録はXPSでなくMAPエントリに対して行われる（MAP対応必須）


関数の動作(2007/06/30現在)
動作指定が無い場合は、現在フォーカスのあるタイムラインを処理する
引数"all"がある場合はシート全体を処理

タイムライン種別を本格的に実装開始したので、フォーマッタはタイムライン種別を認識して動作を区分すること。
上記の動作は"timing"タイムラインに限定すること

 */

reformatTimeline=function(flg){

function reformatTLC(id){
//===camerawork===
//ターゲットタイムライン
	var myTargetBody=XPS.xpsBody[id];//指定タイムラインのデータを配列参照
	var myDestTLBody=new Array();//編集用カラ配列
	var bufNoChange=new Array(); var bufModified=new Array();//編集バッファ
	var fix=true;//値固定（中間値生成ではない）区間か否かのフラグ　生成区間の未記入セルに中間値生成記号を補間する？
/*第一フレームが有効記述か否か確認
カメラワークトラックでは開始フレームが無効記述・区間開始ノードであった場合、
その値は初期値ではなく次に区間切り替えノードがあるか、有効値を持った記述があるまでは保留状態とする。
有効な値が与えられなかった場合初期値が効果を持つ。

1.意味のある値かまたは予約語の確認
	[角括弧]で支持された値のある（と思われる）エントリ、開始ノード、終了ノード、中間値生成ノード
2.その他の記述
	マップに問い合わせて有効な値か否かを確認
	有効記述ならば、[角括弧]を与える
	無効記述ならば、値はそのままにして配置
	区間(Section)により意味が変わる
		値固定区間(fixSection)ならば無効記述
		中間値生成区間(interpolationSection)ならば、中間値生成ノード

*/
	var referenceValue=(myTargetBody[0].match(/^(\[.+\]|[▽▼])$/))?RegExp.$1:"res";

	if(referenceValue=="res"){
		myDestTLBody.push(myTargetBody[0]);
	}else{
		if(myTargetBody[0].match(/^[▽▼]$/)){fix=false};
		myDestTLBody.push(myTargetBody[0]);
	};
//第二フレームからデータループ
	for(var fidx=1;fidx<myTargetBody.length;fidx++){
//	評価値取得
		var evValue=myTargetBody[fidx];

		bufNoChange.push(myTargetBody[fidx].replace(/^(x|0|〆|Ｘ|ｘ)$/i,"|"));//非加工バッファを作成
//	リファレンスと一致
		if((evValue=="")&&(! fix)){
			var modifiedData=(myTargetBody[fidx])?myTargetBody[fidx]:"|";
			if(modifiedData=="1"){modifiedData="(1)"};//これ一括調整関数がほしい
			if((referenceValue=="blank")&&(modifiedData=="|")){
				modifiedData=":";//置き替え
			};
			bufModified.push(modifiedData);
//	同値カウンタ加算
			sVC++;
		}else{
			var modifiedData=myTargetBody[fidx];
			if(modifiedData=="1"){
				modifiedData="(1)";
};
			bufModified.push(modifiedData.toString());
//	シートの値が変更されたのでバッファをフラッシュする
			if(sVC>myLimit){
//	同値カウンタが規定値以上(4以上)なら加工済みバッファでフラッシュ
				myDestTLBody=myDestTLBody.concat(bufModified);
//myDestTLBody.push("mfd");
			}else{
//	同値カウンタが規定値より下(3以下)なら非加工バッファでフラッシュ
				myDestTLBody=myDestTLBody.concat(bufNoChange);
//myDestTLBody.push("nch");
			};
//	同値カウンタリセット
//	サブバッファ初期化
		bufNoChange.length=0; bufModified.length=0;
//	基準値更新
		referenceValue=evValue;
		};
	};
//	全ループ終了後に残った編集バッファをフラッシュする
	if(sVC>0){
		if(sVC>myLimit){
//	同値カウンタが規定値以上(4以上)なら加工済みバッファでフラッシュ
			myDestTLBody=myDestTLBody.concat(bufModified);
		}else{
//	同値カウンタが規定値より下(3以下)なら非加工バッファでフラッシュ
			myDestTLBody=myDestTLBody.concat(bufNoChange);
		};
	};
	return myDestTLBody.join();
};

function reformatTL(id){
//===timing===
//　分岐であらかじめ判定するのでプロパティチェックは不要に　2013/06/22
//現状ではidがセル範囲外であった場合に中断するトラップが必要
//	if( id<0 || id>= XPS.layers.length ){return false};
//タイミングタイムラインでない場合は、処理中断
//	if(XPS.layers[id+1]["option"]!="timing"){return false};
//ターゲットタイムライン
	var myTargetBody=XPS.xpsBody[id];//指定タイムラインのバルクデータを配列で参照
	var myDestTLBody=new Array();//編集用カラ配列
	var bufNoChange=new Array(); var bufModified=new Array();//編集バッファ
	var sVC=0;//同値カウンタ
	var myLimit=3;//3kまでは縦線省略
//第一フレームが有効記述か否か確認(id=0は、事前チェックで入らないはず)
	var referenceValue=(dataCheck(myTargetBody[0],XPS.layers[id-1].name)==null)?"blank":dataCheck(myTargetBody[0],XPS.layers[id-1].name);

	if(referenceValue=="blank"){
		myDestTLBody.push("X");
	}else{
		if(myTargetBody[0]=="1"){myTargetBody[0]="(1)"};//これは一括調整がほしい
		myDestTLBody.push(myTargetBody[0]);
	};
	sVC=1;
//第二フレームからデータループ
	for(var fidx=1;fidx<myTargetBody.length;fidx++){
//	評価値取得
		var evValue=(dataCheck(myTargetBody[fidx],XPS.layers[id-1].name)==null)?referenceValue:dataCheck(myTargetBody[fidx],XPS.layers[id-1].name);

		if(myTargetBody[fidx]=="1"){myTargetBody[fidx]="(1)"};//これは一括調整がほしい

		bufNoChange.push(myTargetBody[fidx].replace(/^(x|0|〆|Ｘ|ｘ)$/i,"X"));//非加工バッファを作成
//	リファレンスと一致
		if((evValue==referenceValue)&&(evValue!="interp")){
			var modifiedData=(myTargetBody[fidx])?myTargetBody[fidx]:"|";
			if(modifiedData=="1"){modifiedData="(1)"};//これ一括調整関数がほしい
			if((referenceValue=="blank")&&(modifiedData=="|")){
				modifiedData=":";//置き替え
			};
			bufModified.push(modifiedData);
//	同値カウンタ加算
			sVC++;
		}else{
			var modifiedData=myTargetBody[fidx];
			if(modifiedData=="1"){
				modifiedData="(1)";
};//これ一括調整関数がほしい
			if(evValue=="blank"){
				modifiedData=modifiedData.replace(/^(x|0|〆|Ｘ|ｘ)$/i,"X");
			};
			bufModified.push(modifiedData.toString());
//	シートの値が変更されたのでバッファをフラッシュする
			if(sVC>myLimit){
//	同値カウンタが規定値以上(4以上)なら加工済みバッファでフラッシュ
				myDestTLBody=myDestTLBody.concat(bufModified);
//myDestTLBody.push("mfd");
			}else{
//	同値カウンタが規定値より下(3以下)なら非加工バッファでフラッシュ
				myDestTLBody=myDestTLBody.concat(bufNoChange);
//myDestTLBody.push("nch");
			};
//	同値カウンタリセット
		sVC=1;
//	サブバッファ初期化
		bufNoChange.length=0; bufModified.length=0;
//	基準値更新
		referenceValue=evValue;
		};
	};
//	全ループ終了後に残った編集バッファをフラッシュする
	if(sVC>0){
		if(sVC>myLimit){
//	同値カウンタが規定値以上(4以上)なら加工済みバッファでフラッシュ
			myDestTLBody=myDestTLBody.concat(bufModified);
		}else{
//	同値カウンタが規定値より下(3以下)なら非加工バッファでフラッシュ
			myDestTLBody=myDestTLBody.concat(bufNoChange);
		};
	};
	return myDestTLBody.join();
};


//分岐と処理
	var bkPos=xUI.Select.join("_");//カーソル位置保存

if(flg=="all"){
//全シート指定
	for(var idx=0;idx<(XPS.xpsBody.length);idx++){

		xUI.selectCell((idx)+"_0")//カーソルを当該タイムラインの第一フレームへ
	 var myOpt=(idx==0)? "dialog":XPS.layers[idx-1].option;
	 switch(myOpt){
	 case "dialog": ;break;
	 case "still": ;break;
	 case "sfx": ;break;
	 case "camera": ;break;
	 case "timing":
	 default:
//alert(reformatTL(idx));
 xUI.put(reformatTL(idx));
// alert(idx+":"+myOpt);
	 }
	};
}else{
//指定なければ現在のタイムラインを指定
	if((! flg) && (xUI.Select[0]>=1 && xUI.Select[0]<(XPS.xpsBody.length-1))){
		xUI.selectCell(xUI.Select[0]+"_0")//カーソルを当該タイムラインの第一フレームへ
	if(xUI.Select[0]>0){var myOpt=XPS.layers[xUI.Select[0]-1].option}else{var myOpt="dialog"};
	 switch(myOpt){
	 case "dialog": ;break;
	 case "still": ;break;
	 case "sfx": ;break;
	 case "camera": ;break;
	 case "timing":
	 default:
		xUI.put(reformatTL(xUI.Select[0]));//データ更新
	 }
	};
};
	xUI.selectCell(bkPos);	//バックアップ位置へ復帰
	document.getElementById("iNputbOx").focus();
};
vxPrompt= function(msg,params){return prompt(msg,params);};
//タイムライン追加
/*
	現在アクティブなタイムラインの右側にタイムラインを１つだけ追加する
	以下の手順のもとにラベルは引数指定または自動生成
	コマンドには、確認等の手順はなし
	既存のタイムラインラベルは変更されない
	必要ならば挿入後に変名を行う

	UNDO拡張に伴って変更　2015.09.14

addTimeline(kind,label)
	kind　はタイムライン種別
	dialog,still,timing,camera,effect いずれか
	label　はタイムラインラベル
	指定がない場合は以下の基準で命名
	ダイアログ	指定順に N2 N3 N4 ～ナンバリング
	タイミング	右端追加の場合のみAB順で次のラベル
			それ以外の場合は現在のタイムラインラベルに数字を加算
	カメラ/エフェクト	挿入後のタイムラインID　3番タイムラインでの指定時には必ず"04"
*/
addTimeline=function(myOpt,myName){
	if(xUI.Select[0]>XPS.layers.length){return false;};//コメントの右側へは挿入不可
	var insertPoint=[xUI.Select[0]+1,xUI.Select[1]];//挿入ポイントを作成
	if(!myOpt){myOpt="timing"};
	if(!myName){
		switch(myOpt){
case	"dialog":
		//ダイアログラベルの数を数えて数値でラベル名を作成
		var countDialog=1;//デフォルト1
		for (prp in XPS.layers){if (XPS.layers[prp].option=="dialog")countDialog++;}
		myName= "N"+(countDialog +1);
break;
case	"timing":
		var countTiming=0;//カレントよりも右側のタイミングタイムラインを数える
		for (var pIdx=xUI.Select[0];pIdx<XPS.layers.length;pIdx++){if(XPS.layers[pIdx].option=="timing")countTiming++;}
//		alert(countTiming);//
		if(countTiming<=0){
		  var currentLabels=[]
		//タイミングラベルの最大を検出して次の文字をピックアップ 
		for (prp in XPS.layers){if (XPS.layers[prp].option=="timing")currentLabels.push(XPS.layers[prp].name.charAt(0));}
		currentName=currentLabels.sort()[currentLabels.length-1];
		myName= ("ABCDEFGHIJKLMNOPQRSTUVWXYZ").charAt((("ABCDEFGHIJKLMNOPQRSTUVWXYZ").indexOf(currentName)+1)%26);
break;
		}
case	"still":
case	"camera":
case	"effect":
default	:	myName=nas.Zf(insertPoint[0],2).toString();//挿入点のID　二桁文字列
		
		}
	}

//現在のXPSの複製を作り
//新しいタイムラインを作成して挿入位置に挿入
//putメソッドでドキュメントを入れ替える
	var newXPS= new Xps();
	newXPS.readIN(XPS.toString());
	newXPS.insertTL(insertPoint[0],new XpsLayer(myName,myOpt));
//	nas_Rmp_Init();//リフレッシュ
	xUI.put(newXPS);
	xUI.selectCell(insertPoint.join("_"));
}
//タイムライン挿入
/*
	指定IDの前方に挿入
	挿入するタイムラインはすべて"timing"
	挿入位置及び挿入数指定は、選択範囲を使用
	新規作成するタイムラインのラベルは自動作成したものを提示してユーザ編集
	undoバッファは維持できないのでクリア
	挿入と削除はXpsオブジェクトのメソッドを呼ぶ形に変更
 */
insertColumns=function(newNames){
	var insertLength=Math.abs(xUI.Selection[0])+1;//挿入タイムライン数を取得
	var insertPoint=(xUI.Selection[0]<0)?[xUI.Select[0]+xUI.Selection[0],0]:[xUI.Select[0],0];//挿入ポイントを記録
if(typeof newNames == "undefined"){
	if(insertPoint[0]<1){return};

	var currentNames=new Array();//挿入後のラベル名格納配列
//	挿入分仮ラベルをタイムラインIDで初期化
	for(var Tidx=0;Tidx<insertLength;Tidx++){
		currentNames.push(nas.Zf(Tidx+insertPoint[0],2));
	};
//	警告
	nas.showModalDialog("prompt",
		"以下のタイムラインを挿入します。\n希望のラベルをコンマ区切りで指定できます。\n",
		"タイムライン挿入",
		currentNames.join(","),
		function(){if(this.status==0){insertColumns(this.value)};xUI.setStored("force");//sync();
		}
	)

}else{
//	xUI.printStatus();
if(newNames!=null){
	newNames=newNames.split(",");
	if(newNames.length>insertLength){newNames.length=insertLength;};//オーバー時切捨て
	if(newNames.length<insertLength){
		for(var Tidx=newNames.length;Tidx<insertLength;Tidx++){
			newNames.push(nas.Zf(Tidx+insertPoint[0],2));
		};
	};//不足時は再生成

	var bkPt=xUI.Select;//カーソル元位置控

	var newXPS=new Xps();
	newXPS.readIN(XPS.toString());
	newXPS.insertTL(insertPoint[0],newNames);
	xUI.put(newXPS);
//	nas_Rmp_Init();//リフレッシュ put側で実行される

	xUI.selectCell(add(bkPt,[insertLength,0]).join("_"));//カーソルを挿入後の元位置へ復帰
//	xUI.flushUndoBuf();sync("undo");//

}else{
	alert("処理を中止しました。");
};
};
}
;//
//		タイムライン削除
/*
	指定IDのタイムラインを削除
	指定は、選択範囲を使用することに
	undoバッファは維持できないのでクリア
	Xpxのメソッドを呼び出す形に変更
	0番タイムライン及びフレームコメントは削除不可
 */
deleteColumns=function(newNames){
	if(xUI.Select[0]==0||xUI.Select[0]+xUI.Selection[0]<=0||xUI.Select[0]+xUI.Selection[0]>=(XPS.xpsBody.length-1)||xUI.Select[0]==(XPS.xpsBody.length-1))
	{return false;};
	var deleteLength=Math.abs(xUI.Selection[0])+1;//削除列数を算出
	if(deleteLength>=(XPS.xpsBody.length-2)){return false;};
	var deletePoint=(xUI.Selection[0]<0)?[xUI.Select[0]+xUI.Selection[0],0]:[xUI.Select[0],0];//削除ポイントを記録

if(newNames==undefined){


	var restNames=new Array();//削除後のラベル名格納配列
//新規ラベルセット
	for(var Lidx=0;Lidx<XPS.layers.length;Lidx++){
		if((Lidx<(deletePoint[0]-1)) || (Lidx >(deletePoint[0]+deleteLength-2)) ){restNames.push(XPS.layers[Lidx].name)};
	};

//	警告
nas.showModalDialog(
	"prompt",
	deleteLength+" 個のタイムラインが削除されて以下のタイムラインが残ります。\n必要ならばレイヤ名の編集ができます。\n",
	"タイムライン削除",
	restNames.join(","),
	function(){if(this.status==0){deleteColumns(this.value)};xUI.setStored("force");sync();}
);
//		alert(newNames);
}else{
if(newNames!=null){
	newNames=newNames.split(",");
	var bkPt=xUI.Select;//カーソル元位置
	var removeIdx=[];
	for (var ix=0;ix<deleteLength;ix++){removeIdx.push(ix+deletePoint[0]);}

	var newXPS=new Xps();
	newXPS.readIN(XPS.toString());
	newXPS.deleteTL(removeIdx); 
	xUI.put(newXPS);

	// タイムライン削除後にラベルの指定があれば書きなおし(ダイアログ拡張が考慮されていないでの後で修正)
	for(var Lidx=0;Lidx<newNames.length;Lidx++){if(XPS.layers[Lidx].name != newNames[Lidx]){XPS.layers[Lidx].name=newNames[Lidx]}};

		sync("lbl");
//	nas_Rmp_Init();//リフレッシュ

	xUI.selectCell(bkPt.join("_"));//カーソルを元位置へ復帰
//	xUI.flushUndoBuf();sync("undo");//

}else{
	alert("処理を中止しました。");
};
}

};
//フレームデータ挿入
/*
	指定フレームの位置に引数データを挿入
	引数がない場合はヤンクバッファを挿入
	空フレーム挿入時は相当の空データを作成してコール
	データ形式はストリーム
 */
insertBlock=function(myStream){
	if(typeof myStream == "undefined") myStream=xUI.yankBuf;
	if(myStream.length==0) return false;
//挿入データから操作配列を作成
	var myInsert=myStream.split('\n');
    var origPoint=xUI.Select;
     var myRange=xUI.Selection;
	;//選択範囲はクリアする
	xUI.selection();//クリア
	var myRight=origPoint[0]+myInsert.length-1;
	xUI.selection([(myRight<XPS.layers.length+1)?myRight:XPS.layers.length+1,XPS.duration()-1].join("_"));//末尾まで選択
	//ヤンクバッファを使わずにレンジ内のデータを取得する
	var myBuf=xUI.getRange().split('\n');
	//バッファ内のストリームを整形して上書き用のデータを作る
	for(var lineCount=0;lineCount<myBuf.length;lineCount++){
		myBuf[lineCount]=myInsert[lineCount]+','+myBuf[lineCount];
	}
	myBuf=myBuf.join('\n');
	xUI.put(myBuf);//整形データで上書き
	xUI.selectCell(origPoint.join("_"));//挿入ポイントへ戻る
	xUI.selection(add(origPoint,myRange).join("_"));//選択範囲を戻す？
};
//空フレームデータ挿入
/*
	選択範囲に空フレームを挿入
	削除も同様の処理で可能か？
 */
insertBlank=function(){
	;//選択範囲がなければ処理なし
  if(xUI.Selection[0]==0 && xUI.Selection[1]==0){return};
    var origPoint=xUI.Select;
     var myRange=xUI.Selection;
var myLeft=(myRange[0]<0)?origPoint[0]+myRange[0]:origPoint[0];
var myTop=(myRange[1]<0)?origPoint[1]+myRange[1]:origPoint[1];
	xUI.selectCell([myLeft,myTop].join("_"));//選択範囲左上方
	xUI.selection([myLeft+Math.abs(myRange[0]),XPS.duration()-1].join("_"));//末尾まで選択
	//ヤンクバッファを使わずにレンジ内のデータを取得する
	var myBuf=xUI.getRange().split('\n');
	//挿入分の空白データを作成
	var insertBlank=Array(Math.abs(myRange[1])+1).join(',');
	//バッファ内のストリームを整形して上書き用のデータを作る
	for(var lineCount=0;lineCount<myBuf.length;lineCount++){
		myBuf[lineCount]=insertBlank+','+myBuf[lineCount];
	}
	myBuf=myBuf.join('\n');
	xUI.put(myBuf);//整形データで上書き
	xUI.selectCell(origPoint.join("_"));//挿入ポイントへ戻る
	xUI.selection(add(origPoint,myRange).join("_"));//選択範囲を復帰
};
/*
	選択範囲を削除して隙間を詰める
*/
deleteBlank=function(){
	;//選択範囲がなければ処理なし
	if(xUI.Selection[0]==0 && xUI.Selection[1]==0){return};
	var origPoint=xUI.Select;
	var myRange=xUI.Selection;
	
var myLeft=(myRange[0]<0)?origPoint[0]+myRange[0]:origPoint[0];
var myTop=(myRange[1]<0)?origPoint[1]+myRange[1]:origPoint[1];

	if(Math.abs(myRange[1])+myTop<XPS.duration()){
		xUI.selectCell(add([myLeft,myTop],[0,Math.abs(myRange[1])+1]).join("_"));//新しいポイントへ移動
		xUI.selection([myLeft+Math.abs(myRange[0]),XPS.duration()-1].join("_"));//末尾まで選択
	//ヤンクバッファを使わずにレンジ内のデータを取得する
		var myBuf=xUI.getRange().split('\n');
	//レンジ分の空白データを作成
		var tailBlank=Array(Math.abs(myRange[1])+1).join(',');
	//バッファ内のストリームを整形して上書き用のデータを作る
	for(var lineCount=0;lineCount<myBuf.length;lineCount++){
		myBuf[lineCount]=myBuf[lineCount]+','+tailBlank;;
	}
	myBuf=myBuf.join('\n');
		xUI.selectCell([myLeft,myTop].join("_"));//挿入ポイントへ戻る
		xUI.selection();//クリア
		xUI.put(myBuf);
		xUI.selectCell([myLeft,myTop].join("_"));//挿入ポイントへ戻る
//		xUI.selection();//クリア
		xUI.selection(add(origPoint,myRange).join("_"));//選択戻す?
	};
};

/*
	セルラベルの付け替え
	タイムラインIDが与えられた場合は、そのタイムラインのみ
	引数なしの場合は、すべてのタイムラインのラベルを変更
	単独ラベルの場合はタイムラインラベルの種別を判定してUIを表示する
	セル	A-Z?
	静止画	BG/BOOK インクリメント・デクリメント
	カメラワーク　FIX/PAN/SL/TU/TB/TILT/
	効果 WXP/透過光/FI/FO/OL/FLT　通常/加算/SC/覆焼/乗算/焼込/差分
	種別の編集は行わない
*/
reNameLabel=function(TimelineId)
{
	var newNames=new Array();

	var msg="タイムラインラベルを変更します。";
	if(!TimelineId){
		//全タイムラインモードを仮セット
		for (var Tidx=1;Tidx<=XPS.layers.length;Tidx++){
			newNames.push(XPS.layers[Tidx-1].name);
		};
		msg+="\n新しいラベル名セットを指定してください。\n不足分、超過分は無視されます。"
	}else{
		var kind=XPS.layers[TimelineId-1].option;
		newNames.push(XPS.layers[TimelineId-1].name);
		msg+="\n新しいラベルを指定してください。\n"+kind+":"
		msg=[msg];
		switch (kind){
		  case "dilaog":
		  	msg.push(document.getElementById("DSLabelTemplate").innerHTML);
		  break;
		  case "still":
		  	msg.push(document.getElementById("BGLabelTemplate").innerHTML);
		  break;
		  case "timing":
		  case "replacement":
		  	msg.push(document.getElementById("CLLabelTemplate").innerHTML);
		  break;
		  case "camera":
		  case "peg":
		  	msg.push(document.getElementById("CWLabelTemplate").innerHTML);
		  break;
		  case "effect":
		  case "composite":
		  	msg.push(document.getElementById("FXLabelTemplate").innerHTML);
		  break;
		}
	};

	var myFunc=function(){
	  if(! TimelineId){this.TimelineId=null}else{this.TimelineId=TimelineId};
		if((this.value=="")||(this.startValue==this.value)||(this.status >= 1)){return;};
	  var newNames=this.value;
	  if(newNames!=null){
		newNames=newNames.split(",");
		if(! this.TimelineId){
			for (var Lidx=0;Lidx<newNames.length;Lidx++){
				if((Lidx<XPS.layers.length)&&(XPS.layers[Lidx].name!=newNames[Lidx])){
//					XPS.layers[Lidx].name=newNames[Lidx];
					xUI.put([["name",Lidx].join("."),newNames[Lidx]]);
				};//&&(newNames[Lidx]!="")
			};
		}else{
//			XPS.layers[this.TimelineId-1].name=newNames[0];
			xUI.put([["name",this.TimelineId-1].join("."),newNames[0]]);
		};
		sync("lbl");
	  };
	return;
	}
	myFunc.TimelineId=TimelineId;
	newNames=nas.showModalDialog("prompt",msg,"タイムラインの変更",newNames.join(","),myFunc);

/*
	if(newNames!=null){
		newNames=newNames.split(",");
		if(!TimelineId){
			for (var Lidx=0;Lidx<newNames.length;Lidx++){
				if((Lidx<XPS.layers.length)&&(XPS.layers[Lidx].name!=newNames[Lidx])){
					XPS.layers[Lidx].name=newNames[Lidx];
				};//&&(newNames[Lidx]!="")
			};
		}else{
			XPS.layers[TimelineId-1].name=newNames[0];

		};
		sync("lbl");
	};
	return;
*/
};
//タイムラインラベル変更用ボタンメソッド
inputButtonText=function(myText){
	document.getElementById("nas_modalInput").value=myText;nas.showModalDialog("result",0);
}
// リファレンスシートのコピー
putReference=function()
{
	//xUIに範囲設定があれば、その範囲を、無ければすべてのシートを操作対象にする
	if((xUI.Selection[0]==0)&&(xUI.Selection[1]==0)){
		xUI.referenceXPS.readIN(XPS.toString());//選択範囲指定がない場合は、すべてコピー
	}else{
	//return false;
	
		var mStart=[
			(xUI.Selection[0]>0)?xUI.Select[0]:xUI.Select[0]+xUI.Selection[0],
			(xUI.Selection[1]>0)?xUI.Select[1]:xUI.Select[1]+xUI.Selection[1]
		];
		var mEnd  =[
			(xUI.Selection[0]>0)?xUI.Select[0]+xUI.Selection[0]:xUI.Select[0],
			(xUI.Selection[1]>0)?xUI.Select[1]+xUI.Selection[1]:xUI.Select[1]
		];
	//選択範囲がreferenceXPSよりも広かった場合は、参照XPSを拡張する
		
		var widthUp=   (mEnd[0]>xUI.referenceXPS.xpsBody.length)? true:false;
		var durationUp=(mEnd[1]>xUI.referenceXPS.duration())?     true:false;
		if((widthUp)||(durationUp)){
			xUI.referenceXPS.reInitBody(
				(widthUp)?    mEnd[0]:xUI.referenceXPS.xpsBody.length,
				(durationUp)? mEnd[1]:xUI.referenceXPS.duration()
			);
		};
		xUI.referenceXPS.put(mStart,xUI.getRange())
	}
	nas_Rmp_Init();
}

getReference=function()
{
	//xUIに範囲設定があれば、その範囲を、無ければすべてのシートを操作対象にする
	if((xUI.Selection[0]==0)&&(xUI.Selection[1]==0)){
		XPS.readIN(xUI.referenceXPS.toString());//選択範囲指定がない場合は、すべてコピー
	}else{
//	return false;
		var mStart=[
			(xUI.Selection[0]>0)?xUI.Select[0]:xUI.Select[0]+xUI.Selection[0],
			(xUI.Selection[1]>0)?xUI.Select[1]:xUI.Select[1]+xUI.Selection[1]
		];
		var mEnd  =[
			(xUI.Selection[0]>0)?xUI.Select[0]+xUI.Selection[0]:xUI.Select[0],
			(xUI.Selection[1]>0)?xUI.Select[1]+xUI.Selection[1]:xUI.Select[1]
		];
	//選択範囲がreferenceXPSよりも広かった場合は、参照XPSを拡張する
		
		var widthUp=   (mEnd[0]>xUI.referenceXPS.xpsBody.length)? true:false;
		var durationUp=(mEnd[1]>xUI.referenceXPS.duration())?     true:false;
		if((widthUp)||(durationUp)){
			xUI.referenceXPS.reInitBody(
				(widthUp)?    mEnd[0]:xUI.referenceXPS.xpsBody.length,
				(durationUp)? mEnd[1]:xUI.referenceXPS.duration()
			);
		};
		xUI.put(xUI.referenceXPS.getRange([mStart,mEnd]));
	}
	nas_Rmp_Init();
}
/*	セルの内容を繰り上げる/下げる
数値部分を持ったタイムラインセルの数値部分を引数分だけ操作する
通常は+1/-1
セルの内容がアルファベット一文字のみだった場合は、文字位置を引数分だけシフトする

捜査対象は選択範囲、選択範囲がなければ現在のセル
操作終了時は、開始時のセルと選択範囲を維持
// 今捜査対象がタイムライン一つだけど複数列に拡張したほうがよいかも
*/
incrementCell=function(myShift){
	if((!myShift)||(isNaN(myShift))) return ;//引数ゼロ＝操作なし　とみなす
	myShift=parseInt(myShift);
  var bkCell=xUI.Select.join("_");
	var bkSelect=[xUI.Select[0]+xUI.Selection[0],xUI.Select[1]+xUI.Selection[1]].join("_");
  var startFrm=xUI.Select[1];
  var names="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var myDepth =xUI.Selection[0]; 
  var myLength=xUI.Selection[1];
	var myStream=[];
for(var idy=0;idy<=myDepth;idy++){  
  var myBody=[];
  var currentContent=XPS.xpsBody[xUI.Select[0]].slice(startFrm,startFrm+myLength+1);
for(var idx=0;idx<currentContent.length;idx++){
	if(currentContent[idx].match(/^(\[?)([A-Z])(\]?)$/)){
		myBody.push(RegExp.$1+names.charAt((names.indexOf(RegExp.$2)+myShift+26)%26)+RegExp.$3);
	}else{
		if(currentContent[0].match(/\d/)){
			myBody.push(nas.incrStr(currentContent[idx],myShift));
		}else{
			myBody.push(currentContent[idx]);		
		}
	}
}
	myStream.push(myBody.join(","));
}
	xUI.selectCell(xUI.Select[0]+"_"+startFrm);
	xUI.selection();
	xUI.put(myStream.join("\n"));
	xUI.selectCell(bkCell);
	xUI.selection(bkSelect);
}

/*	呼び出されたら指定範囲にバルクの区間記述を入力する。

指定範囲がない場合はセレクションを使用
動作条件は、指定範囲が単一タイムラインで２フレーム以上ある場合（１フレームの区間は対象外）
選択タイムラインが
カメラワーク→両端に区間端子（三角）を置き前後に値ノードを配置する。
エフェクト→両端に区間端子シンボルを置いて注釈を挿入する。シンボルは、ラベルで判定　判定不能な場合はデフォルト
ダイアログ→サウンドエフェクト区間を入れる
セリフはダイアログの方から入力
スチル	→NOP
セル→NOP

動作終了後は、選択を解除してカーソル位置を復帰
*/
writeNewSection=function(myOpt){
  if((xUI.Selection[0]>0)||(xUI.Selection[1]<1)){return}

  var bkFrm=xUI.Select[1];
  var startFrm=xUI.Select[1];
  var myLength=xUI.Selection[1];
  var myBody=[];
 if(! myOpt){
 	myOpt=(xUI.Select[0]==0)?"dialog":(xUI.Select[0]<=XPS.layers.length)?XPS.layers[xUI.Select[0]-1].option:"comment";
 }
    switch(myOpt){
      case "camera":
      case "pan":
      case "slide":
      case "TU":
      case "TB":
      	//カメラワークトラックには値指定ブラケット付きで
      	if(startFrm>0){startFrm--}else{myLength--};
	myBody.push("[A]");
	myBody.push("▽");
	for(var idx=1;idx<myLength;idx++){myBody.push("|");}
	myBody.push("△");
	myBody.push("[B]");
      break;
      case "effect":
	myBody.push(")FX(");
	for(var idx=1;idx<myLength;idx++){myBody.push("|");}
	myBody.push(")FX(");
      break;
      case "FI":
	myBody.push("▲");
	for(var idx=1;idx<myLength;idx++){myBody.push("|");}
	myBody.push("▲");
	break;
      case "FO":
	myBody.push("▼");
	for(var idx=1;idx<myLength;idx++){myBody.push("|");}
	myBody.push("▼");
	break;
      case "transition":
      case "OL":
      case "WIPE":
	myBody.push("]><[");
	for(var idx=2;idx<(myLength/2);idx++){myBody.push("|");}
	if(myLength%2){myBody.push("↓");myBody.push("↑");}else{myBody.push("＊")}
	for(var idx=2;idx<(myLength/2);idx++){myBody.push("|");}
	myBody.push("]><[");
      break;
	case "comment":
	myBody.push("┓");
	for(var idx=2;idx<myLength+1;idx++){myBody.push("┃");}
	myBody.push("┛");
	break;
	case "timing": return;
        break;
      default:
	for(var idx=0;idx<myLength+1;idx++){myBody.push("|");}
    }

	xUI.selectCell(xUI.Select[0]+"_"+startFrm);
	xUI.selection();
	xUI.put(myBody.join(","));
	xUI.selectCell(xUI.Select[0]+"_"+bkFrm);
}

/*	呼び出されたら指定範囲に縦棒を入力する。
罫線としての「縦棒（線引き）」と、論理的な[セクション]とを分けるほうが良い
このルーチンは線引に特化させる
空白部の線引のみを行うトグル動作

指定範囲がない場合はセレクションを使用(1コマのみ処理)
選択タイムラインがカメラワーク・エフェクト・タイミングの場合は単純にセルに縦線を引く
ダイアログ、サウンド等の場合は、動作しない
開始フレームに縦棒がすでにある場合は、縦棒を削除する動作
タイミングの場合のみセルの値を判定して波線に自動変更

動作終了後は、選択を解除してカーソル位置を入力終了位置へ送り、可能ならその下へ1フレーム進める
暫定的に引数でターゲットを与える
ターゲットのシンボルのトグルとなる
*/
putSectionLine=function(myTarget){
  //if((xUI.Selection[0]>0)||(xUI.Selection[1]<1)){return}
	if (! myTarget) myTarget="|"; 
  var bkFrm=xUI.Select[1]+xUI.Selection[1]+1;
  var startFrm=xUI.Select[1];
  var myLength=xUI.Selection[1];
  var myBody=[];
  var myOpt=(xUI.Select[0]==0)?"dialog":(xUI.Select[0]<=XPS.layers.length)?XPS.layers[xUI.Select[0]-1].option:"comment";
  var currentContent=XPS.xpsBody[xUI.Select[0]].slice(startFrm,startFrm+myLength+1);
  
    switch(myOpt){
      case "dialog":     	return;
      break;
      case "camera":
      case "effect":
      case "timing":
//すでに入力されているセルはそのままで "","|",";" のみを編集対象セルにする？
//↑しない　全て上書き
for(var idx=0;idx<currentContent.length;idx++){
	if(currentContent[0]==myTarget){myBody.push("");}else{myBody.push(myTarget);}
}
      break;

      default:
	for(var idx=0;idx<myLength+1;idx++){myBody.push(myTarget);}
    }

	xUI.selectCell(xUI.Select[0]+"_"+startFrm);
	xUI.selection();
	xUI.put(myBody.join(","));
	xUI.selectCell(xUI.Select[0]+"_"+bkFrm);
//	xUI.spin("fwd");
}

/*interpSign()
引数なし
選択範囲のない場合
フォーカスのあるシートセルに、補間サインを入力してスピンする
補間サインだった場合は補完サインの種別を変更してスピンを留保する
種別ループに消去あり? > なし　消去はDELキー

有効記述だった場合はNOP？

選択範囲がある場合　範囲が一列ならばそのまま動作対象に
複数列の場合はフォーカスのある一列に変更して
その区間にSPIN指定の間隔で補完サインを配置する。基点は選択範囲の最も上のシートセル
*/
interpSign=function(){
	var interpRegex=new RegExp("["+InterpolationSigns.join("")+"]");
	var myValue = XPS.xpsBody[xUI.Select[0]][xUI.Select[1]];
  if(xUI.Selection.join(",")=="0,0"){
	if(myValue.match(interpRegex)){
	//	alert(InterpolationSigns.indexOf(myValue));
		var newValue=InterpolationSigns[((InterpolationSigns.indexOf(myValue))+1) % InterpolationSigns.length];
		xUI.put(newValue);
//		xUI.spin("fwd");
	}else	if(true){
//		xUI.put(InterpolationSigns[0]);//InterpolationSigns[InterpolationSigns.length-1];
		xUI.put(nas_expdList(InterpolationSigns[0]));
		xUI.spin("down");
	}else{
		return;
	}
  }else{
	var myRange=xUI.actionRange();
	var currentColumn=xUI.Select[0];//現在のカラム
	xUI.selectCell([currentColumn,myRange[0][1]]);
	xUI.selection([currentColumn,myRange[1][1]]);
	xUI.put(nas_expdList("/-/"));
	xUI.selectCell([currentColumn,myRange[0][1]]);
  }
}
/*addCircle()
引数なし
選択範囲のない場合
フォーカスのあるシートセルが、空白、カラセル、補間サイン、空白の線引であった場合は　NOP
正確には、有効記述のみを処理するべき
有効記述だった場合は、丸囲み＝（丸括弧）付加 または 削除

選択範囲がある場合　範囲が一列ならばそのまま動作対象に
複数列の場合はフォーカスのある一列に変更して
その区間の全てのシートセルを処理
*/
addCircle=function(){
	var interpRegex=new RegExp("["+InterpolationSigns.join("")+"]");
//コレは基礎オブジェクトに移行 …というか、総合判定メソッドが必要（ケースで判断が変わる）
//後で置き換え
	var newValue=new Array();
	var myRange=xUI.actionRange();
	var currentColumn=xUI.Select[0];//現在のカラム
	xUI.selectCell([currentColumn,myRange[0][1]]);
	xUI.selection([currentColumn,myRange[1][1]]);
//	if(xUI.Selection.join(",")!="0,0") xUI.selection([currentColumn,myRange[1][1]]);
	for(var f=myRange[0][1];f<=myRange[1][1];f++){
		var myValue = XPS.xpsBody[currentColumn][f];
		if(	(myValue!="")&&
			(!(myValue.match(interpRegex)))&&
			(!(myValue.match(/[|｜￤;:X✗×]/)))
		){
		  if(myValue.match(/^\((.*)\)$/)){
			newValue.push(RegExp.$1);
		  }else{
			newValue.push("("+myValue+")");
		  }
		}else{
			newValue.push(myValue);
		}
	}
	if(newValue.length){
		
		xUI.put(newValue.join(","));
		xUI.selectCell([currentColumn,myRange[0][1]]);
	}
	if(newValue.length==1)xUI.spin("fwd");
}
/*addBrackets()
引数なし
選択範囲のない場合
フォーカスのあるシートセルが、空白、カラセル、補間サインであった場合は　NOP
有効記述だった場合は、囲み＝[角括弧]付加 または 削除

選択範囲がある場合　範囲が一列ならばそのまま動作対象に
複数列の場合はフォーカスのある一列に変更して
その区間の全てのシートセルを処理
*/
addBrackets=function(){
	var interpRegex=new RegExp("["+InterpolationSigns.join("")+"]");
//コレは基礎オブジェクトに移行 …というか、総合判定メソッドが必要（ケースで判断が変わる）
//後で置き換え
	var newValue=new Array();
	var myRange=xUI.actionRange();
	var currentColumn=xUI.Select[0];//現在のカラム
	xUI.selectCell([currentColumn,myRange[0][1]]);
	xUI.selection([currentColumn,myRange[1][1]]);
//	if(xUI.Selection.join(",")!="0,0") xUI.selection([currentColumn,myRange[1][1]]);
	for(var f=myRange[0][1];f<=myRange[1][1];f++){
		var myValue = XPS.xpsBody[currentColumn][f];
		if(	(myValue!="")&&
			(!(myValue.match(interpRegex)))&&
			(!(myValue.match(/[|｜￤;:X✗×]/)))
		){
		  if(myValue.match(/^\[(.*)\]$/)){
			newValue.push(RegExp.$1);
		  }else{
			newValue.push("["+myValue+"]");
		  }
		}else{
			newValue.push(myValue);
		}
	}
	if(newValue.length){
		
		xUI.put(newValue.join(","));
		xUI.selectCell([currentColumn,myRange[0][1]]);
	}
	if(newValue.length==1)xUI.spin("fwd");
}
/*
	タイムラインをセクションへ変換する関数
	Section オブジェクトは　Timeline.sectionsのメンバーである
	sections[0]〜　メンバーは以下のプロパティを持つ
	Section.inpoint	: Int Frames
	Section.duration	: Int Frames 
	Section.body 	: Array.
	Section.isInterp	: Bool 補間フラグ
	Section.value		: String 値 Timeline.valueAt()関数はこの値から現在の値を算出する
	値は空白の場合がある　未定義の値は空白となる場合がある
	補間フラグがあればその区間は中間値補間区間となる
	補間区間は基本的に値を持たず、前後区間の値を補完する
	補間区間が連続する場合は前方区間が終了値を持つ場合がある
		セクションは必ずタイミングを持つ
	Section.timing	:タイミングオブジェクトまたはタイミング記述？
	
	
	セクション編集時はタイムライン全体をバッファにとって編集する
	編集後のストリームをシート上にputして編集を終了する
	りまぴんでは編集のたびにセクションを含むタイムラインをパースする
	キャッシュは行われない
*/

/*
	このファイルの関数は基本的にはxUIまたはXPSのメソッドなので
	デバグ終了後には必要に応じてラッパ関数を残してふさわしい位置へ移動すること。
	2007/06/29

*/