var ImageTools = Class.create({

    initialize: function(image_id, params) {
        this.image = $(image_id);
        this.config = params;

        this.form_resize_width = $(this.config.resize_width);
        this.form_resize_height = $(this.config.resize_height);
        this.form_crop_width = $(this.config.crop_width);
        this.form_crop_height = $(this.config.crop_height);
        this.form_crop_x = $(this.config.crop_x);
        this.form_crop_y = $(this.config.crop_y);

        $(this.form_resize_width).observe('change', this._manualResizeWidth.bindAsEventListener(this));
        $(this.form_resize_height).observe('change', this._manualResizeHeight.bindAsEventListener(this));
        $(this.form_crop_width).observe('change', this._manualCropperArea.bindAsEventListener(this));
        $(this.form_crop_height).observe('change', this._manualCropperArea.bindAsEventListener(this));

        this.zoomer = this._getZoomer();

        Event.observe( $(this.config.zoomer.track), 'click', function(event){event.stop()});
        Event.observe( $(this.config.zoomer.handler), 'click', function(event){event.stop()});
        Event.observe( $(this.config.zoomer.button_in), 'click', this.zoom.bindAsEventListener(this, this.config.zoomer.step ));
        Event.observe( $(this.config.zoomer.button_out), 'click', this.zoom.bindAsEventListener(this, -1 * this.config.zoomer.step));

        Event.observe($(this.config.cropper.preset_selector), 'change', this._setPreset.bindAsEventListener(this));

        this.cropper = new Cropper.Img(this.image, {
            minWidth: this.config.cropper.min_width,
            minHeight: this.config.cropper.min_height,
            maxWidth: this.getWidth(),
            maxHeight: this.getHeight(),
            captureKeys: false,
            displayOnInit: 1,
            onloadCoords: this.config.cropper.coords,
            onEndCrop: this.updateCropData.bind(this)
        });

        this.updateCropData();
    },

    reloadImage: function(name, width, height, sid) {

        this.image.src = this.config.base_url + name;

        this.cropper.imgW = this.width = width;
        this.cropper.imgH = this.height = height;

        this.cropper.reset();
        this.zoomer.setValue(1);

        this.updateCropData();
    },

    updateCropData: function(new_coords) {

        if (!new_coords) return 0;

        var coords = new_coords;

        this.form_resize_width.value = this.image.width;
        this.form_resize_height.value = this.image.height;
        this.form_crop_x.value = coords.x1;
        this.form_crop_y.value = coords.y1;
        this.form_crop_width.value = coords.x2 - coords.x1;
        this.form_crop_height.value = coords.y2 - coords.y1;

        return 1;
    },

    _manualResize: function(new_value, real_value){

        if (isNaN(new_value)) return 0;

        if (new_value < this.config.cropper.min_width) new_value = this.config.cropper.min_width;
        if (new_value > real_value) new_width = real_value;
        var ratio = new_value / real_value;

        this.zoomer.setValue(ratio);
        return this._changeZoom(ratio);
    },

    _manualResizeWidth: function(event){return this._manualResize(event.target.value, this.getWidth())},
    _manualResizeHeight: function(event){return this._manualResize(event.target.value, this.getHeight())},

    _setPreset: function(event) {

        if (!$F(event.target).match(/^\d+-\d+$/)) return 0;

        var values = $F(event.target).split('-');

        return this._resizeCropperArea(parseInt(values[0]), parseInt(values[1]));
    },

    _manualCropperArea: function() {
        return this._resizeCropperArea(parseInt(this.form_crop_width.value), parseInt(this.form_crop_height.value));
    },

    _resizeCropperArea: function(new_width, new_height) {
        
        if (isNaN(new_width)) new_width = 0;
        if (isNaN(new_height)) new_height = 0;
        
        if (new_width < this.config.cropper.min_width) new_width = this.config.cropper.min_width;
        if (new_height < this.config.cropper.min_height) new_height = this.config.cropper.min_height;
        
        coords = this.cropper.areaCoords;

        new_coords = coords;

        new_coords.x2 = coords.x1 + new_width;
        new_coords.y2 = coords.y1 + new_height;

        if (new_coords.x2 > this.image.width) {
            new_coords.x1 = this.image.width - new_width;
            new_coords.x2 = this.image.width;
        };

        if (new_coords.y2 > this.image.height) {
            new_coords.y1 = this.image.height - new_height;
            new_coords.y2 = this.image.height;
        }

        this._updateCropper(new_coords);
    },

    _resizeCropper: function (new_width, new_height) {

        this.cropper.imgW = new_width;
        this.cropper.imgH = new_height;

        new_coords = coords = this.cropper.areaCoords;

        if (new_coords.x2 > new_width) {
            new_coords.x1 = new_width - (coords.x2 - coords.x1);
            new_coords.x2 = new_width;
        }
        if (new_coords.y2 > new_height) {
            new_coords.y1 = new_height - (coords.y2 - coords.y1);
            new_coords.y2 = new_height;
        }
        this._updateCropper(new_coords);
    },

    _updateCropper: function(new_coords) {

        this.cropper.options.onloadCoords = new_coords;
        this.cropper.reset();
        this.cropper.setAreaCoords(new_coords);
        this.cropper.drawArea();
    },

    _getZoomer: function() {
        var min_v = this.config.cropper.min_width / this.getWidth();
        return new Control.Slider(this.config.zoomer.handler, this.config.zoomer.track, {
            range:          $R(min_v, 1),
            sliderValue:    1,
            onSlide:        this._changeZoom.bind(this),
            onChange:       this._changeZoom.bind(this)
        });
    },

    zoom: function (event, value) {
        this.zoomer.setValue( this.zoomer.value + value );
        event.stop();
    },

    _changeZoom: function (value) {

        this.image.width = Math.round(value * this.getWidth());
        this.image.height = Math.round(value * this.getHeight());

        this._resizeCropper(this.image.width, this.image.height);
    },

    getWidth: function() {
        if (this.width) return this.width;
        this.width = $(this.image).getWidth();
        return this.width;
    },
    getHeight: function() {
        if (this.height) return this.height;
        this.height = $(this.image).getHeight();
        return this.height;
    }

});

function IsNumeric(input){
   return (input - 0) == input && input.length > 0;
}

