/******************************************************************************************
* Visual response scale for spatial orientation tasks
* v0.1beta
*
* http://timo.gnambs.at
*
* Copyright (c) 2004 Timo Gnambs. All rights reserved.
* Created 2004-08-29 by Timo Gnambs <timo@gnambs.at>
* Last modified 2004-08-30
*
*
* Requires wz_dragdrop.js and wz_jsgraphics created by Walter Zorn
* available at http://www.walterzorn.de
*
* This script has been tested with wz_dragdrop.js v4.55
* and wz_jsgraphics v2.3
*
*
* Any comments, suggestions or bug reports should be adressed
* to Timo Gnambs <timo@gnambs.at>
*
******************************************************************************************/



//global container for all scales
var os = new Array();



/**
 * The circle object
 */
function circle() {
    this.stroke = 1;            //stroke width of circle
    this.color = '#000000';     //color of circle
    this.radius = 50;           //radius of circle
    this.x = 0;                 //position of circle (x)  [there shouldnīt be a reason to change this]
    this.y = 0;                 //position of circle (y)  [there shouldnīt be a reason to change this]
}


/**
 * The line object
 */
function line() {
    this.stroke = 1;            //stroke width of line
    this.color = '#000000';     //color of line
    this.graph = false;         //instanc of jsgraphics [donīt override this setting!!]
}


/**
 * The marker object
 */
function marker() {
    this.img = '';              //image source for marker (optional)
    this.img_w = '';            //image width (optional; but it should be set when using images)
    this.img_h = '';            //image height (optional; but it should be set when using images)
    this.text = '';             //text as marker (optional)
    this.text_size = '';        //text size (optional; in pixel)
    this.text_family = '';      //font family (optional)
    this.text_stile = '';       //make text bold (optional; possible values: BOLD, ITALIC, BOLD_ITALIC)
    this.text_corrx = 0;        //x correction for positioning text
    this.text_dist = 0;        //y correction for positioning text
    this.stroke = 1;            //stroke width of marker
    this.color = '#000000';     //color of marker
    this.w = 10;                //width of marker
    this.h = 10;                //height of marker
}


/**
 * The scale object
 */
function scale() {
   
    //properties of scale
    this.drawRefline = 1;       //draw the reference line (boolean)
    this.name = 'item' + os.length;  //name of hidden form field
    this.x = 0;                 //center of circle (x) [gets set on runtime]
    this.y = 0;                 //center of circle (y) [gets set on runtime]
   
    //objects composing the scale
    this.circle = new circle(); //the circle
    this.line = new line();     //the answer line
    if(this.drawRefline) this.refline = new line(); //the reference line
    this.center = new marker(); //the center
    this.marker = new marker(); //the answer marker
    this.refmarker = new marker(); //ther reference marker
    
    //print scale
    this.print = printScale;
    
    //add scale to global var
    os[os.length] = this;
}


/**
 * Prints the necessary html objects for the scale
 */
function printScale() {
    //transparent image as background
    document.write('<img id="os_img_' + (os.length-1) + '"');
    document.write(' name="os_img_' + (os.length-1) + '"');
    document.write(' src="/sites/all/themes/gnambs/scripts/orientationscales/transparentpixel.gif" width="' + (this.circle.radius*2) + '"');
    document.writeln(' height="' + (this.circle.radius*2) + '" alt="" />');
    
    //div for answer marker
    document.writeln('<div id="os_marker_' + (os.length-1) + '" style="position:absolute;top:0;left:0;"></div>');
    
    //answer marker image
    if(this.marker.img != '') {
        document.write('<img id="os_marker_img_' + (os.length-1) + '"');
        document.write(' name="os_marker_img_' + (os.length-1) + '"');
        document.write(' src="' + this.marker.img + '"');
        if(this.marker.img_w > 0) document.write(' width="' + this.marker.img_w + '"');
        if(this.marker.img_h > 0) document.write(' height="' + this.marker.img_h + '"');
        document.writeln(' alt="" />');
    }
    
    //reference marker image
    if(this.refmarker.img != '') {
        document.write('<img id="os_refmarker_img_' + (os.length-1) + '"');
        document.write(' name="os_refmarker_img_' + (os.length-1) + '"');
        document.write(' src="' + this.refmarker.img + '"');
        if(this.refmarker.img_w > 0) document.write(' width="' + this.refmarker.img_w + '"');
        if(this.refmarker.img_h > 0) document.write(' height="' + this.refmarker.img_h + '"');
        document.writeln(' alt="" />');
    }
    
    //hidden form field to save the answer to
    document.writeln('<input type="hidden" name="' + this.name + '" id="' + this.name + '" value="-9" />');
    
    //center image
    if(this.center.img != '') {
        document.write('<img id="os_center_img_' + (os.length-1) + '"');
        document.write(' name="os_center_img_' + (os.length-1) + '"');
        document.write(' src="' + this.center.img + '"');
        if(this.center.img_w > 0) document.write(' width="' + this.center.img_w + '"');
        if(this.center.img_h > 0) document.write(' height="' + this.center.img_h + '"');
        document.writeln(' alt="" />');
    }
}


