class Rect {
    constructor(w, h, x1=0, y1=0, alpha=0, text = "", fontSize = 20){
        this.w = Math.abs(w);
        this.h = Math.abs(h);
        this.x1 = x1;
        this.y1 = y1;
        this.alpha = alpha;
        this.alphaRad = this.alpha*Math.PI/180;
        this.text = text;
        this.fontSize = fontSize;
        this.initBoundingBox();
    }
    refresh(){
        this.w = Math.abs(this.w);
        this.h = Math.abs(this.h);
        this.alphaRad = this.alpha*Math.PI/180;
        this.initBoundingBox();
    }
    getQuadrant(){
        if(0<=this.alphaRad<Math.PI/2) return 1;
        if(Math.PI/2<=this.alphaRad<Math.PI) return 2;
        if(Math.PI<=this.alphaRad<3*Math.PI/2) return 3;
        if(3*Math.PI/2<=this.alphaRad<2*Math.PI) return 4;
    }
    initBoundingBox(){
        let cAlpha = Math.cos(this.alphaRad);
        let sAlpha = Math.sin(this.alphaRad);
        this.xx = [this.x1, this.x1 + this.w*cAlpha, this.x1 + this.w*cAlpha - this.h*sAlpha, this.x1 - this.h*sAlpha];
        this.yy = [this.y1, this.y1 + this.w*sAlpha, this.y1 + this.w*sAlpha + this.h*cAlpha, this.y1 + this.h*cAlpha];
        this.minX = Math.min(...this.xx);
        this.maxX = Math.max(...this.xx);
        this.minY = Math.min(...this.yy);
        this.maxY = Math.max(...this.yy);
    }

    printCoords(showRectangles=true, maxFontSize=80, minFontSize=20){
        let styleR = ' style="fill:red;stroke:black;stroke-width:2;opacity:0.5"';
        let styleG = ' style="fill:green;stroke:black;stroke-width:2;opacity:0.5"';
        let styleB = ' style="fill:blue;stroke:black;stroke-width:2;opacity:0.5"';
        let style;
        let selector = Math.floor(Math.random()*3);
        //console.log('sel', selector);
        if(selector==0) style=styleR;
        if(selector==1) style=styleG;
        if(selector==2) style=styleB;
        //console.log('st', style);
        let toRet = "";
        let rectCoordsHtml = ' x="'+this.x1+'" y="'+this.y1+'" width="'+(this.w)+'" height="'+(this.h)+'"';
        let rotateHtml = ' transform="rotate('+this.alpha+','+this.x1+','+this.y1+')"'
        if(this.text!=""){
            let colRGB = {
                red: 155*(this.fontSize-minFontSize)/(maxFontSize-minFontSize),
                green: 0,
                blue: 155*(maxFontSize-this.fontSize)/(maxFontSize-minFontSize)
            };
            let rectsHtml = showRectangles ? '<rect' + rectCoordsHtml + style + '/>' : "";
            let textCoordsHtml = ' x="'+this.x1+'" y="'+(this.y1+2/3*this.h)+'"';
            toRet = '<g' + rotateHtml + '>' +
            rectsHtml +
            '<text' + textCoordsHtml + ' font-family="Verdana" fill="RGB('+colRGB.red+','+colRGB.green+','+colRGB.blue+')" font-size="'+this.fontSize+'">' + this.text + '</text>' +
            '</g>'
        } else{
            toRet = '<rect' + rectCoordsHtml + rotateHtml + style + '/>';
        }
        return toRet;
    }

}


function rotate(rect, angle, x0, y0){
    let alpha1 = rect.alpha+angle;
    let angleRad = angle*Math.PI/180;
    let x1Temp = rect.x1-x0;
    let y1Temp= rect.y1-y0;
    let x11 = Math.cos(angleRad)*x1Temp - Math.sin(angleRad)*y1Temp + x0;
    let y11 = Math.sin(angleRad)*x1Temp + Math.cos(angleRad)*y1Temp + y0;
    return new Rect(rect.w, rect.h, x11, y11, alpha1, rect.text, rect.fontSize);
}

function rotoTranslate(rect, angle, x0, y0){
    let alpha1 = rect.alpha+angle;
    let angleRad = angle*Math.PI/180;
    let x1Temp = rect.x1-x0;
    let y1Temp= rect.y1-y0;
    let x11 = Math.cos(angleRad)*x1Temp - Math.sin(angleRad)*y1Temp;
    let y11 = Math.sin(angleRad)*x1Temp + Math.cos(angleRad)*y1Temp;
    return new Rect(rect.w, rect.h, x11, y11, alpha1);
}

function checkColl(r1, r2){

    // 1. Check bounding box collision:
    if( r1.minX>r2.maxX || r1.maxX<r2.minX || r1.minY>r2.maxY || r1.maxY<r2.minY ) return false;

    let newR1 = rotoTranslate(r1, -r2.alpha, r2.x1, r2.y1);
    if( newR1.minX>r2.w || newR1.maxX<0 || newR1.minY>r2.h || newR1.maxY<0 ) return false;

    let newR2 = rotoTranslate(r2, -r1.alpha, r1.x1, r1.y1);
    if( newR2.minX>r1.w || newR2.maxX<0 || newR2.minY>r1.h || newR2.maxY<0 ) return false;

    // A Rectangle has a parametric description through s and t:
    // (x1, y1) + t*(cAlpha, sAlpha ) + s*(-sAlpha, cAlphs)
    // 0 <= t <= w, 0 <= s <= h.
    //
    // Start by limiting s through t range check

    return true;
}
