
/**
 * Product:     Custom Product Preview
 * Package:     Aitoc_Aitcg_1.0.3_1.0.0_92820
 * Purchase ID: n/a
 * Generated:   2011-07-19 20:15:39
 * File path:   js/aitoc/aitcg/aitcg.js
 * Copyright:   (c) 2011 AITOC, Inc.
 */
var Aitcg = {
    editors: {},
    cachedImages : {},
    
    loadAreaEditor : function(optionId) {
        if(typeof(this.editors['ed_'+optionId]) == 'undefined') {
            this.editors['ed_'+optionId] = new Aitcg.AreaEditor(optionId);
        }
        var editor = this.editors['ed_'+optionId];
        editor.loadEditor();
    },

    clone : function(el) {
        if(typeof(JSON)!='undefined') {
            return eval('(' + JSON.stringify(el) + ')');
        } else {
            return this.deepCloneJSON(el);
        }
    },
    
    deepCloneJSON: function(obj) {
        var outpurArr = new Array();
        for (var i in obj) {
            outpurArr[i] = typeof (obj[i]) == 'object' ? this.deepCloneJSON(obj[i]) : obj[i];
        }
        return outpurArr;
    },    
    
    cacheImage : function(imgId, path, callback) {
        if(typeof(this.cachedImages[imgId]) == 'undefined') {
            
            this.cachedImages[imgId] = document.createElement('img');
            var img = this.cachedImages[imgId];
    
            Event.observe(img,'load',callback.cached.bind(callback))
            img.src = path;
            
        }else{
            callback.cached();
        }
    }, 
    
    getImageData : function( imgId ) {
        return {
            origW:this.cachedImages[imgId].width,
            origH:this.cachedImages[imgId].height
        }        
    }, 
    
    getDefault : function() {
        return {
            dim: document.viewport.getDimensions(),
            off: document.viewport.getScrollOffsets(),
            curr: {}
        };        
    },
    
    countMult : function( imgId ) {
        scr = this.getDefault();
        if(imgId != 0) {
            scr.orig = this.getImageData(imgId);
        } else {
            scr.orig = {origW:arguments[1],
                origH:arguments[2]};
        }
        var mult = 1;
        var offsetX = 30;
        var offsetY = 75;
        
        if(scr.orig.origW > (scr.dim.width-offsetX)) {
            mult = (scr.dim.width-offsetX) / scr.orig.origW;
        }

        if(scr.orig.origH > (scr.dim.height-offsetY)) {
            var mY = (scr.dim.height-offsetY) / scr.orig.origH;
            if (mY < mult) {
                mult = mY;
            }
        }
        scr.mult = mult;
        
        if (mult !== 1) {
            scr.curr.width = Math.round(scr.orig.origW * mult);
            scr.curr.height = Math.round(scr.orig.origH * mult);
        } else {
            scr.curr.width = scr.orig.origW;
            scr.curr.height = scr.orig.origH;
        }
                
        return scr;
    },
    
        sizesCache: {},
        
        /**
         *  if you've made changes in this method be sure to
         *  make same changes in Aitoc_Aitcg_Model_Image
         */        
        checkSizes : function(imgX, imgY, maxX, maxY) {
            var id = 'id'+imgX + '_'+imgY+'_'+maxX+'_'+maxY;
            if(typeof(this.checkSizes[id]) != 'undefined') {
                return this.checkSizes[id];
            }
            var minpx = 0;
            var x = imgX/maxX,
                y = imgY/maxY;
            var ret = {};
            if( x > y && x > 1) {
                ret =  this.calcSizes(imgX,imgY, maxX, maxY);
                ret.axis = 'x';
            } else if( y > 1 ){
                var t = this.calcSizes(imgY,imgX, maxY, maxX);
                ret = {x:t.y,y:t.x};
                ret.axis = 'y';
            } else {
                ret = {x:imgX,y:imgY};
                ret.axis = 'b';
            }
            if(ret.x > maxX || ret.y > maxY) {
                var scale_x = maxX / ret.x,
                    scale_y = maxY / ret.y;
                if( scale_x < scale_y ) {
                    ret.y = ret.y * ret.x / maxX;
                    ret.x = maxX;
                    ret.axis = 'y';
                } else {
                    ret.x = ret.x * ret.y / maxY;
                    ret.y = maxY;
                    ret.axis = 'x';
                }
            }
            ret["posX"] = Math.round((maxX-ret.x)/2);
            ret["posY"] = Math.round((maxY-ret.y)/2);
            ret.mult = ret.x / imgX;
            return ret;
        },
        calcSizes : function(a, b, maxa, maxb) {
            maxa = maxa;
            maxb = b * maxa / a;
            return { x : maxa,y : maxb };
        }
    
};