/**
 * Constructor to set the inital states of the scales
 */
function init() {

    //initialise the dragdrop script
    initDragdrop();
    
    for(var i = 0; i < os.length; i++) {
        //calculate center
        os[i].x = dd.elements['os_img_' + i].x + os[i].circle.radius;
        os[i].y = dd.elements['os_img_' + i].y + os[i].circle.radius;
        
        //graphic object
        var jg_doc = new jsGraphics();
        
        //print circle
        jg_doc.setStroke(os[i].circle.stroke);
        jg_doc.setColor(os[i].circle.color);
        jg_doc.drawEllipse(dd.elements['os_img_' + i].x, dd.elements['os_img_' + i].y, os[i].circle.radius*2, os[i].circle.radius*2);
        jg_doc.paint();
        
        //print center
        if(os[i].center.img == '') {
            jg_doc.setStroke(os[i].center.stroke);
            jg_doc.setColor(os[i].center.color);
            jg_doc.drawLine(os[i].x-os[i].center.w/2, os[i].y-os[i].center.h/2, os[i].x+os[i].center.w/2, os[i].y+os[i].center.h/2);
            jg_doc.drawLine(os[i].x-os[i].center.w/2, os[i].y+os[i].center.h/2, os[i].x+os[i].center.w/2, os[i].y-os[i].center.h/2);
            jg_doc.paint();
        } else {
            dd.elements['os_center_img_' + i].moveTo(os[i].x-dd.elements['os_center_img_' + i].w/2, os[i].y-dd.elements['os_center_img_' + i].h/2);
        }
        //print text for center
        if(os[i].center.text != '') {
            var fontfamily = (os[i].center.text_family == '') ? 'sans_serif' : os[i].center.text_family;
            var fontsize = (os[i].center.text_size == '') ? 12 : os[i].center.text_size;
            var fontstile = (os[i].center.text_stile === 'BOLD' || os[i].center.text_stile === 'ITALIC' || 
                             os[i].center.text_stile === 'BOLD_ITALIC' || os[i].center.text_stile === 'ITALIC_BOLD') ?
                                 os[i].center.text_stile : 'PLAIN';
            jg_doc.setFont(fontfamily, fontsize+'px', 'Font.'+fontstile);
            jg_doc.drawString(os[i].center.text, os[i].x+os[i].center.text_corrx, os[i].y+os[i].center.text_corry);
            jg_doc.paint();
        }

        //print reference marker
        if(os[i].refmarker.img == '') {
            jg_doc.setStroke(os[i].refmarker.stroke);
            jg_doc.setColor(os[i].refmarker.color);
            jg_doc.drawLine(os[i].x-os[i].refmarker.w/2, dd.elements['os_img_' + i].y-os[i].refmarker.h/2, os[i].x+os[i].refmarker.w/2, dd.elements['os_img_' + i].y+os[i].refmarker.h/2);
            jg_doc.drawLine(os[i].x-os[i].refmarker.w/2, dd.elements['os_img_' + i].y+os[i].refmarker.h/2, os[i].x+os[i].refmarker.w/2, dd.elements['os_img_' + i].y-os[i].refmarker.h/2);
            jg_doc.paint();
        } else {
            dd.elements['os_refmarker_img_' + i].moveTo(dd.elements['os_img_' + i].x+os[i].circle.radius-os[i].refmarker.img_w/2, dd.elements['os_img_' + i].y-os[i].refmarker.img_h/2);
        }
        
        //print reference line
        if(os[i].drawRefline) {
            jg_doc.setStroke(os[i].refline.stroke);
            jg_doc.setColor(os[i].refline.color);
            jg_doc.drawLine(os[i].x, os[i].y, os[i].x, dd.elements['os_img_' + i].y);
            jg_doc.paint();
        }
        
        //position answer marker
        dd.elements['os_marker_' + i].resizeTo(os[i].circle.radius*2, os[i].circle.radius*2);         
        dd.elements['os_marker_' + i].moveTo(dd.elements['os_img_' + i].x, dd.elements['os_img_' + i].y);
        os[i].line.graph = new jsGraphics('os_marker_' + i);
        if(os[i].marker.img != '') dd.elements['os_marker_img_' + i].hide();
    }

}


/**
* Parse string for id (= last number)
*
* @param   string    string    string to parse
* @return  integer             id
*/
function getId(string) {
    var result = string.match(/^\D+(\d+)$/);
    return result[1];           
}


