/**
 * LX' ImageCrop v3.0
 *
 *  Authors: Alexander Schulze
 *  License: GPL v2 or compatible
 *           http://www.fsf.org/licenses/gpl.html
 *  Contact: webmaster@lxhome.de
 *           http://www.lxhome.de
 *
 * This script provides a basic functionality to draw crop areas on an
 * image and to paste necessary size information into a form, which
 * can then be posted to a server side script to crop an image to the
 * specified size.
 *
 *********************************************************************
 *
 * History of Changes:
 * v3.0   Note:    this version is not entirely backwards compatible
 *                 to version 2.x, for updating remove the first
 *                 parameter, also the middle quadruple (see below)
 *                 and also remove the wand and cover DIVs from the
 *                 HTML part as these are created automagically now;
 *                 setting a fixed aspect ratio is now done via a
 *                 setter method and some styling has changed, too
 *        Feature: wand area is created automatically and have not to
 *                 be passed to the crop class (hence removed the
 *                 first parameter)
 *        Feature: cover areas are created automatically and have not
 *                 to be passed to the crop class (hence removed the
 *                 middle quadruple of parameters)
 *        Feature: wand lines are created automatically and have not
 *                 to be defined in HTML anymore
 *        Feature: post-resizing of selections via mouse pointer
 *        Feature: help texts can be defined to pop up when hovering
 *                 certain areas
 *        Misc:    possibly performance tweak: less event handling
 *        Misc:    new method: setAspectRatio(), please use it instead
 *                 of setting fixAspectRatio directly
 * v2.1   Bugfix:  key presses are correctly handled even if no action
 *                 was possible
 *        Bugfix:  selections with a height greater than width are now
 *                 treated correctly when being resized
 * v2.0   Note:    this version is not backwards compatible to v1.x
 *        Misc:    accumulated all functions in an object to allow for
 *                 multiple instances on the same page and freely
 *                 nameable input fields and elements
 *        Feature: maximizing a selection can now also be done by
 *                 calling method maximizeSelection()
 *        Feature: predefining of selections by calling method
 *                 setSelection()
 *        Feature: scrolling while using cursor or page keys should be
 *                 disabled now
 *        Misc:    some minor performance improvements
 * v1.5   Bugfix:  drawing selection from bottom upwards now returns
 *                 correct values
 * v1.4   Feature: horizontal scrolling is now allowed
 *        Bugfix:  positioning with keys returned wrong values
 *        Bugfix:  shading of maximized selection after already
 *                 drawing a selection
 *        Misc:    better XHTML support
 * v1.3   Feature: action frame
 * v1.2   Bugfix:  selection can be expanded to the top when document
 *                 is scrolled
 *        Feature: selection can be finished when cursor is out of
 *                 the image
 *        Feature: clear selection with DEL and ESC, too
 * v1.1   Bugfix:  moving without selection
 *        Bugfix:  selection problem in Firefox
 *        Feature: moving and resizing the selection faster using the
 *                 SHIFT key
 *        Feature: switched resizing the selection to PGUP/PGDN
 *                 because of "find as you type" funtionality in some
 *                 browsers
 *        Feature: biggest possible selection using HOME key
 *        Feature: clear selection using END key
 * v1.0   first release
 *
 *********************************************************************
 *
 * Works with (at least):
 * - modern browsers (Gecko derivates, Opera, Konqueror, IE7)
 * - IE6 (without action frame)
 *
 *********************************************************************
 *
 * Usage:
 * See http://www.lxhome.de/eng/scripts/imagecrop
 *
 *********************************************************************
 *
 * Restrictions:
 * - drawing selections behaves funny if any parent element in
 *   the DOM tree has a special positioning (absolute, relative)
 *
 *********************************************************************
 *
 * Disclaimer:
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published  by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

function lx_crop ( el_crop, el_actarea, c_left, c_top, c_width, c_height )
{
    // Scrollposition auf der Seite bestimmen
    this.getScrollPosition = function()
    {
        if ( !me.isactive ) return;

        me.scrollX = ( typeof window.pageXOffset == 'undefined' )
                   ? document.body.scrollLeft
                   : window.pageXOffset;

        me.scrollY = ( typeof window.pageYOffset == 'undefined' )
                   ? document.body.scrollTop
                   : window.pageYOffset;
    }

    // diese Crop-Instanz aktivieren oder deaktivieren
    this.setActive = function ( act )
    {
        me.isactive = act;

        // Tastendrücke an diese Funktion leiten
        if ( act )
        {
            // Events registrieren
            me.Act.onmousedown = me.selectStart;
            document.onkeydown = me.keyAction;

            me.toggleTooltips ( true );
        }
        else
        {
            me.Act.onmousedown = null;
            document.onkeydown = null;

            me.toggleTooltips ( false );
        }
    }

    // Auswahl markieren Anfang
    this.selectStart = function ( e )
    {
        if ( !me.isactive || me.WandAction ) return;

        e = ( !e ) ? window.event : e;

        me.getScrollPosition();

        if (      e.clientX < me.Crop.offsetLeft - me.scrollX )
            me.startX = me.Crop.offsetLeft;
        else if ( e.clientX > me.Crop.offsetLeft - me.scrollX + me.Crop.width )
            me.startX = me.Crop.offsetLeft + me.Crop.width;
        else
            me.startX = e.clientX + me.scrollX;

        if (      e.clientY < me.Crop.offsetTop - me.scrollY )
            me.startY = me.Crop.offsetTop;
        else if ( e.clientY > me.Crop.offsetTop - me.scrollY + me.Crop.height )
            me.startY = me.Crop.offsetTop + me.Crop.height;
        else
            me.startY = e.clientY + me.scrollY;

        me.reset();

        me.WandAction     = true;
        me.Wand.className = 'wand_area crosshair wandaction';

        document.onmousemove = me.selectSize;
        document.onmouseup   = me.selectEnd;

        me.toggleTooltips ( false );

        return false;
    }

    // Auswahl verändern Anfang
    this.resizeStart = function ( e )
    {
        if ( !me.isactive || me.WandAction ) return;

        e = ( !e ) ? window.event : e;

        me.getScrollPosition();

        me.target = ( typeof e.target != 'undefined' )
                  ? e.target
                  : e.srcElement;

        me.target.oldevent = me.target.onmouseout;
        me.target.onmouseout = null;

        if ( me.target.startX == 'l' )
        {
            me.startX = me.Crop.offsetLeft + parseInt ( me.Wand.style.left );
            me.addX   = e.clientX - (me.Crop.offsetLeft - me.scrollX + parseInt ( me.Wand.style.left ) + parseInt ( me.Wand.style.width ));
        }
        else if ( me.target.startX == 'r' )
        {
            me.startX = me.Crop.offsetLeft + parseInt ( me.Wand.style.left ) + parseInt ( me.Wand.style.width );
            me.addX   = e.clientX - (me.Crop.offsetLeft - me.scrollX + parseInt ( me.Wand.style.left ));
        }
        else
        {
            me.ignoreX = true;
        }

        if ( me.target.startY == 't' )
        {
            me.startY = me.Crop.offsetTop  + parseInt ( me.Wand.style.top );
            me.addY   = e.clientY - (me.Crop.offsetTop - me.scrollY + parseInt ( me.Wand.style.top ) + parseInt ( me.Wand.style.height ));
        }
        else if ( me.target.startY == 'b' )
        {
            me.startY = me.Crop.offsetTop  + parseInt ( me.Wand.style.top ) + parseInt ( me.Wand.style.height );
            me.addY   = e.clientY - (me.Crop.offsetTop - me.scrollY + parseInt ( me.Wand.style.top ));
        }
        else
        {
            me.ignoreY = true;
        }

        // absolute Werte in relative umrechnen
        me.addX /= me.target.offsetWidth;
        me.addY /= me.target.offsetHeight;

        me.target.origClass = me.target.className;
        me.target.className += ' active';

        me.WandAction     = true;
        me.Wand.className = 'wand_area wandaction';

        document.onmousemove = me.selectSize;
        document.onmouseup   = me.selectEnd;

        me.toggleTooltips ( false );

        return false;
    }

    // Auswahl markieren Größe ändern
    this.selectSize = function ( e )
    {
        if ( !me.isactive ) return;

        if ( typeof me.WandAction == 'undefined' || !me.WandAction )
            return;

        e = ( !e ) ? window.event : e;

        if ( me.target != null )
        {
            var clientX = Math.round ( e.clientX - ( me.addX * me.target.offsetWidth  ) );
            var clientY = Math.round ( e.clientY - ( me.addY * me.target.offsetHeight ) );

            if ( me.target.startX == 'l' && clientX < me.startX - me.scrollX + 1 ) clientX = me.startX - me.scrollX + 1;
            if ( me.target.startX == 'r' && clientX > me.startX - me.scrollX - 1 ) clientX = me.startX - me.scrollX - 1;
            if ( me.target.startY == 't' && clientY < me.startY - me.scrollY + 1 ) clientY = me.startY - me.scrollY + 1;
            if ( me.target.startY == 'b' && clientY > me.startY - me.scrollY - 1 ) clientY = me.startY - me.scrollY - 1;
        }
        else
        {
            var clientX = e.clientX;
            var clientY = e.clientY;
        }

        if ( !me.ignoreX )
        {
            if (      clientX < me.Crop.offsetLeft - me.scrollX )
                me.s_width = Math.max ( 0,                 me.startX - me.Crop.offsetLeft );
            else if ( clientX > me.Crop.offsetLeft - me.scrollX + me.Crop.width )
                me.s_width = Math.max ( 0, me.Crop.width - me.startX + me.Crop.offsetLeft );
            else
                me.s_width = Math.abs ( me.startX - clientX - me.scrollX );
        }

        if ( !me.ignoreY )
        {
            if (      clientY < me.Crop.offsetTop - me.scrollY )
                me.s_height = Math.max ( 0,                  me.startY - me.Crop.offsetTop );
            else if ( clientY > me.Crop.offsetTop - me.scrollY + me.Crop.height )
                me.s_height = Math.max ( 0, me.Crop.height - me.startY + me.Crop.offsetTop );
            else
                me.s_height = Math.abs ( me.startY - clientY - me.scrollY );
        }

        if ( me.s_height == 0 && me.s_width == 0 )
        {
            me.reset();

            return;
        }

        if ( me.fixAspectRatio != 0 )
        {
            if (      me.s_width / me.s_height > me.fixAspectRatio )
                me.s_width  = Math.round ( me.fixAspectRatio * me.s_height );
            else if ( me.s_width / me.s_height < me.fixAspectRatio )
                me.s_height = Math.round ( me.s_width / me.fixAspectRatio  );
        }

        me.Wand.style.width  = me.s_width  + 'px';
        me.Wand.style.height = me.s_height + 'px';

        me.C_L.height = me.C_R.height = me.s_height + 'px';

        // waagerecht
        if ( !me.ignoreX )
        {
            if ( me.startX > clientX + me.scrollX )
                me.Wand.style.left = me.C_L.width = me.startX - me.s_width - me.Crop.offsetLeft + 'px';
            else
                me.Wand.style.left = me.C_L.width = me.startX - me.Crop.offsetLeft + 'px';
        }

        // senkrecht
        if ( !me.ignoreY )
        {
            if ( me.startY > clientY + me.scrollY )
                me.Wand.style.top = me.C_T.height = me.C_L.top = me.C_R.top =
                    me.startY - me.s_height - me.Crop.offsetTop + 'px';
            else
                me.Wand.style.top = me.C_T.height = me.C_L.top = me.C_R.top =
                    me.startY - me.Crop.offsetTop + 'px';
        }

        me.C_R.width  = me.Crop.width  - parseInt ( me.C_L.width  ) - me.s_width  + 'px';
        me.C_B.height = me.Crop.height - parseInt ( me.C_T.height ) - me.s_height + 'px';

        return false;
    }

    // Auswahl markieren Ende
    this.selectEnd = function ( e )
    {
        if ( !me.isactive ||
             typeof me.WandAction == 'undefined' ||
             !me.WandAction )
            return;

        e = ( !e ) ? window.event : e;

        if ( me.s_width  == 0 || typeof me.s_width  == 'undefined' ||
             me.s_height == 0 || typeof me.s_height == 'undefined' ||
             me.startX == e.clientX + me.scrollX ||
             me.startY == e.clientY + me.scrollY )
        {
            me.reset();
        }
        else
        {
            me.icl.value = parseInt ( me.Wand.style.left   );
            me.ict.value = parseInt ( me.Wand.style.top    );
            me.icw.value = parseInt ( me.Wand.style.width  );
            me.ich.value = parseInt ( me.Wand.style.height );

            if ( me.WandAction )
            {
                me.Wand.className = 'wand_area move';

                me.Wand.onmousedown  = me.moveStart;
            }
        }

        document.onmousemove = null;
        document.onmouseup   = null;

        me.aspectRatio = me.s_height / me.s_width;
        me.WandAction  = false;

        if ( me.target != null )
        {
            me.target.className  = me.target.origClass;
            me.target.onmouseout = me.target.oldevent;
            me.target            = null;

            me.addX    = 0;
            me.addY    = 0;

            me.ignoreX = false;
            me.ignoreY = false;
        }

        me.toggleTooltips ( true );

        return false;
    }

    // Auswahl verschieben Anfang
    this.moveStart = function ( e )
    {
        if ( !me.isactive || me.WandAction ) return;

        e = ( !e ) ? window.event : e;

        me.WandAction = true;

        me.Wand.className = 'wand_area move wandaction';

        document.onmousemove = me.moveMove;
        document.onmouseup   = me.moveEnd;

        me.startX = e.clientX - me.Crop.offsetLeft;
        me.startY = e.clientY - me.Crop.offsetTop;

        me.toggleTooltips ( false );

        return false;
    }

    // Auswahl verschieben Bewegung
    this.moveMove = function ( e )
    {
        if ( !me.isactive ) return;

        if ( !me.WandAction )
            return;

        e = ( !e ) ? window.event : e;

        var t = parseInt ( me.Wand.style.top  ) - me.startY + e.clientY - me.Crop.offsetTop;
        var l = parseInt ( me.Wand.style.left ) - me.startX + e.clientX - me.Crop.offsetLeft;

        // prüfen, ob Selektion außerhalb des Bildes geht
        if ( t < 0 )
            t = 0;
        else if ( t + me.s_height > me.Crop.height )
            t = me.Crop.height - me.s_height;

        if ( l < 0 )
            l = 0;
        else if ( l + me.s_width  > me.Crop.width )
            l = me.Crop.width  - me.s_width;

        me.Wand.style.top  = t + 'px';
        me.Wand.style.left = l + 'px';

        me.startX = e.clientX - me.Crop.offsetLeft;
        me.startY = e.clientY - me.Crop.offsetTop;

        me.C_T.height = t + 'px';
        me.C_L.top    = t + 'px';
        me.C_L.width  = l + 'px';
        me.C_R.top    = t + 'px';
        me.C_R.width  = me.Crop.width  - parseInt ( me.C_L.width  ) - me.s_width  + 'px';
        me.C_B.height = me.Crop.height - parseInt ( me.C_T.height ) - me.s_height + 'px';

        return false;
    }

    // Auswahl verschieben Ende
    this.moveEnd = function ( e )
    {
        if ( !me.isactive ) return;

        e = ( !e ) ? window.event : e;

        me.ict.value = parseInt ( me.Wand.style.top  );
        me.icl.value = parseInt ( me.Wand.style.left );

        me.WandAction = false;
        me.Wand.className = 'wand_area move';

        document.onmousemove = null;
        document.onmouseup   = null;

        me.toggleTooltips ( true );

        return false;
    }

    // größtmögliche Auswahl treffen
    this.maximizeSelection = function()
    {
        me.s_width  = me.Crop.width;
        me.s_height = me.Crop.height;

        if ( me.fixAspectRatio != 0 )
        {
            if (      me.s_width / me.s_height > me.fixAspectRatio )
                me.s_width  = Math.round ( me.fixAspectRatio * me.s_height );
            else if ( me.s_width / me.s_height < me.fixAspectRatio )
                me.s_height = Math.round ( me.s_width / me.fixAspectRatio  );
        }

        me.icl.value = me.ict.value = 0;
        me.ich.value = me.s_height;
        me.icw.value = me.s_width;

        me.aspectRatio = me.s_height / me.s_width;

        me.Wand.style.top    = '0px';
        me.Wand.style.left   = '0px';
        me.Wand.style.height = me.s_height + 'px';
        me.Wand.style.width  = me.s_width  + 'px';

        me.C_T.height = me.C_L.width   = me.C_L.top = me.C_R.top ='0px';
        me.C_L.height = me.C_R.height  = me.s_height + 'px';
        me.C_R.width  = me.Crop.width  - me.s_width  + 'px';
        me.C_B.height = me.Crop.height - me.s_height + 'px';

        me.Wand.className = 'wand_area move';

        me.Wand.onmousedown = me.moveStart;
    }

    // Behandlung von Tastatur-Eingaben
    this.keyAction = function ( e )
    {
        if ( !me.isactive ) return;

        e = ( !e ) ? window.event : e;

        if ( document.all )
            var k = e.keyCode;
        else
            var k = e.which;

        // größtmögliche Auswahl treffen (POS1)
        if ( k == 36 )
        {
            me.maximizeSelection();
            return false;
        }

        if ( me.s_height == 0 || me.s_width == 0 ) return;


        // Auswahl aufheben (END, ESC, ENTF)
        if ( k == 35 || k == 27 || k == 46 )
        {
            me.reset();
            return false;
        }

        if ( e.shiftKey )
            var value = 10;
        else
            var value = 1;

        // links
        if ( k == 37 )
        {
            if ( parseInt ( me.Wand.style.left ) - value >= 0 )
            {
                me.Wand.style.left = ( parseInt ( me.Wand.style.left ) - value ) + 'px';
                me.icl.value = parseInt ( me.icl.value ) - value;

                me.C_L.width = parseInt ( me.C_L.width ) - value + 'px';
                me.C_R.width = parseInt ( me.C_R.width ) + value + 'px';
            }

            return false;
        }

        // hoch
        if ( k == 38 )
        {
            if ( parseInt ( me.Wand.style.top ) - value >= 0 )
            {
                me.Wand.style.top = ( parseInt ( me.Wand.style.top ) - value ) + 'px';
                me.ict.value = parseInt ( me.ict.value ) - value;

                me.C_T.height = parseInt ( me.C_T.height ) - value + 'px';
                me.C_B.height = parseInt ( me.C_B.height ) + value + 'px';
                me.C_R.top    = parseInt ( me.C_R.top    ) - value + 'px';
                me.C_L.top    = parseInt ( me.C_L.top    ) - value + 'px';
            }

            return false;
        }

        // rechts
        if ( k == 39 )
        {
            if ( parseInt ( me.Wand.style.left ) + me.s_width + value <= me.Crop.width )
            {
                me.Wand.style.left = ( parseInt ( me.Wand.style.left ) + value ) + 'px';
                me.icl.value = parseInt ( me.icl.value ) + value;

                me.C_L.width = parseInt ( me.C_L.width ) + value + 'px';
                me.C_R.width = parseInt ( me.C_R.width ) - value + 'px';
            }

            return false;
        }

        // runter
        if ( k == 40 )
        {
            if ( parseInt ( me.Wand.style.top ) + me.s_height + value <= me.Crop.height )
            {
                me.Wand.style.top = ( parseInt ( me.Wand.style.top ) + value ) + 'px';
                me.ict.value = parseInt ( me.ict.value ) + value;

                me.C_T.height = parseInt ( me.C_T.height ) + value + 'px';
                me.C_B.height = parseInt ( me.C_B.height ) - value + 'px';
                me.C_R.top    = parseInt ( me.C_R.top    ) + value + 'px';
                me.C_L.top    = parseInt ( me.C_L.top    ) + value + 'px';
            }

            return false;
        }

        // proportional vergrößern (PGUP)
        if ( k == 33  )
        {
            if ( parseInt ( me.Wand.style.top  ) + me.s_height + value <= me.Crop.height &&
                 parseInt ( me.Wand.style.left ) + me.s_width  + value <= me.Crop.width )
            {
                if ( me.aspectRatio < 1 )
                {
                    me.s_width += value;
                    me.s_height = Math.round ( me.aspectRatio * me.s_width );
                }
                else
                {
                    me.s_height += value;
                    me.s_width   = Math.round ( me.s_height / me.aspectRatio );
                }

                me.Wand.style.width  = me.s_width  + 'px';
                me.Wand.style.height = me.s_height + 'px';

                me.icw.value = me.s_width;
                me.ich.value = me.s_height;

                me.C_R.width  = me.Crop.width  - parseInt ( me.C_L.width  ) - me.s_width  + 'px';
                me.C_B.height = me.Crop.height - parseInt ( me.C_T.height ) - me.s_height + 'px';
                me.C_L.height = me.s_height + 'px';
                me.C_R.height = me.s_height + 'px';
            }

            return false;
        }

        // proportional verkleinern (PGDN)
        if ( k == 34 )
        {
            if ( me.s_height > value && me.s_width > value )
            {
                if ( me.aspectRatio < 1 )
                {
                    me.s_width -= value;
                    me.s_height = Math.round ( me.aspectRatio * me.s_width );
                }
                else
                {
                    me.s_height -= value;
                    me.s_width   = Math.round ( me.s_height / me.aspectRatio );
                }

                me.Wand.style.width  = me.s_width  + 'px';
                me.Wand.style.height = me.s_height + 'px';

                me.icw.value = me.s_width;
                me.ich.value = me.s_height;

                me.C_R.width  = me.Crop.width  - parseInt ( me.C_L.width  ) - me.s_width  + 'px';
                me.C_B.height = me.Crop.height - parseInt ( me.C_T.height ) - me.s_height + 'px';
                me.C_L.height = me.s_height + 'px';
                me.C_R.height = me.s_height + 'px';
            }

            return false;
        }
    }

    // definierte Auswahl treffen
    this.setSelection = function ( left, top, width, height )
    {
        // erstmal in Zahlen umwandeln, sicher ist sicher
        me.s_width  = parseInt ( width  );
        me.s_height = parseInt ( height );
        left        = parseInt ( left   );
        top         = parseInt ( top    );

        // festes Seitenverhältnis beachten
        if ( me.fixAspectRatio != 0 )
        {
            if (      me.s_width / me.s_height > me.fixAspectRatio )
                me.s_width  = Math.round ( me.fixAspectRatio * me.s_height );
            else if ( me.s_width / me.s_height < me.fixAspectRatio )
                me.s_height = Math.round ( me.s_width / me.fixAspectRatio  );
        }

        me.Wand.style.left   = me.C_L.width  = left + 'px';
        me.Wand.style.top    = me.C_T.height = me.C_R.top = me.C_L.top = top  + 'px';
        me.Wand.style.width  = me.s_width + 'px';
        me.Wand.style.height = me.C_R.height = me.C_L.height = me.s_height + 'px';

        me.C_R.width  = me.Crop.width  - me.s_width  - left + 'px';
        me.C_B.height = me.Crop.height - me.s_height - top  + 'px';

        me.icl.value = left;
        me.ict.value = top;
        me.icw.value = me.s_width;
        me.ich.value = me.s_height;

        me.Wand.className = 'wand_area move';

        me.Wand.onmousedown = me.moveStart;

        me.aspectRatio = me.s_height / me.s_width;
        me.WandAction  = false;
    }

    // festes Seitenverhältnis setzen
    this.setAspectRatio = function ( ratio )
    {
        if ( ratio == null || ratio == '' || ratio == 0 )
        {
            me.fixAspectRatio = 0;

            if ( me.Crop.fixRatio )
            {
                me.Crop.fixRatio = false;
                me.Crop.className = me.Crop.origClass;
            }
        }
        else
        {
            me.fixAspectRatio = 0 + ratio;

            if ( !me.Crop.fixRatio )
            {
                me.Crop.fixRatio = true;
                me.Crop.origClass = me.Crop.className;
                me.Crop.className += ' fixratio';
            }

            // wenn bereits eine Auswahl besteht:
            // diese auf neues Seitenverhältnis anpassen
            if ( me.s_width != 0 && me.s_height != 0 )
                me.setSelection ( me.C_L.width, me.C_T.height, me.s_width, me.s_height );
        }
    }

    // alle Werte zurücksetzen
    this.reset = function()
    {
        me.Wand.style.width = me.Wand.style.height = me.Wand.style.top = me.Wand.style.left = '0px';

        me.C_T.height = me.C_L.width = me.C_R.width = me.C_B.height = '0px';
        me.icl.value  = me.ict.value = me.icw.value = me.ich.value  = 0;
        me.s_height   = me.s_width   = 0;
    }

    // title-Attribute für bestimmte Elemente setzen
    this.setI18Ntitle = function ( name, text )
    {
        if ( name == 'resizers' )
        {
            me.resizer_tl.title = me.resizer_tl.oldTitle = text;
            me.resizer_tr.title = me.resizer_tr.oldTitle = text;
            me.resizer_bl.title = me.resizer_bl.oldTitle = text;
            me.resizer_br.title = me.resizer_br.oldTitle = text;

            me.resizer_t.title = me.resizer_t.oldTitle = text;
            me.resizer_b.title = me.resizer_b.oldTitle = text;
            me.resizer_l.title = me.resizer_l.oldTitle = text;
            me.resizer_r.title = me.resizer_r.oldTitle = text;
        }
        else
        {
            eval ( 'me.' + name + '.title = me.' + name + '.oldTitle = "' + text + '";');
        }
    }

    this.toggleTooltips = function ( act )
    {
        if ( act )
        {
            me.resizer_tl.title = me.resizer_tl.oldTitle;
            me.resizer_tr.title = me.resizer_tr.oldTitle;
            me.resizer_bl.title = me.resizer_bl.oldTitle;
            me.resizer_br.title = me.resizer_br.oldTitle;

            me.resizer_t.title = me.resizer_t.oldTitle;
            me.resizer_b.title = me.resizer_b.oldTitle;
            me.resizer_l.title = me.resizer_l.oldTitle;
            me.resizer_r.title = me.resizer_r.oldTitle;

            me.Wand.title = me.Wand.oldTitle;
            me.Act.title  = me.Act.oldTitle;
        }
        else
        {
            me.resizer_tl.title = '';
            me.resizer_tr.title = '';
            me.resizer_bl.title = '';
            me.resizer_br.title = '';

            me.resizer_t.title = '';
            me.resizer_b.title = '';
            me.resizer_l.title = '';
            me.resizer_r.title = '';

            me.Wand.title = '';
            me.Act.title  = '';
        }
    }

    var me = this;

    // handelt es sich hierbei um die gerade aktive Instanz?
    // muss mittels setActive()-Methode definiert werden, bevor
    // Maus- oder Tastatureingaben angenommen werden
    me.isactive = false;

    // Startpunkt der Selektion und deren Höhe und Breite
    me.startX   = 0;
    me.startY   = 0;
    me.s_height = 0;
    me.s_width  = 0;

    // aktuelle Scroll-Position im Dokument
    me.scrollX  = 0;
    me.scrollY  = 0;

    // Versatz beim Resizen
    me.addX     = 0;
    me.addY     = 0;

    // aktives Resize-Handle
    me.target   = null;

    // Mausbewegungen beim Resizen ignorieren?
    me.ignoreX  = false;
    me.ignoreY  = false;

    // Seitenverhältnis der Selektion sowie deren festgeschriebener Wert
    me.aspectRatio    = 1;
    me.fixAspectRatio = 0;

    me.WandAction = false;

    // Verweise auf die benötigten DOM-Elemente
    me.Crop = window.document.getElementById(el_crop);
    me.Act  = window.document.getElementById(el_actarea);

    // Auswahlrahmen generieren
    me.Wand = me.Crop.appendChild(document.createElement('DIV'));
    me.Wand.className = 'wand_area';

    me.Crop.fixRatio  = false;

    // Cover-Bereiche
    temp = me.Crop.appendChild(document.createElement('DIV'));
    temp.style.top   = '0px';
    temp.style.left  = '0px';
    temp.style.width = '100%';
    temp.className   = 'cover';
    temp.innerHTML   = 'fuck IE 6';
    me.C_T = temp.style;

    temp = me.Crop.appendChild(document.createElement('DIV'));
    temp.style.bottom = '0px';
    temp.style.left   = '0px';
    temp.style.width  = '100%'
    temp.innerHTML    = 'fuck IE 6';;
    temp.className    = 'cover';
    me.C_B = temp.style;

    temp = me.Crop.appendChild(document.createElement('DIV'));
    temp.style.left   = '0px';
    temp.style.height = '100%';
    temp.className    = 'cover'
    me.C_L = temp.style;

    temp = me.Crop.appendChild(document.createElement('DIV'));
    temp.style.right  = '0px';
    temp.style.height = '100%';
    temp.className    = 'cover'
    me.C_R = temp.style;

    // Rahmenlinien
    wand_top = me.Wand.appendChild(document.createElement('DIV'));
    wand_top.style.top = '0px';
    wand_top.className = 'wand h_wand';

    wand_bottom = me.Wand.appendChild(document.createElement('DIV'));
    wand_bottom.style.bottom = '0px';
    wand_bottom.className    = 'wand h_wand';

    wand_left = me.Wand.appendChild(document.createElement('DIV'));
    wand_left.style.left = '0px';
    wand_left.className  = 'wand v_wand';

    wand_right = me.Wand.appendChild(document.createElement('DIV'));
    wand_right.style.right = '0px';
    wand_right.className   = 'wand v_wand';

    // Resize-Handles
    me.resizer_t = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_t.className   = 'r_hor resizer n';
    me.resizer_t.startY      = 'b';
    me.resizer_t.onmousedown = this.resizeStart;

    me.resizer_b = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_b.className   = 'r_hor resizer s';
    me.resizer_b.startY      = 't';
    me.resizer_b.onmousedown = this.resizeStart;

    me.resizer_l = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_l.className   = 'r_ver resizer w';
    me.resizer_l.startX      = 'r';
    me.resizer_l.onmousedown = this.resizeStart;

    me.resizer_r = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_r.className   = 'r_ver resizer e';
    me.resizer_r.startX      = 'l';
    me.resizer_r.onmousedown = this.resizeStart;

    me.resizer_tl = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_tl.className   = 'corner resizer nw';
    me.resizer_tl.startX      = 'r';
    me.resizer_tl.startY      = 'b';
    me.resizer_tl.onmousedown = this.resizeStart;

    me.resizer_tr = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_tr.className   = 'corner resizer ne';
    me.resizer_tr.startX      = 'l';
    me.resizer_tr.startY      = 'b';
    me.resizer_tr.onmousedown = this.resizeStart;

    me.resizer_bl = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_bl.className   = 'corner resizer sw';
    me.resizer_bl.startX      = 'r';
    me.resizer_bl.startY      = 't';
    me.resizer_bl.onmousedown = this.resizeStart;

    me.resizer_br = me.Wand.appendChild(document.createElement('DIV'));
    me.resizer_br.className   = 'corner resizer se';
    me.resizer_br.startX      = 'l';
    me.resizer_br.startY      = 't';
    me.resizer_br.onmousedown = this.resizeStart;

    // Formularfelder für die Ausgabe der Auswahlgröße und -Position
    me.icl  = document.getElementById(c_left);
    me.ict  = document.getElementById(c_top);
    me.icw  = document.getElementById(c_width);
    me.ich  = document.getElementById(c_height);

    // wird häufiger gebraucht, daher kürzer als Property
    me.Crop.width  = parseInt ( me.Crop.style.width  );
    me.Crop.height = parseInt ( me.Crop.style.height );

    // alle Werte initialisieren
    me.reset();
}