Aitcg.AreaEditor = Class.create({
    
    // current option id
    optionId : null,

    // selected option image id
    imgId : null,
    
    // prefix used to access coords elements
    pfx : null,
    
    // information about image
    imgInfo : {},
    
    // some data
    currentImage : {},
    
    croper : null,
    
    initialize: function(optionId) {
        this.optionId = optionId;
        this.pfx = 'product_option_'+optionId+'_coords_';
    },
    
    loadEditor : function() {
        $('loading-mask').show();
        this.imgId = $(aitcgImageSelector.id+'_'+this.optionId).value;
        this.imgInfo = aitcgImageSelector.customImages[this.imgId];
        Aitcg.cacheImage(this.imgId, this.imgInfo['full_image'], this);
    },
    
    cached : function() {
        $('loading-mask').hide();
        this.showEditor();
    },
    
    showEditor : function() {
        this.currentImage.origW=Aitcg.cachedImages[this.imgId].width;
        this.currentImage.origH=Aitcg.cachedImages[this.imgId].height;
        this.currentImage.mult = this.countMult();

        // calculating image view size
        //if (this.mult !== 1) { //!!!!!!!!!!! - to check
        if (this.currentImage.mult !== 1) {
            this.currentImage.width = Math.round(this.currentImage.origW*this.currentImage.mult);
            this.currentImage.height = Math.round(this.currentImage.origH*this.currentImage.mult);
        } else {
            this.currentImage.width = this.currentImage.origW;
            this.currentImage.height = this.currentImage.origH;
        }
        
        // some window rendering variables
        this.imgInfo['img_width'] = this.currentImage.width;
        this.imgInfo['img_height'] = this.currentImage.height;
        this.imgInfo['option_id'] = this.optionId;

        // window rendering
        var window = new Aitcg.Popup(PrintableAreaEditor, this.imgInfo);
        html = window.render();
        Element.insert($('anchor-content'),{before : html});

        var height = $('html-body').getHeight();
        $('message-popup-window-mask').setStyle({'height':height+'px'});
        $('message-popup-window').setStyle({
            'width'      : 'auto',
            'top'        : '' + parseInt((this.currentImage.scr.dim.height-this.currentImage.height-10)/2 + this.currentImage.scr.off.top) + 'px',
            'marginLeft' : '-'+(parseInt(this.currentImage.width/2+4))+'px'
        });
        Element.show('message-popup-window-mask');
        $('message-popup-window').addClassName('show');

        Draggables.drags = [];
        this.cropper = new Cropper.Img('printable-area-image', {
            onloadCoords : {
                x1 : Math.round(parseInt($(this.pfx+'offset_x').value?(parseInt($(this.pfx+'offset_x').value)-1):0)*this.currentImage.mult),
                y1 : Math.round(parseInt($(this.pfx+'offset_y').value?(parseInt($(this.pfx+'offset_y').value)-1):0)*this.currentImage.mult),
                x2 : Math.round((parseInt($(this.pfx+'size_x').value)?(parseInt($(this.pfx+'offset_x').value)+parseInt($(this.pfx+'size_x').value)+1):(Aitcg.cachedImages[this.imgId].width))*this.currentImage.mult),
                y2 : Math.round((parseInt($(this.pfx+'size_y').value)?(parseInt($(this.pfx+'offset_y').value)+parseInt($(this.pfx+'size_y').value)+1):(Aitcg.cachedImages[this.imgId].height))*this.currentImage.mult)
            },
            displayOnInit : true
        });
    },

    countMult : function() {
        this.currentImage.scr = {
            dim: document.viewport.getDimensions(),
            off: document.viewport.getScrollOffsets()
        };
        var mult = 1;
        var offsetX = 30;
        var offsetY = 100;

        if(this.currentImage.origW > (this.currentImage.scr.dim.width-offsetX)) {
            mult = (this.currentImage.scr.dim.width-offsetX) / this.currentImage.origW;
        }

        if(this.currentImage.origH > (this.currentImage.scr.dim.height-offsetY)) {
            var mY = (this.currentImage.scr.dim.height-offsetY) / this.currentImage.origH;
            if (mY < mult) {
                mult = mY;
            }
        }
        return mult;
    },
    
    applyCoords : function() {
        var coords = this.cropper.areaCoords;
        $(this.pfx+'offset_x').value = Math.round((coords.x1+1)/this.currentImage.mult);
        $(this.pfx+'offset_y').value = Math.round((coords.y1+1)/this.currentImage.mult);
        $(this.pfx+'size_x').value = Math.round((coords.x2-coords.x1-2)/this.currentImage.mult);
        $(this.pfx+'size_y').value = Math.round((coords.y2-coords.y1-2)/this.currentImage.mult);
        this.closeEditor();
    },
    
    closeEditor : function() {
        this.cropper.remove();
        Draggables.drags = [];
        $('message-popup-window').remove();
        $('message-popup-window-mask').remove();
        aitcgImageSelector.reloadImage(this.optionId);
    }
    
});

Aitcg.Popup = Class.create({
    template : null,
    options : {},
    templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
    
    initialize: function(template, options) {
        this.template = template;
        this.options = options;
    },

    render: function() {
        var popup = new Template(this.template, this.templateSyntax);
        var html = popup.evaluate(this.options);
        return html;
    },
    
    renderWindow: function ( imgId, fullUrl, callback ) {
        if( $('loading-mask') == null ) {
            if(typeof(AitPopupHtml)!= 'undefined') {
                $$('body')[0].insert( {after:AitPopupHtml} );
            } else {
                document.body.appendChild( '<div id="loading-mask">Please wait...</div>' );
            }
        }
        $('loading-mask').show();
        Aitcg.cacheImage(imgId, fullUrl, callback);
    },
    
    showTextWindow: function ( ) {
        // window rendering
        var scr = Aitcg.getDefault();
        //var window = new Aitcg.Popup(PrintableAreaEditor, this.imgInfo);
        var body = $$('body')[0];        
        Element.insert(body,{before : this.render() });
        var height = body.getHeight();
        $('message-popup-window-mask').setStyle({'height':height+'px'});
        $('message-popup-window').setStyle({
            'width'      : '' + parseInt(scr.dim.width*3/4) +'px',
            'top'        : '' + parseInt(50 + scr.off.top) + 'px',
            'marginLeft'       : '-' + parseInt(scr.dim.width*3/8) + 'px'
        });
        Element.show('message-popup-window-mask');
        $('message-popup-window').addClassName('show');         
    }, 
    
    showWindow: function ( imgId ) {
        var scr = Aitcg.countMult( imgId );
        
        // some window rendering variables for templates
        this.options['img_width'] = scr.curr.width;
        this.options['img_height'] = scr.curr.height;
        
        //if(typeof(arguments[1])!='undefined' && arguments[1]==true) {
            this.options['width']   = Math.floor(this.options.areaSizeX * scr.mult)+"px";
            this.options['height']  = Math.floor(this.options.areaSizeY * scr.mult)+"px";
            this.options['left']    = Math.max(0, Math.round(this.options.areaOffsetX * scr.mult - 1))+"px";
            this.options['top']     = Math.max(0, Math.round(this.options.areaOffsetY * scr.mult - 1))+"px";            
        //}
        
        // window rendering
        //var window = new Aitcg.Popup(PrintableAreaEditor, this.imgInfo);
        var body = $$('body')[0];        
        Element.insert(body,{before : this.render() });
        var height = body.getHeight();
        $('message-popup-window-mask').setStyle({'height':height+'px'});
        $('message-popup-window').setStyle({
            'width'      : 'auto',
            'top'        : '' + parseInt((scr.dim.height-scr.curr.height-10)/2 + scr.off.top) + 'px',
            'marginLeft' : '-'+(parseInt(scr.curr.width/2+4))+'px'
        });
        Element.show('message-popup-window-mask');
        $('message-popup-window').addClassName('show');         
        return scr;
    }, 
    closeEditor : function() {
        $('message-popup-window').remove();
        $('message-popup-window-mask').remove();
    }
    
});

