var LoadImage = Class.create({
/**
 * 初期化時
 */
initialize: function(imgPath, fileName, options){
    // フォルトオプション
    this.options = {
        parent     : $$('body')[0],             // 基点エレメント
        unique     : +(new Date()),             // 生成フレームのID用
        idPrefix   : 'image',                   // ID、クラス用プレフィックス
        height     : 328,                       // イメージの高さ
        width      : 500,                       // イメージの幅
        top        : 0,                         // デフォルト表示位置
        left       : 0,                         // デフォルト表示位置
        anchor     : null,                      // クリックイベントを設定する場合は関数を文字列で指定
        header     : false,                     // ヘッダを表示する場合にTRUE
        absolute   : false,                     // ポジション
        draggable  : false,                     // ドラッグ可能かどうか(コスト高)
        shadow     : 6,                         // 影の幅
        frame      : 8,                         // フレームの幅
        indicatorSrc : 'img/common/spinner.gif',// インジケータイメージ※nullまたは空文字でインジケータを使用しない
        indiHeight : 8,                         // インジケータ高さ
        indiWidth  : 8,                         // インジケータ幅
        closeBtnSrc: 'img/common/btn_close.gif',// 閉じるボタンイメージ
        imgTitle   : fileName,                  // イメージのタイトル
        imgAlt     : fileName,                  // イメージ代替用文字列
        insPos     : 'bottom'                   // 親要素のどこに挿入するかを指定
    };

    Object.extend(this.options, options);


    // イメージ生成
    var targetImage = new Image();
    targetImage.src = imgPath + fileName;

    // フレーム生成
    this.setFrame();

    var timer = null;
    if(targetImage.complete) {
        dbg('image complete : ' + targetImage.src);
        this.showImage(targetImage);
    } else {
        // 画像の読み込みが終了するまで再帰的に処理
        this.imageOnLoad = function() {
            if(targetImage.complete) {
                dbg('imageOnLoad complete : ' + targetImage.src);
                clearTimeout(timer);
                this.showImage(targetImage);
            } else {
                timer = setTimeout(this.imageOnLoad.bind(this), 100);
            }
        };
        this.imageOnLoad();
    }

},
/**
 * フレームブロックの生成
 */
setFrame: function(){

    /* ID */
    var wrapId = this.options.idPrefix + 'Detail_' + this.options.unique;
    var shadowId = this.options.idPrefix + 'Shadow_' + this.options.unique;
    var frameId = this.options.idPrefix + 'Frame_' + this.options.unique;
    var indicatorId = this.options.idPrefix + 'Spinner_' + this.options.unique;
    var imgId = this.options.idPrefix + 'Img_' + this.options.unique;

    // 仮に同IDがあった場合は容赦なく削除
    if($(wrapId)){
        $(wrapId).remove();
    }

    // フレームテンプレートを生成
    var temp = new Template(this.tempFrame);
    temp = temp.evaluate({ idPrefix      : this.options.idPrefix,
                           unique        : this.options.unique,
                           spinnerSrc    : this.options.indicatorSrc != null ? this.options.indicatorSrc : '',
                           imgAlt        : this.options.imgAlt,
                           imgTitle      : this.options.imgTitle
                         });
    // フレームを挿入
    var insOpt = {bottom: temp};
    if(this.options.insPos == 'top'){
        insOpt = {top: temp};
    }

    $(this.options.parent).insert(insOpt);

    // インジケータソースが未指定の場合は使用しない
    if(this.options.indicatorSrc == null || this.options.indicatorSrc == ''){
        $(indicatorId).hide();
    }

    // 縦横の設定
    var hImg = this.options.height;
    var wImg = this.options.width;

    var hBlk = (this.options.height + this.options.frame);
    var wBlk = (this.options.width + this.options.frame);

    // ポジション
    var topPosi = (wBlk - hBlk) / 2;
    var leftPosi = 0;

    /* スタイル設定 */

    var posi = 'relative';
    if(this.options.absolute){
        posi = 'absolute';
    }
    $(wrapId).setStyle({position : posi,
                        top      : this.options.top + 'px',
                        left     : this.options.left + 'px',
                        height   : (this.options.frame != 0 ? (wBlk >= hBlk ? wBlk:hBlk) : hBlk) + 'px',
                        width    : (this.options.frame != 0 ? (wBlk >= hBlk ? wBlk:hBlk) : wBlk) + 'px'});


    // 影は指定幅0なら削除
    if(this.options.shadow != 0){
        $(shadowId).setStyle({top    : (topPosi + this.options.shadow) + 'px',
                              left   : (leftPosi + this.options.shadow) + 'px',
                              height : hBlk + 'px',
                              width  : wBlk + 'px'});
    } else {
        $(shadowId).remove();
    }

    // フレーム
    $(frameId).setStyle({top       : (this.options.frame != 0 ? topPosi : 0) + 'px',
                         left      : (this.options.frame != 0 ? leftPosi : 0) + 'px',
                         height    : hBlk + 'px',
                         width     : wBlk + 'px',
                         border    : this.options.frame != 0 ? '1px solid gray' : 'none'});

    // インジケータ
    $(indicatorId).setStyle({top      : ((hImg - this.options.indiHeight) / 2) + 'px',
                             left     : ((wImg - this.options.indiWidth) / 2) + 'px'});


    $(imgId).setStyle({margin  : (this.options.frame / 2) + 'px', height: hImg + 'px', width: wImg + 'px'});
    $(imgId).setOpacity(0);

    // クリックイベント用アンカー
    if(this.options.anchor != null){
        var hrefStr = 'javascript:;';
        if(Object.isString(this.options.anchor)){
            hrefStr = this.options.anchor;
        }

        $(imgId).wrap('a' ,{ 'id'     : this.options.idPrefix + 'Lnk_' + this.options.unique,
                             'href'   : hrefStr});
        if(Object.isFunction(this.options.anchor)){
            Event.observe(this.options.idPrefix + 'Lnk_' + this.options.unique, 'click', this.options.anchor);
        }
    }

    // ヘッダ
    if(this.options.header){

        var header = new Template(this.tempHeader);
        header = header.evaluate({ idPrefix      : this.options.idPrefix,
                                   unique        : this.options.unique,
                                   closeBtnSrc   : this.options.closeBtnSrc,
                                   wrapId        : wrapId,
                                   shadowId      : shadowId,
                                   frameId       : frameId,
                                   imgId         : imgId
                                  });

        // ヘッダの挿入
        $(frameId).insert({bottom: header});

        var headerId = this.options.idPrefix + 'Header_' + this.options.unique;

        /* スタイル指定 */
        $(headerId).setStyle({top        : (this.options.frame / 2) + 'px',
                              left       : (this.options.frame / 2) + 'px',
                              width      : wImg + 'px'});
    }

    // フレーム表示
    $(wrapId).show();
},
/**
 * 画像の表示
 */
showImage: function(targetImage){

    /* IDの設定 */
    var wrapId = this.options.idPrefix + 'Detail_' + this.options.unique;
    var frameId = this.options.idPrefix + 'Frame_' + this.options.unique;
    var spinnerId = this.options.idPrefix + 'Spinner_' + this.options.unique;
    var imgId = this.options.idPrefix + 'Img_' + this.options.unique;

    // イメージ設定
    $(imgId).writeAttribute({'src' : targetImage.src});

    // Spinnerの非表示
    $(spinnerId).hide();

    // 縦横比が逆の場合、縦横再設定
    if(targetImage.width < targetImage.height){

        var hImg = this.options.width;
        var wImg = this.options.height;

        var hBlk = (this.options.width + this.options.frame) ;
        var wBlk = (this.options.height + this.options.frame);

        var leftPosi = (hBlk - wBlk) / 2;
        var topPosi = 0;

        // 影は指定幅0なら削除
        if(this.options.shadow != 0){
            var shadowId = this.options.idPrefix + 'Shadow_' + this.options.unique;
            $(shadowId).setStyle({top    : (topPosi + this.options.shadow) + 'px',
                                    left   : (leftPosi + this.options.shadow) + 'px',
                                    height : hBlk + 'px',
                                    width  : wBlk + 'px'});
        }

        // フレーム
        $(frameId).setStyle({top       : (this.options.frame != 0 ? topPosi : 0) + 'px',
                              left      : (this.options.frame != 0 ? leftPosi : 0) + 'px',
                              height    : hBlk + 'px',
                              width     : wBlk + 'px'});

        $(imgId).setStyle({ height: hImg + 'px', width: wImg + 'px'});

        // ヘッダの再設定
        if(this.options.header){
            var headerId = this.options.idPrefix + 'Header_' + this.options.unique;
            $(headerId).setStyle({ width      : wImg + 'px'});
        }

    }

    // ドラッグドロップ許可時
    if(this.options.draggable){
        new Draggable(wrapId);
    }

    // イメージ表示
    Effect.Appear(imgId);

    dbg('show image : ' + $(imgId).src);
    dbg('-----------------------------');
},

remove:function(){
    $(this.options.idPrefix + 'Detail_' + this.options.unique).remove();
},

/**
 * フレームテンプレート
 */
tempFrame: '<div id="#{idPrefix}Detail_#{unique}" class="#{idPrefix}Detail" style="position:relative;display:none;">'
           +     '<div id="#{idPrefix}Shadow_#{unique}" class="#{idPrefix}Shadow" style="position:absolute;background-color:silver;" >'
           +     '</div>'
           +     '<div id="#{idPrefix}Frame_#{unique}" class="#{idPrefix}Frame" style="position:absolute;top:0px;left:0px;background-color:white;">'
           +         '<img id="#{idPrefix}Spinner_#{unique}" src="#{spinnerSrc}" alt="now loading..." title="now loading..."'
           +              'style="position:absolute;border:none;" />'
           +         '<img id="#{idPrefix}Img_#{unique}" class="#{idPrefix}Img" alt="#{imgAlt}" title="#{imgTitle}" '
           +              'style="border:none;display:none;" />'
           +     '</div>'
           + '</div>',
/**
 * ヘッダテンプレート
 */
tempHeader:  '<div id="#{idPrefix}Header_#{unique}" class="#{idPrefix}Header" style="position:absolute;height:auto;padding-top:3px;text-align:right;">'
           +    '<a id="#{idPrefix}CloseLnk_#{unique}" class="frameCloseLnk" style="text-decoration:none;border:none;" '
           +       'onclick="$(\'#{idPrefix}Header_#{unique}\').remove();$(\'#{shadowId}\').remove();'
           +                'new Effect.Opacity(\'#{frameId}\',{duration: 0.5,to:0.2});'
           +                'Effect.Puff(\'#{imgId}\', {afterFinishInternal: function(effect) {$(\'#{wrapId}\').remove();}});">'
           +        '<img src="#{closeBtnSrc}" alt="閉じるボタン" title="この画像を閉じる" style="margin-left:auto;margin-right:3px;border:none;" />'
           +    '</a>'
           + '</div>'
});