/**
 * Initialise the dragdrop library
 */
function initDragdrop() {
    var dragdrop = 'NO_SCROLL+CURSOR_HAND';
            
    for(var i = 0; i < os.length; i++) {
        dragdrop += ', "os_img_' + i + '"+HORIZONTAL+MAXOFFLEFT+0+MAXOFFRIGHT+0';
        dragdrop += ', "os_marker_' + i + '"+NO_DRAG';
        
        if(os[i].center.img != '') {
            dragdrop += ', "os_center_img_' + i + '"+NO_DRAG';
        }
        if(os[i].marker.img != '') {
            dragdrop += ', "os_marker_img_' + i + '"+NO_DRAG';
        }
        if(os[i].refmarker.img != '') {
            dragdrop += ', "os_refmarker_img_' + i + '"+NO_DRAG';
        }

    }

    /* initialise the dragdrop script */
    eval("SET_DHTML(" + dragdrop + ")");
}


/**
* Set value of hidden form element
*
* @param  string   name    name of form element
* @param  integer  content value to set form value to
* @return bool
*/
function setFormValue(name, content) {
    if (document.getElementById) document.getElementById(name).value = content;
    else if(document.all) document.all[name].value = content;
    else if (document.layers) document.forms[0].elements[name].value = content;

    //debug("Wert (" + name + "): " + content);
    return true;
}


/**
* Alert form input
*
* @return   bool
*/
function processForm() {
    var element, msg = "Gesendete Daten:\n\n";
            
    for(var i = 0; i < document.forms[0].length-1; i++) {
        element = document.forms[0].elements[i];
        msg += element.name + ": " + element.value;
        msg += "\n";
    }
            
    alert(msg);
    return false;
}


/**
* Construct and print debug layer
*
* @param   string   msg     message to print
*/        
function debug(msg) {
    if(!debug.box) {
        debug.box = document.createElement("div");
        debug.box.setAttribute("style",
                                "background-color: #FFFFFF; " + 
                                "font-family: monospace; " + 
                                "font-size:10px; " +
                                "border: solid black 3px; " + 
                                "padding: 10px; " + 
                                "position: absolute; " + 
                                "top: 10px; " + 
                                "right: 10px;");
        document.body.appendChild(debug.box);
                
        var h1 = document.createElement("h1");
        h1.appendChild(document.createTextNode("Ergebnis"));
        h1.setAttribute("style", "font-size: 10px;");
        debug.box.appendChild(h1);
    }
            
    var p = document.createElement("p");
    p.appendChild(document.createTextNode(msg));
    debug.box.appendChild(p);
}


/**
 * Calculate width on circle
 */
function calcCircleW() {
    if(calcCircleW.arguments.length < 2) return false;
    
    var radius = calcCircleW.arguments[0];
    var rel = calcCircleW.arguments[1];
    return Math.sqrt(Math.pow(radius, 2) / (1 + Math.pow(rel, 2)));
}


/****************
* These functions are processed by wz_dragdrop.js
****************/
        