Aitcg.Uploader = Class.create({
    //unique Id of class, must be reloaded
    id: "",
    lastUploadedFile: {},
    imgData : {},
    hidden : false,
    editorEnabled: false,
    force_show : false,

    window: null,
    paper : null,
    raph : null,
    imgThumbSelector : null,
    
    updateUrl : '/aitcg/ajax/update',
    
    initialize : function(id) {
        this.id = id;
        this.imgThumbSelector = '#' +this.id + '_imagediv div.th';
    },
    
    toggleDelete: function() {},
    
    getThumbnailImgHtml: function(productUrl, previewUrl) {
        var template = new Template('<img src="{{productUrl}}" class="bg" /><div class="th"><div><img src="{{previewUrl}}" class="ith" /></div></div>', /(^|.|\r|\n)({{(\w+)}})/);
        return template.evaluate({productUrl:productUrl,previewUrl:previewUrl});        
    },
    
    getPopupTemplate: function() {
        var str = '<div id="message-popup-window-mask" onclick="opFile{{rand}}.closeEditor();"></div>'+
            '<div id="message-popup-window" class="message-popup print-area-editor">'+
                '<div class="message-popup-head">'+
                    '<a href="#" onclick="opFile{{rand}}.closeEditor(); return false;" title="{{close_text}}"><span>{{close_text}}</span></a>'+
                    '<h2></h2>'+
                '</div>'+
                '<div class="aitclear"></div>'+
                '<div class="message-popup-ait" style="width:{{img_width}}px;height:{{img_height}}px">'+
                    '<img src="{{full_image}}" id="printable-area-image" width="{{img_width}}" height="{{img_height}}" alt="" />'+
                    '<div id="{{option_id}}_raph" class="message-popup-aitraph" style="left:{{left}};top:{{top}};width:{{width}};height:{{height}};"></div>'+
                '</div>'+
                '<div class="message-popup-head"  id="qqq">'+
                (this.editorEnabled? '<a class="apply-but" href="#" onclick="opFile{{rand}}.apply(); return false;" title="{{apply_text}}">{{apply_text}}</a>'+
                    '<a class="reset-but" href="#" onclick="opFile{{rand}}.reset(); return false;" title="{{reset_text}}">{{reset_text}}</a>':'')+
                '</div>'+
            '</div>';
        return str;
    },
    
    getTextPopupTemplate: function() {
        var str = '<div id="message-popup-window-mask" onclick="opFile{{rand}}.agree(false);"></div>'+
                '<div id="message-popup-window" class="aitcgpopup">'+
                    '<div class="aitcgpopInner"><a class="close_btn" onclick="opFile{{rand}}.agree(false); return false;" ></a></div>'+
                    '<div class="aitcgpop_text">{{text}}</div>'+
                    '<a class="aitcgpop_btn" onclick="opFile{{rand}}.agree(true); return false;"><div class="pop_btn_right"></div><p>{{agree_text}}</p></a>'+
                  '</div>';
        return str;
    },
    
    updateData: function() {
        var param = this.imgData;
        param.template_id = this.tempId;
        param.product_id = this.product_id;
        if(typeof(this.cart_option_id)!='undefined') {
            param.cart_option_id = this.cart_option_id;
            param.cart_item_id = this.cart_item_id;
        }
        param.aittype = this.aittype;
        new Ajax.Request(this.updateUrl, {
            method: 'post',
            parameters: param,
            evalJSON: 'force',
            onSuccess: function(response) {
                this.updateThumbnail(response.responseJSON).bind(this);
            }.bind(this)
        });
        return false;
    },            
    
    loadThumbnailImage: function( tempId, tempThumbUrl, tempFullUrl, param  ) 
    {
        this.tempThumbUrl = tempThumbUrl;
        this.tempFullUrl = tempFullUrl;
        this.tempImageSizes = {full_x: param.full_x, full_y: param.full_y};
        var el = $(this.id + '_imagediv');
            el.update( this.getThumbnailImgHtml(this.productImageThumbnailUrl, tempThumbUrl) ).show();
        if(this.obs == 0) {
            el.observe('click', this.showEditor.bind(this));
            this.obs = 1;
        }
        this.applyImgData(param);
        this.setTemplateId(tempId);            
    },
    

    toggleFileChange: function(inputBox) {
        this.initializeFile(inputBox);
        inputBox.toggle();
        this.fileChangeFlag = this.fileChangeFlagForse ? true : (this.fileChangeFlag ? false : true);
        if (!this.fileDeleteFlag) {
            if (this.fileChangeFlag) {
                 this.inputFileAction.value = 'save_new';
                 this.inputFile.disabled = false;
             } else {
                 this.inputFileAction.value = 'save_old';
                 this.inputFile.disabled = true;
             }
        }
    },

    toggleFileDelete: function(fileDeleteFlag, inputBox) {
        this.initializeFile(inputBox);
        this.fileDeleteFlag = fileDeleteFlag.checked ? true : false;
        if (this.fileDeleteFlag) {
            this.inputFileAction.value = '';
            this.inputFile.disabled = true;
            this.previewFile.disabled = true;
            $(this.id + '_template_id').value = this.tempId;
            this.fileNameBox.setStyle({'text-decoration': 'line-through'});
        } else {
            this.inputFileAction.value = this.fileChangeFlag ? 'save_new' : 'save_old';
            this.inputFile.disabled = (this.fileChangeFlag == 'save_old');
            this.fileNameBox.setStyle({'text-decoration': 'none'});
            this.previewFile.disabled = false;
            $(this.id + '_template_id').value = 0;
        }
        $(this.id + '_template_type').value = this.aittype;
    },
    
    manageUploadedFile : function(response) 
    {
        if(response.error != '0') {
            if(response.message != "")
                $(this.id + "_error").update(response.message).show();
        } else {
            this.updateImage(response);
            this.toggleInputFileFields();
            this.lastUploadedFile = response;
            
            this.loadThumbnailImage(response.temp_id, response.temp_thumbnail_url, response.temp_image_url, {
                full_x: response.preview_width, 
                full_y: response.preview_height,
                x : response.x,
                y : response.y,
                scale_x : response.scale_x,
                scale_y : response.scale_y,
                angle :  response.angle
            });
            
            this.imgData.x = this.defaultCoords.x;
            this.imgData.y = this.defaultCoords.y;
            this.updateData();
        }
    },
    
    setTemplateId: function( id )
    {
        if($(this.id + '_template_id') != null)
            $(this.id + '_template_id').value = id;
        this.tempId = id;
    },
    
    updateImage: function(resp) 
    {
        $$('#'+this.id + '_filename span')[0].update(resp.file_name);
    },
    
    toggleInputFileFields: function() 
    {
        if(this.hidden) {                
            $(this.id + '_id').show();
            $(this.id + '_filename').hide();
        } else {
            $(this.id + '_id').hide();
            $(this.id + '_filename').show();
        }
        this.hidden =  ! this.hidden;
    }, 
    
    checkConfirmBox : function(el) {
        el = $(el).previous();
        if(typeof(this.text.confirm)=='undefined' || this.text.confirm=='') {
            return false;
        }
        /*if(typeof(window.aitCheckboxConfirmed) == 'number') {
            return false;
        }
        window.aitCheckboxConfirmed = 1;*/
        this.window = new Aitcg.Popup(this.getTextPopupTemplate(true), {            
            full_image : this.productImageFullUrl,
            rand: this.rand,
            option_id: this.id,
            close_text: this.text.close,
            agree_text: this.text.agree,
            text: this.text.confirm
        } );
        var scr = this.window.showTextWindow( this.id );
        return false;
    },
    agree : function( data ) {
        if(data)
            $(this.id+'_checkbox').checked = true;
        this.window.closeEditor( );
        this.window = null;
    },
    
    closeEditor : function() {
        this.window.closeEditor( );
        this.window = null;
    },
    
    showEditor : function() {
        if( this.window != null ) {
            this.closeEditor();
        }
        this.window = new Aitcg.Popup(this.getPopupTemplate(), {            
            full_image : this.productImageFullUrl,
            rand: this.rand,
            option_id: this.id,
            close_text: this.text.close,
            apply_text: this.text.apply,
            reset_text: this.text.reset,
            areaSizeX: this.areaSizeX,
            areaSizeY: this.areaSizeY,
            areaOffsetX: this.areaOffsetX,
            areaOffsetY: this.areaOffsetY
        } );
        this.window.renderWindow( this.id, this.productImageFullUrl, this );
    },

    cached : function() {
        $('loading-mask').hide();
        var scr = this.window.showWindow( this.id );
        
        var optdata = {
            width  : Math.floor(this.areaSizeX * scr.mult),
            height : Math.floor(this.areaSizeY * scr.mult),
            left : Math.max(0, Math.round(this.areaOffsetX * scr.mult - 1)),
            top  : Math.max(0, Math.round(this.areaOffsetY * scr.mult - 1))
        };
        var options = {
            width  : optdata.width + "px",
            height : optdata.height+ "px",
            left :   optdata.left  + "px",
            top  :   optdata.top   + "px"
        };
        
        this.shownScr = scr;
        this.shownScr.opt = options;
        
        var el = $(this.id + "_raph");
        el.setStyle(options);
        this.raph = new Aitcg.Raph( el, optdata.width, optdata.height, 50, 50);
        scr.img_mult = this.raph.addThumbnail( this.tempFullUrl, this.tempImageSizes, scr.mult );
        if(this.editorEnabled) {
            this.raph.setImageDrag();
            this.raph.addResizeSquare(1,1, "se");//bottom,right, css
            
            this.raph.addRotate(1,0, 'pointer');//bottom-left
        }
        
        this.scr = scr;
        this.raph.applyImageData( this.getImgData(scr.mult, scr.img_mult) );
    },
    
    show : function(el) {
        var str = "";
        for(var i in el) {
            str += i+" -> "+el[i]+"\n";        
            if(typeof(el[i])=='object') {
                for(var j in el[i]) {
                    if(typeof(el[i][j])!='function')
                        str += '---'+j+' -> '+el[i][j]+"\n";
                }
            }
        }
        if(typeof(arguments[1])!='undefined') {
            str = arguments[1] + ": \n"+ str;
        }
        alert(str);
    },
    
    getImgData : function ( mult, img_mult ) {
        var data = Aitcg.clone(this.imgData);
        if(mult !== 1) {
            data.x = data.x * mult;
            data.y = data.y * mult;
            if(img_mult == 1) {
                data.scale_x *= mult;
                data.scale_y *= mult;
            }
        }
        return data;
    },
    
    formatImgData : function ( coords ) {
        if(typeof(this.scr.mult) != 'undefined' && this.scr.mult !== 1) {
            coords.x /= this.scr.mult;
            coords.y /= this.scr.mult;
            if(this.scr.img_mult == 1) {
                coords.scale_x /= this.scr.mult;
                coords.scale_y /= this.scr.mult;
            }
        }
        return coords;
    },

    /**
     *  if you've made changes in this method be sure to
     *  make same changes in Aitoc_Aitcg_Model_Image
     */
    getDivRotated : function( box ) { 
        var width, height, axis;
        if(typeof(box.width) !='undefined') {
            width = box.width;
            height = box.height;
            axis = 'b';
        } else {
            var size = Aitcg.checkSizes( box.full_x, box.full_y, this.areaSizeX, this.areaSizeY );
            width  = size.x * box.scale_x;
            height = size.y * box.scale_y;
            axis = size.axis;
        } 
                    
        if( box.angle != 0 ) {
            var degreesAsRadians = box.angle * Math.PI / 180,
                points = new Array(); 
                    points.push({ x: 0, y: 0 }); 
                    points.push({ x: width, y: 0 }); 
                    points.push({ x: 0, y: height }); 
                    points.push({ x: width, y: height }); 
            var bb = new Array();
            var newX, newY;
            bb['left'] = box.x+width; bb['right'] = 0; bb['top'] = box.y+height; bb['bottom'] = 0; 

            for (_px = 0; _px < points.length; _px++) { 
                var p = points[_px]; 
                newX = parseInt((p.x * Math.cos(degreesAsRadians)) + (p.y * Math.sin(degreesAsRadians))); 
                newY = parseInt((p.x * Math.sin(degreesAsRadians)) + (p.y * Math.cos(degreesAsRadians))); 
                bb['left'] = Math.min(bb['left'], newX); 
                bb['right'] = Math.max(bb['right'], newX); 
                bb['top'] = Math.min(bb['top'], newY); 
                bb['bottom'] = Math.max(bb['bottom'], newY); 
            } 

            box.newWidth = parseInt(Math.abs(bb['right'] - bb['left'])); 
            box.newHeight = parseInt(Math.abs(bb['bottom'] - bb['top'])); 
            box.newX = (box.x + (width) / 2) - box.newWidth / 2; 
            box.newY = (box.y + (height) / 2) - box.newHeight / 2; 
        } else {
            box.newWidth = width;
            box.newHeight = height;
            box.newX = box.x;
            box.newY = box.y;            
        }
        box.axis = axis;
        return box; 
    },
    
    applyImgData : function( data ) {
        data = this.getDivRotated(data);
        this.imgData = data;   
        this.setThumbnailPosition();
    },
    
    apply : function() {
        var coords = this.raph.getImageData();
        this.closeEditor();
        this.applyImgData( this.formatImgData(coords) );
        this.updateData();        
    },
    
    reset : function() {
        this.raph.reset();
    },

    updateThumbnail: function(resp)
    {
        this.loadThumbnailImage(resp.id, resp.temp_thumbnail_url, resp.temp_image_url, {
            full_x: resp.preview_width, 
            full_y: resp.preview_height,
            x : resp.x,
            y : resp.y,
            scale_x : resp.scale_x,
            scale_y : resp.scale_y,
            angle :  resp.angle
        });
    },
    
    /**
     *  if you've made changes in this method be sure to
     *  make same changes in Aitoc_Aitcg_Model_Image
     */
    setThumbnailPosition: function() {
        var el = $$(this.imgThumbSelector + ' div');
        var mult = Math.min(1, this.productImageThubnailSizeX / this.productImageSizeX, this.productImageThubnailSizeY / this.productImageSizeY);
        el[0].setStyle({
            left: Math.max(0, Math.round( (this.areaOffsetX) * mult-1 )) + "px",
            top:  Math.max(0, Math.round( (this.areaOffsetY) * mult-1 )) + "px",
            width: Math.min(198, Math.round( this.areaSizeX * mult )) + "px",
            height: Math.min(198, Math.round( this.areaSizeY * mult )) + "px"
        });
        var windowData = Aitcg.countMult( 0, this.productImageSizeX, this.productImageSizeY );
        //this.show(windowData,"windowData");
        var mult2 = mult / windowData.mult,
            box = {
                width:  Math.round( this.imgData.newWidth  * mult ),
                height: Math.round( this.imgData.newHeight * mult )
            },                                                   
            mult_x = this.areaSizeX * windowData.mult / this.imgData.full_x,
            mult_y = this.areaSizeY * windowData.mult  / this.imgData.full_y;
        var coords = {};
            
        if(typeof(this.imgData.force)!='undefined') {
            box = {
                width:  Math.round( this.imgData.newWidth  * mult2 ),
                height: Math.round( this.imgData.newHeight * mult2 )
            };            
            box.left= Math.round( (this.imgData.newX) * mult );
            box.top = Math.round( (this.imgData.newY) * mult );
            coords.y = this.imgData.newX;
            coords.x = this.imgData.newY;
            this.force_show = true;
        } else {
            if(this.imgData.x != 0 || this.imgData.y!=0 || this.force_show == true || this.imgData.scale_x!=1 || this.imgData.scale_y != 1 || this.imgData.angle != 0) {
                if(mult_x >= 1 && mult_y >= 1) {
                    mult2 = mult;
                } else {
                    mult2 = mult; //Math.min(mult_x, mult_y, 1) * mult2;
                }
                box.width = Math.round(this.imgData.newWidth * mult2);
                box.height = Math.round(this.imgData.newHeight * mult2);
                /*box.width = box.width + 'px';
                box.height = box.height + 'px';                */
                box.left= Math.round( (this.imgData.newX) * mult );
                box.top = Math.round( (this.imgData.newY) * mult );
                coords.y = this.imgData.newX;
                coords.x = this.imgData.newY;
            } else {
                if(mult_x < 1 && mult_x < mult_y) {//x
                    box.width = this.areaSizeX * mult;
                    //box.height = mult_x * box.height;
                    box.left = coords.x = 0;
                    box.top  = Math.round( (this.areaSizeY * mult - box.height) /2 );
                    coords.y = Math.round( (this.areaSizeY - box.height) /2 );
                } else if (mult_y < 1 && mult_y <= mult_x) {
                    box.height = this.areaSizeY * mult;
                    //box.width = mult_y * box.width;
                    box.top  = coords.y = 0;
                    box.left = Math.round( (this.areaSizeX * mult - box.width) /2 );
                    coords.x = Math.round( (this.areaSizeX - box.width) /2 );
                } else {
                    box.width = this.imgData.newWidth * mult2;
                    box.height = this.imgData.newHeight * mult2;
                    box.top  = Math.round( (this.areaSizeY * mult - this.imgData.newHeight * mult2) /2 );
                    box.left = Math.round( (this.areaSizeX * mult - this.imgData.newWidth  * mult2) /2 );
                    
                    coords.y = Math.round( (this.areaSizeY - this.imgData.newHeight) /2 );
                    coords.x = Math.round( (this.areaSizeX - this.imgData.newWidth) /2 );
                }
            }
        }
        box.width++;
        box.height++;
        for(var i in box) {
            box[i] = box[i]+'px';
        }

        var el = $$(this.imgThumbSelector + ' img');
        el[0].setStyle(box);

        this.defaultCoords = coords;
    }
    
});


