include <BOSL2/std.scad>
include <BOSL2/beziers.scad>
include <Round-Anything/polyround.scad>


$fn=64;

OFFSET=0.01;

PIN_DIAMETER=4.76;              // 3/16 inch
PIN_LENGTH = PIN_DIAMETER * 3;  // 9/16inch



/**
 * US Box profile
 
 * @param length - Length of the fin without the tab and back space
 *
 **/
module boxProfileUS( length ,height=23, tabHeight = 8,tabLength = 20, backRounding = 8, backExtra = 10 ) {

    assert (height-tabHeight,"height-tabHeight should be bigger than 0");
   
    tabExtra = opp_ang_to_adj(height-tabHeight,45);
    points = [
        [ -tabLength                    , 0             ,1],            // 0
        [ length+backExtra              , 0             ,2],            // 1
        [ length+backExtra              , -height       ,backRounding], // 2
        [ tabExtra                      , -height       ,4],            // 3
        [ 0                             , -tabHeight    ,4],            // 4
        [ -tabLength                    , -tabHeight    ,1]             // 5
    ];
    polygon(
        polyRound(points)
    );
}    

function profileUS( length,height=23,tabHeight = 8,tabLength = 20, backRounding = 8, backExtra = 10 ) = polyRound([
        [ -tabLength                    , 0             ,1],            // 0
        [ length+backExtra              , 0             ,2],            // 1
        [ length+backExtra              , -height       ,backRounding], // 2
        [ opp_ang_to_adj(height-tabHeight,45) , -height ,4],            // 3
        [ 0                             , -tabHeight    ,4],            // 4
        [ -tabLength                    , -tabHeight    ,1]             // 5
    ]);

/**
 * US Box 
 *
 * @param length : Length of the fin base. backExtra and tabLength will be added to have the full length
 *
 */
module usBox( length, height=23, thickness = 9, tabLength = 20,pinDiameter = 5,pinInset = 8, backExtra = 10,cutReduction = 0.5,screw_diameter=4.5,drill = true, color="Grey", showPin = false ) {
    color(color) mirror_copy([0,0,1], offset=-OFFSET) 
    difference() {
        linear_extrude ( height = thickness/2 ) color(color) boxProfileUS( length, tabLength = tabLength, height=height, backExtra=backExtra );
        // Thickness cut
        translate([length + backExtra + OFFSET,-OFFSET,thickness/2-cutReduction+OFFSET])
            thickness_cut( cutReduction , height );
        // Pin drill
        if ( drill ) 
            translate([length+backExtra-pinInset,-height+pinInset,0])  
                color("Red")
                    cyl(h=thickness*2,d=pinDiameter,$fn=32);
            
        // Screw Cut
        if ( drill ) 
            translate ([-tabLength/2,-height/2+OFFSET,0]) 
                color ("Red") cyl( h=height, d=screw_diameter, orient=FRONT );    
    }
    if (showPin)
        translate([length+backExtra-pinInset,-height+pinInset,0])
            cyl (h=PIN_LENGTH,d=PIN_DIAMETER);
    
}


module usBoxMold( length, height=23, thickness = 9, moldThickness = 4,tabLength = 20,part = "bottom",skirtAngle=80 , skirt = true ) {

//assert(length == 130,"Not 130");
    assert (length >0,"length should be bigger than 0");

    moldHeight = thickness + 2 * moldThickness;
    
    
    skirtHeight = 3 * thickness;
    deviation = opp_ang_to_adj (skirtHeight,skirtAngle);    // Skirt devitation
    
    baseInt = profileUS (length);
    baseExt = offset(baseInt,delta=moldThickness            , chamfer=false, same_length=true );   
    topInt  = offset(baseInt,delta=deviation                , chamfer=false, same_length=true );    
    topExt  = offset(baseInt,delta=deviation+moldThickness  , chamfer=false, same_length=true );
    
    if ( part == "bottom") {
        union() {
            difference() {
                // Mold
                down (moldHeight/2) 
                    linear_extrude(moldHeight)    
                        offset(r= (part=="top" ? 0 :  moldThickness)) 
                            boxProfileUS( length, height );
                
                usBox(length,height,drill=false,color="Red");

                // Mask Top  
                verticalMask = 
                    part == "bottom" ? 0 : 
                    part == "top"    ? moldHeight : 
                    100;        
                debug = false    ;
                    
                if (!debug) 
                    down( verticalMask )
                    linear_extrude( moldHeight )    
                        offset( r = moldThickness*2 ) 
                            boxProfileUS( length, height );                    
                            
            }
            //topInt  = offset(baseInt,delta=deviation,chamfer=false,same_length=true);
            if (skirt) difference(){
                skin([baseExt,topExt],z=[0,skirtHeight],slices=0);
                skin([baseInt,topInt],z=[0,skirtHeight+OFFSET],slices=0);
            }
        }  
    }   
   
    if ( part == "top") { 
        difference() {
            // Top Mold
            linear_extrude(  thickness/2+OFFSET+moldThickness /*moldHeight/2*/ )    
                offset(r=-OFFSET)
                    boxProfileUS( length, height );
            // Box to subtract            
            usBox(length,height,drill=false,color="Red");
            
        }                    
    }
    
}


module finBoxMold( length, finLength=-1, skirtAngle = 80, part="bottom", skirt = true) {

    assert (finLength,"Missing 'finLength' parameter in finBoxMold module");
    //if (part=="bottom") {
    usBoxMold( length,part=part,skirtAngle=skirtAngle,skirt=skirt );
    //}
    
}

module thickness_cut(thickness,height) {
    color("Orange")
    linear_extrude(thickness) 
        polygon([
           [0           , 0         ],
           [0           , -height   ],
           [-height*2   , -height   ] 
        ]);
}



//usBoxMold (130,part="bottom",skirt=false);

//back (30) usBoxMold (130,part="top",skirt=false);


// US Box

//usBox(130,height=23,drill=true,color="White",showPin=false);

//down(0) back(0) usBox(130,height=23,drill=false,color="Green");


 if ( false ) {
    // Bottom
   down(0) back(0) usBoxMold( 130 ,part="bottom"  ,skirt=false );
   // Top
   down(-50) back(0) usBoxMold( 130  ,part="top"     ,skirt=false );

   down(50) back(0) usBoxMold( 130  ,part="bottom"     ,skirt=true );
   
   
   //down(0) back(0) usBox(130,height=23,drill=false,color="Green");
}