/**
* my_PickFunc IS AUTOMATICALLY CALLED WHEN AN ITEM STARTS TO BE DRAGGED.
*/
function my_PickFunc()
{
    //determine id of current scale
    var id = getId(dd.obj.name);
    dd.elements['os_marker_' + id].maximizeZ();
    
    //calculate distance of click from center
    var click_w = Math.abs(dd.e.x - os[id].x);
    var click_h = Math.abs(dd.e.y - os[id].y);
    var rel = click_h / click_w;
    //click width on circle
    var total_w = calcCircleW(os[id].circle.radius, rel);
    var winkel = 0;
    

    
    if(click_w > 0) {

        //calculate winkel (Kosinussatz: aē=bē+cē-2*b*c*cos Alpha)
        //cos(alpha) = b2+c2 -a2 / 2bc
        winkel = (Math.pow(total_w, 2) + Math.pow(os[id].circle.radius, 2) - Math.pow(total_w*rel, 2)) / (2 * total_w * os[id].circle.radius);
        winkel = Math.acos(winkel) / (Math.PI / 180); //transform radiant to degree!!!
    
        //calculate winkel dependent on section of circle
        if(dd.e.x >= os[id].x && dd.e.y <= os[id].y) {
            winkel = 90-winkel;
        } else if(dd.e.x >= os[id].x && dd.e.y > os[id].y) {
            winkel = 90+winkel;
        } else if(dd.e.x < os[id].x && dd.e.y <= os[id].y) {
            winkel = 270+winkel;
        } else {
            winkel = 270-winkel;
        }
        
        //calculate position on circle
        var posx = posy = 0;
        if(dd.e.x >= os[id].x) {
            posx = os[id].circle.radius + total_w;
        } else {
            posx = os[id].circle.radius - total_w;
        }
        if(dd.e.y <= os[id].y) {
            posy = os[id].circle.radius - (total_w  * rel);
        } else {
            posy = os[id].circle.radius + (total_w  * rel);
        }
        
    //in case the click matched exactly the vertical of the circle, there is no total_w to calculate
    } else {
        winkel = (dd.e.y <= os[id].y) ? 0 : 180;
        posx = os[id].circle.radius;
        posy = (dd.e.y <= os[id].y) ? 0 : dd.elements['os_img_' + id].h;
    }
    
    //save position to hidden form field
    setFormValue(os[id].name, Math.round(winkel)); 

    //print line 
    os[id].line.graph.clear();
    os[id].line.graph.setStroke(os[id].line.stroke);
    os[id].line.graph.setColor(os[id].line.color);
    os[id].line.graph.drawLine(os[id].circle.radius, os[id].circle.radius, posx, posy);
    os[id].line.graph.paint();
    
    //set reference marker
    if(os[id].marker.img == '') {
    
        os[id].line.graph.setStroke(os[id].marker.stroke);
        os[id].line.graph.setColor(os[id].marker.color);
        os[id].line.graph.drawLine(posx-os[id].marker.w/2, posy-os[id].marker.h/2, posx+os[id].marker.w/2, posy+os[id].marker.h/2);
        os[id].line.graph.drawLine(posx+os[id].marker.w/2, posy-os[id].marker.h/2, posx-os[id].marker.w/2, posy+os[id].marker.h/2);
        os[id].line.graph.paint();
    
    } else {
    
        if(click_w > 0) {
            //total_w = Math.sqrt(Math.pow(os[id].circle.radius, 2) / (1 + Math.pow(rel, 2)));

            if(dd.e.x >= os[id].x) {
                posx = os[id].circle.radius + dd.elements['os_img_' + id].x + total_w - os[id].marker.img_w/2;
            } else {
                posx = os[id].circle.radius + dd.elements['os_img_' + id].x - total_w - os[id].marker.img_w/2;
            }
            if(dd.e.y <= os[id].y) {
                posy = os[id].circle.radius + dd.elements['os_img_' + id].y - (total_w  * rel) - os[id].marker.img_h/2;
            } else {
                posy = os[id].circle.radius + dd.elements['os_img_' + id].y + (total_w  * rel) - os[id].marker.img_h/2;
            }
            if(posx < 0) posx = 0;
            if(posy < 0) posy = 0;
        } else {
            posx = os[id].x-os[id].marker.img_w/2;
            posy = (dd.e.y <= os[id].y) ? dd.elements['os_img_' + id].y - os[id].marker.img_h*0.5 : dd.elements['os_img_' + id].y + os[id].circle.radius*2 - os[id].marker.img_h/2;
        }
        
        dd.elements['os_marker_img_' + id].moveTo(posx, posy);
        dd.elements['os_marker_img_' + id].show();
    }
    
    //print text for marker
    if(os[id].marker.text != '') {
        var fontfamily = (os[id].marker.text_family == '') ? 'sans_serif' : os[id].marker.text_family;
        var fontsize = (os[id].marker.text_size == '') ? 12 : os[id].marker.text_size;
        var fontstile = (os[id].marker.text_stile == 'BOLD' || os[id].marker.text_stile == 'ITALIC' || 
                            os[id].marker.text_stile == 'BOLD_ITALIC' || os[id].marker.text_stile == 'ITALIC_BOLD') ?
                                os[id].marker.text_stile : 'PLAIN';
        os[id].line.graph.setFont(fontfamily, fontsize+'px', 'Font.'+fontstile);
        
        if(click_w > 0) {
            total_w = calcCircleW(os[id].circle.radius+os[id].marker.text_dist, rel);

            if(dd.e.x >= os[id].x) {
                posx = os[id].circle.radius + total_w;
            } else {
                //posx = os[id].circle.radius - total_w - os[id].marker.text_dist-80;
                posx = -50;
            }
            if(dd.e.y <= os[id].y) {
                posy = os[id].circle.radius - (total_w  * rel) - os[id].marker.text_dist;
            } else {
                posy = os[id].circle.radius + (total_w  * rel);
            }
            if(posx < 0) posx = 0;
            if(posy < 0) posy = 0;
        } else {
            posx = os[id].center.radius;
            posy = (dd.e.y <= os[id].y) ? -os[id].marker.text_dist : os[id].circle.radius*2 - os[id].marker.text_dist;
        }
               
        os[id].line.graph.drawString(os[id].marker.text, posx, posy);
        os[id].line.graph.paint();
    }
}