Aitcg.Raph = Class.create({  
    p : null, //paper
    img : null, //thumbnail url
    reset : false,
    control : {
        r : 5,
        o : 3,
        a : 4
    },
    initialize : function(el, sizeX, sizeY, minX, minY) 
    {
        this.p = Raphael(el, sizeX, sizeY);
        this.x = sizeX;
        this.y = sizeY;
        this.minX = minX;
        this.minY = minY;
        
        Raphael.el.moveTo = function(x, y) {            
            var dX = - this.lastX + x,
                dY = - this.lastY + y;
            this.translate(dX, dY);
            this.lastX = x;
            this.lastY = y;
        }
        Raphael.el.moveBy = function(dx, dy) {            
            this.translate(dx - this.last_x, dy - this.last_y);
            this.lastX = this.lastX + dx - this.last_x;
            this.lastY = this.lastY + dy - this.last_y;
            this.last_x = dx;
            this.last_y = dy;
        }        
        //store object position in private variables
        Raphael.el.save = function () {
            //if(this.type=='path' || this.itype=='translate') {
                this.last_x = 0;
                this.last_y = 0;
                this.ox = 0;
                this.oy = 0;
        };
        Raphael.el.rotateAbs = function (angle, x, y) {
            this.rot_x = x;
            this.rot_y = y;
            this.angle = angle;
            this.rotate(angle, x, y);
        };
        Raphael.el.rotateBack = function (x) {
            this.rotate(x * this.angle, this.rot_x, this.rot_y);
            return this.angle;
        };
        Raphael.el.setPos = function( box ) {
            //vert: 0 - top, 1 - bottom
            //hor: 0 - left, 1 - right
            this.rotate(0, this.rot_x, this.rot_y);
            var x, y;
            if( this.hor == 0 ) {                                  
                x = box.minX;
            } else {
                x = box.maxWidth;
            }
            if(x >= this.img.maxXPos - this.ow ) {
                x = this.img.maxXPos - this.ow;
            } else if (x < this.ow) {
                x = this.ow;
            }
            if( this.vert == 0 ) {
                y = box.minY;
            } else {
                y = box.maxHeight;
            }
            if(y >= this.img.maxYPos - this.oh ) {
                y = this.img.maxYPos - this.oh;
            } else if (y < this.oh) {
                y = this.oh;
            }
            this.moveTo(x,y);
        };
        //return coordinats of rotated image
        
        /**
         *  if you've made changes in this method be sure to
         *  make same changes in Aitoc_Aitcg_Model_Image
         */
        Raphael.el.getBBoxRotated = function() { 
                var degreesAsRadians = this._.rt.deg * Math.PI / 180; 
                var points = new Array(); 
                var box = this.getBBox(); 
                points.push({ x: 0, y: 0 }); 
                points.push({ x: box.width, y: 0 }); 
                points.push({ x: 0, y: box.height }); 
                points.push({ x: box.width, y: box.height }); 
                var bb = new Array();
                var newX, newY;
                bb['left'] = 0; bb['right'] = 0; bb['top'] = 0; bb['bottom'] = 0; 

                for (_px = 0; _px < points.length; _px++) { 
                    var p = points[_px]; 
                    newX = parseInt((p.x * Math.cos(degreesAsRadians)) + (p.y * Math.sin(degreesAsRadians))); 
                    newY = parseInt((p.x * Math.sin(degreesAsRadians)) + (p.y * Math.cos(degreesAsRadians))); 
                    bb['left'] = Math.min(bb['left'], newX); 
                    bb['right'] = Math.max(bb['right'], newX); 
                    bb['top'] = Math.min(bb['top'], newY); 
                    bb['bottom'] = Math.max(bb['bottom'], newY); 
                } 

                var newWidth = parseInt(Math.abs(bb['right'] - bb['left'])); 
                var newHeight = parseInt(Math.abs(bb['bottom'] - bb['top'])); 
                newX = (box.x + (box.width) / 2) - newWidth / 2; 
                newY = (box.y + (box.height) / 2) - newHeight / 2; 
                
                var minX = Math.max(0, Math.min(this.maxXPos, newX)),
                    minY = Math.max(0, Math.min(this.maxYPos, newY)),
                    maxX = Math.max(0, Math.min(this.maxXPos, newX+newWidth)),
                    maxY = Math.max(0, Math.min(this.maxYPos, newY+newHeight));
                return { x: newX, y: newY, width: newWidth, height: newHeight, minX:minX, minY:minY, maxWidth:maxX, maxHeight:maxY }; 
        };
    },
    addThumbnail : function( url, sizes, mult ) 
    {
        var new_sizes = Aitcg.checkSizes( sizes.full_x, sizes.full_y, this.x, this.y );
        //this.show(new_sizes, 'Mult: ' +mult);
        this.img = this.p.image(url, new_sizes.posX, new_sizes.posY, new_sizes.x, new_sizes.y);
        this.img.pair = new Array();
        this.def_pos = new_sizes;
        this.def_img_mult = mult;
        
        this.img.maxXPos = this.x;
        this.img.maxYPos = this.y;
        this.img.rotated = 0;
        this.img.last_scale = {x:1, y:1};

        return new_sizes.mult;
    },
    show : function(el) {
        var str = "";
        for(var i in el) {
            str += i+" -> "+el[i]+"\n";
        }
        if(typeof(arguments[1])!='undefined') {
            str = arguments[1] + ": \n"+ str;
        }        
        alert(str);
    },
    setImageDrag : function() {
        var start = function () {
                this.ox = this.attr("x");
                this.oy = this.attr("y");
                this.w = this.attr("width")/2;
                this.h = this.attr("height")/2;
                
                var box = this.getBBoxRotated();
                var offset = 10;
                this.border = {
                    maxX: this.paper.width - box.x + offset,
                    minX: (box.x + box.width + offset)*-1,
                    maxY: this.paper.height - box.y + offset,
                    minY: -(box.y + box.height + offset)
                };
                
                this.animate({opacity: .75}, 500, ">");

                for(var i in this.pair) {
                    if(typeof(this.pair[i].type)!='undefined') {
                        this.pair[i].save();
                        //this.pair[i].animate({opacity: .75}, 500, ">");
                    }
                }
            },
            move = function (dx, dy) {
                if(dx > this.border.maxX || dx < this.border.minX) {
                    dx = 0;
                }
                if(dy > this.border.maxY || dy < this.border.minY) {
                    dy = 0;
                }
                this.attr({x: this.ox + dx, y: this.oy + dy});                    
                for(var i in this.pair) {
                    if(typeof(this.pair[i].type)!='undefined') {
                        this.pair[i].moveBy(dx,dy);
                    }
                }                
            },
            up = function () {
                this.animate({opacity: 1}, 500, ">");
                var box = this.getBBoxRotated();
                for(var i in this.pair) {
                    if(typeof(this.pair[i].type)!='undefined') {
                        this.pair[i].setPos(box);
                        //this.pair[i].animate({opacity: 1}, 500, ">");
                    }
                }
            };
        this.img.attr({cursor:"move"});
        this.img.drag(move, start, up);        
    },
    
    addResizeSquare : function(vert, hor, cssstyle) {
        //vert: 0 - top, 1 - bottom
        //hor: 0 - left, 1 - right
        var x = this.getImg("x") + hor * this.getImg("width"),
            y = this.getImg("y") + vert* this.getImg("height"),
            c = this.control,
            radius = c.r, offset = c.o, al = c.a,//arrowLength
            start = (x-radius)+","+(y-radius), end = (x+radius)+","+(y+radius),
            rs = this.p.rect(x-radius-offset, y-radius-offset, (radius+offset)*2, (radius+offset)*2).attr({fill:"#aaa",stroke: "#000", opacity: 1,cursor:cssstyle+'-resize'});
            ra = this.p.path("M"+start+"L"+end+"M"+start+"L"+(x-radius)+","+(y-radius+al)+"M"+start+"L"+(x-radius+al)+","+(y-radius)+
            "M"+end+"L"+(x+radius)+","+(y+radius-al)+"M"+end+"L"+(x+radius-al)+","+(y+radius)
            ).attr({stroke: "#fff", cursor:cssstyle+'-resize'});

        var start = function () {
                this.imgx = this.img.attr("x");
                this.imgy = this.img.attr("y");
                
                this.box = this.img.getBBoxRotated();
                this.rotated = this.img.rotated != 0 ? this.img.rotated : 0;

                this.last_scale = {x:1,y:1};
                this.min_scale = 0.05;
                this.center_x = this.imgx + this.img.attr("width")/2;
                this.center_y = this.imgy + this.img.attr("height")/2;
                
                this.angle = this.rotated * Math.PI/180;
                if(typeof(this.img.last_scale) != 'undefined') {
                     this.last_scale = this.img.last_scale;
                }
                
                for(var i in this.img.pair) {
                    if(typeof(this.img.pair[i].type)!='undefined')
                        this.img.pair[i].save();
                }
            },
            move = function (dx, dy) {
                var attr = {x:this.imgx, y:this.imgy},
                    cos = Math.abs(Math.cos(this.angle).toFixed(4)),
                    sin = Math.abs(Math.sin(this.angle).toFixed(4));
                dx = dy = Math.max(dx, dy);
                var x_scale = Math.max(this.min_scale, this.last_scale.x * ( 
                        (cos*cos*(this.hor_mod*dx+this.box.width))/(this.box.width) + 
                        (sin*sin*(this.vert_mod*dy+this.box.height))/(this.box.height)
                    )  ),
                    y_scale = Math.max(this.min_scale, this.last_scale.y * ( 
                        (sin*sin*(this.hor_mod*dx+this.box.width))/(this.box.width) + 
                        (cos*cos*(this.vert_mod*dy+this.box.height))/(this.box.height)
                    )  ),
                    move_hor  = (x_scale==this.min_scale) ? false : true,
                    move_vert = (y_scale==this.min_scale) ? false : true;
                x_scale = y_scale = Math.min(x_scale, y_scale);

                this.img.scale(x_scale, y_scale);
                this.img.last_scale = { x : x_scale, y: y_scale};
                
                var box = this.img.getBBoxRotated();
                for(var i in this.img.pair) {
                    if(typeof(this.img.pair[i].type)!='undefined') {
                        this.img.pair[i].setPos(box);
                    }
                }
            },
            up = function () {
                var box = this.img.getBBoxRotated();
                for(var i in this.img.pair) {
                    if(typeof(this.img.pair[i].type)!='undefined') {
                        this.img.pair[i].setPos(box);
                    }
                }                
            };
        rs.lastX = ra.lastX = x;
        rs.lastY = ra.lastY = y;
        rs.minX = ra.minX = this.minX;
        rs.minY = ra.minY = this.minY;
        rs.vert = ra.vert = vert;
        rs.hor = ra.hor = hor;
        ra.hor_mod = rs.hor_mod = hor ? 1 : -1;
        ra.vert_mod = rs.vert_mod = vert ? 1 : -1;
        ra.ow = rs.ow = ra.oh = rs.oh = c.r + c.o;
        rs.img = ra.img = this.img;
        //rs.itype = ra.itype = 'translate';
        ra.drag(move, start, up);//resize
        rs.drag(move, start, up);
        this.img.pair.push(ra);
        this.img.pair.push(rs);
        
    },
    addRotate : function(vert, hor, cssstyle) {
        //vert: 0 - top, 1 - bottom
        //hor: 0 - left, 1 - right
        var x = this.getImg("x") + hor * this.getImg("width"),
            y = this.getImg("y") + vert* this.getImg("height"),
            c = this.control,
            radius = c.r, offset = c.o, al = c.a,//arrowLength
            start = (x-radius)+","+(y), end = (x)+","+(y+radius),
            rs = this.p.rect(x-radius-offset, y-radius-offset, (radius+offset)*2, (radius+offset)*2).attr({fill:"#aaa",stroke: "#000", opacity: 1,cursor:cssstyle});
            r = this.p.path("M"+start+"C"+start+" "+(x-radius)+","+(y-radius)+" "+(x)+","+(y-radius)+
            "C"+(x)+","+(y-radius)+" "+(x+radius)+","+(y-radius)+" "+(x+radius)+","+(y)+
            "C"+(x+radius)+","+(y)+" "+(x+radius)+","+(y+radius)+" "+ end+
            "M"+(x-radius-1)+","+(y+1)+"L"+(x-radius-1)+","+(y-al)+"M"+(x-radius-1)+","+(y+1)+"L"+(x-radius+al)+","+(y+1)
            ).attr({stroke: "#fff", cursor:cssstyle});
 
        var start = function () {
                this.w = this.img.attr("width") / 2;
                this.h = this.img.attr("height") / 2;
                this.x = this.img.attr("x");
                this.y = this.img.attr("y");
                var center_x = this.x + this.w,
                    center_y = this.y + this.h;
                this.hor_pos = 0;
                this.ver_pos = 0;
                    
                for(var i in this.img.pair) {
                    if(typeof(this.img.pair[i].type)!='undefined')
                        this.img.pair[i].save();
                }
                if(this.ox > center_x) {
                    this.hor_pos = 1;
                }
                if(this.oy > center_y) {
                    this.ver_pos = 1;
                }
                
                this.hyp = function(a,b){return Math.sqrt(a*a+b*b);};
                this.grad = function(rad){return (180/Math.PI)*rad;};
                
                this.def_angle = this.grad(Math.acos( this.w / this.hyp(this.w,this.h) ));//acos|asin
                //sin for right, cos for left
                this.rotated = this.img.rotated != 0 ? this.img.rotated : 0;
            },
            move = function (dx, dy) {
                var Pi = 0;
                dx = dx * -1;// -1 for left, 1 for right
                //dy = dy * -1;// -1 for top, 1 for bottom

                if(dy<0 && Math.abs(dy)>this.h) {
                    //dy = Math.abs(dy)-this.h*2;
                    dy = dy * -1 - this.h*2;
                    dx = dx * -1 - this.w*2;
                    Pi = -180;
                }
                var alp2 = Math.acos( (dx+this.w) / this.hyp(this.w+dx, this.h+dy) );// acos|asin
                alp2 = Math.round(Pi + this.def_angle - this.grad(alp2));
                var rot = this.rotated + alp2; 
                this.img.rotate(rot,true); 
                this.img.rotated = rot;
                for(var i in this.img.pair) {
                    if(typeof(this.img.pair[i].type)!='undefined')
                        this.img.pair[i].rotateAbs( alp2, Math.round(this.x+this.w), Math.round(this.y+this.h) );
                }
            },
            up = function () {
                var box = this.img.getBBoxRotated();
                for(var i in this.img.pair) {
                    if(typeof(this.img.pair[i].type)!='undefined') {
                        this.img.pair[i].setPos(box);
                    }
                }
            };
            
        rs.lastX = r.lastX = x;
        rs.lastY = r.lastY = y;
        rs.minX = r.minX = this.minX;
        rs.minY = r.minY = this.minY;
        rs.vert = r.vert = vert;
        rs.hor = r.hor = hor;
        rs.img = r.img = this.img;
        r.ow = rs.ow = r.oh = rs.oh = c.r + c.o;
        //rs.itype = r.itype = 'translate';
        r.drag(move, start, up);//rotate
        rs.drag(move, start, up);
        this.img.pair.push(r);
        this.img.pair.push(rs);
    },
    check : function(data, id) {
         return (typeof(data[id])=='undefined')?false:true;
    },
    
    applyImageData : function ( data ) {
        var zero = 0;
        var attr = {};
        //this.show(data, 'applyData to  image');
        if(data.x != 0 || data.y!=0 || (data.scale_x!=1 && data.scale_x!=this.def_img_mult) || (data.scale_y != 1 && data.scale_y!=this.def_img_mult) || data.angle != 0) {
            if(this.check(data,"x")) {
                attr.x = data.x;
            } else {
                attr.x = this.getImg("x");
            }
            if(this.check(data,"y")) {
                attr.y = data.y;
            } else {
                attr.y = this.getImg("y");
            }
            if(this.check(data,"scale_x") && this.check(data,"scale_y")) {
                //this.img.scale( data.scale_x, data.scale_y, attr.x, attr.y );
                this.img.scale( data.scale_x, data.scale_y);
                this.img.last_scale = {x:data.scale_x, y:data.scale_y};
            }
            this.img.attr(attr);
            if(this.check(data,"angle")) {
                if(data.angle != 0 ) {
                    this.img.rotate( data.angle, true );
                }
                this.img.rotated = data.angle;
            }
        }
        var box = this.img.getBBoxRotated();
        for(var i in this.img.pair) {
            if(typeof(this.img.pair[i].type)!='undefined') {
                this.img.pair[i].save();
                this.img.pair[i].setPos(box);
            }
        }        
    },
    
    reset : function() {
        this.img.scale(1, 1);
        this.img.attr({x:this.def_pos.posX,y:this.def_pos.posY});
        this.img.last_scale = {x:1, y:1};
        this.img.rotate( 0, true );
        this.img.rotated = 0;
        
        var box = this.img.getBBoxRotated();
        for(var i in this.img.pair) {
            if(typeof(this.img.pair[i].type)!='undefined') {
                this.img.pair[i].save();
                this.img.pair[i].setPos(box);
            }
        }
    },
    
    getImageData: function() {
        var ret = {
            x :         this.getImg("x"),
            y :         this.getImg("y"),
            width:      this.getImg("width"),
            height:     this.getImg("height"),
            angle :     this.getImgRotate() % 360,
            scale_x:    this.getImgScale("x"),
            scale_y:    this.getImgScale("y"),
            shown_x:    this.x,
            shown_y:    this.y,
            force  :    1
        };
        //this.show(ret, 'Ret on apply');
        return ret;
    },
    
    getImgRotate : function() {
        return this.img.rotated;
    },
    getImgScale : function(id) {
        return this.img.last_scale[id];
    },    
    getImg : function (id) {
        return this.img.attr(id);
    },
    get : function() {
        return this.p;
    }
});
