//=============================================================================
//
// rampObject.js   | Object which displays and manages ramping data 
//                       on ArtCAM toolpaths
//
// ----------------------------------------------------------------------------
// COPYRIGHT 2004 DELCAM PLC., BIRMINGHAM, ENGLAND. 
// ----------------------------------------------------------------------------
//
// History.
// Who When     What   
// --- -------- ---------------------------------------------------------------
// sap 02/05/01 Created based on original materialObject.js
// pah 02/04/04 Default ramp values in registry
// pah 29/11/06 AddRampsToToolpath() has argument for non zig-zag ramping
//-----------------------------------------------------------------------------



//=== Ramp Constructor ==============================================
//
// History
// Who When     What
// --- -------- ---------------------------------------------------------
// sap 02/05/01 Written
// bem 21/05/01 Added save/ load settings from toolpath
//-----------------------------------------------------------------------------

function Ramp
   (
   name,
   changed_callback 
   )
{
   // Assign Page Members
   this.name = name;

   this.max_zig_len = 10.0; 
   this.min_zig_len = 0.0; 
   this.zig_angle = 10.0; 
   this.start_height = 0.0; 
   this.use_start_height = false; 
   this.use_ramping = false;

   // Assign Functions
   this.writeDiv              = Ramp_WriteDiv;
   this.initialise            = Ramp_Initialise;
   this.onRampingOnOff        = Ramp_OnOff;
   this.toggleHelp            = Ramp_ToggleHelp;
   this.onUseStartHeightClick = Ramp_OnUseStartHeightClick;
   this.GetData               = Ramp_GetRampData;
   this.Apply                 = Ramp_OnApply;

   this.onUseRampAngleClick   = Ramp_onUseRampAngleClick;


   this.updateParametersFromToolpath = Ramp_UpdateParametersFromToolpath;
   this.saveParametersToToolpath     = Ramp_SaveParametersToToolpath;

   // is there a callback ?
   if (changed_callback == null)
   {
      this.doCallback = false;
   }
   else
   {
      this.updateCallback = changed_callback
      this.doCallback = true;
   }

   // get path to the root of our html - we use this to build
   // addresses to our images
   this.image_dir = artcam.HtmlRootDir();
   this.image_dir += "..\\SharedImages\\Ramp\\";

}

//=== Ramp_WriteDiv ==============================================
//
// Writes out the html which is the interface for the ramping process into any toolpath dialog
//
// History
// Who When     What
// --- -------- ---------------------------------------------------------
// sap 02/05/01 Written
// dmr 11/09/07 Changes for licensing options
//-----------------------------------------------------------------------------

function Ramp_WriteDiv()
{
   // This is a bit like create. We write all our document objects into the page
   // then show and hide them as we wish.

   document.writeln("<tr featureType='FT_2DMACH_RAMPS'>");
   document.writeln("<td valign=top><img src='" + this.image_dir + "/ramp.gif' align=top></td>");  
   document.writeln("<td>");
   
   document.writeln("<table cellspacing=0 border=0 width=100%>");
   document.writeln("<tr><td height=2px></td></tr>");
   document.writeln("<tr><td bgcolor=buttonshadow></td></tr>");
   document.writeln("<tr><td bgcolor=buttonhighlight></td></tr>");
   document.writeln("<tr><td height=2px></td></tr>");

   // this is the not ramping div
   document.writeln("<tr><td>");
   document.writeln("   <INPUT type='checkbox' id='" + this.name + "do_rampingCheck' onClick='" + this.name + ".onRampingOnOff()' name=start_check>");
   document.writeln("   <nobr><span><b>" + gsrAddRampingMovesText + "&nbsp;&nbsp;</b></span>");
   document.writeln("   </nobr>");

   // this is the main editing div
   document.writeln("<table border=0 id='" + this.name + "MainDiv' style='display:none'>");
   document.writeln("<tr>");
   document.writeln("   <td valign=left><IMG src='" + this.image_dir + "/max_ramp_ang.gif'></td>");  
   document.writeln("   <td><b>" + gsrMaxRampAngleText + "&nbsp;&nbsp;(A):</b></td>");
   document.writeln("   <td><INPUT type='checkbox' id='" + this.name + "ramp_angleCheck' onclick='javascript:CheckEditClick(" + this.name + "ramp_angleCheck," + this.name + "zig_angleEdit);' name=start_check checked>");
   document.writeln("       <input id='" + this.name + "zig_angleEdit' size=5 maxLength=6 value='10' number>&deg;</td></tr>");
   document.writeln("<tr>");
   document.writeln("   <td valign=left><IMG src='" + this.image_dir + "/max_ramp_lengh.gif'></td>");  
   document.writeln("   <td><b>" + gsrMaxRampLengthText + "&nbsp;(L)</b></td>");
   document.writeln("   <td><INPUT type='checkbox' id='" + this.name + "ramp_lengthCheck' onclick='javascript:CheckEditClick(" + this.name + "ramp_lengthCheck," + this.name + "zig_lengthEdit);' name=start_check checked>");
   document.writeln("       <input id='" + this.name + "zig_lengthEdit' size=5 maxLength=6 value='20' positive dp='2' number>");
   document.writeln("   <span units></span>");
   document.writeln("  </td>");
   document.writeln("</tr>");
   document.writeln("<tr>");
   document.writeln("   <td valign=left><IMG src='" + this.image_dir + "/max_ramp_lengh.gif'></td>");  
   document.writeln("   <td><b>" + gsrMinRampLengthText + "&nbsp;(Lmin)</b></td>");
   document.writeln("   <td><INPUT type='checkbox' id='" + this.name + "min_lengthCheck' onclick='javascript:CheckEditClick(" + this.name + "min_lengthCheck," + this.name + "zig_min_lengthEdit);' name=start_check checked>");
   document.writeln("      <input id='" + this.name + "zig_min_lengthEdit' size=5 maxLength=6 value='20' positive dp='2' number>");
   document.writeln("   <span units></span>");
   document.writeln("  </td>");
   document.writeln("</tr>");
   document.writeln("<tr>");
   document.writeln("   <td valign=left><IMG src='" + this.image_dir + "/ramp_start_height.gif'></td>");  
   document.writeln("   <td><b>" + gsrRampStartHeightText + "&nbsp;(S)</b></td>");
   document.writeln("   <td><INPUT type='checkbox' id='" + this.name + "start_heightCheck' onclick='javascript:" + this.name + ".onUseStartHeightClick()' name=start_check checked>");
   document.writeln("       <input id='" + this.name + "start_heightEdit' size=5 maxLength=6 value='1' dp='2' number>");
   document.writeln("   <span units></span>");
   document.writeln("  </td>");
   document.writeln("</tr>");
   document.writeln("</table>");
   
   // this is the terse div as yet unused
   document.writeln("<table id='" + this.name + "TerseDiv'>");
   document.writeln("</table>");
   document.writeln("</td>");

   document.writeln("<tr HELPTAG style='display:none'>");
   document.writeln("   <td colspan=1>");
   document.writeln("      <div id='div" + this.name + "Help'>");
   document.writeln("      <p>" + gsrRampHelpText);
   document.writeln("      <BR><BR>");
   document.writeln("      </div>");
   document.writeln("   </td>");
   document.writeln("</tr>");
   document.writeln("</td></tr></table>");

   document.writeln("</td>");
   document.writeln("</tr>");
}


//=============================================================================
//
// Get default value from registry
//
// History
// Who When     What
// --- -------- ---------------------------------------------------------------
// pah 02/04/04 Written
//-----------------------------------------------------------------------------
function Ramp_GetDefault( name, default_mm )
{
   var def = artcam.RetrieveDouble("Defaults", name, default_mm );

   // Ramp defaults are stored in mm
   if ( !artcam.InMM ) 
      def = def/25;

   return def;
}


//=============================================================================
//
// Set default value in registry
//
// History
// Who When     What
// --- -------- ---------------------------------------------------------------
// pah 02/04/04 Written
//-----------------------------------------------------------------------------
function Ramp_SetDefault( name, value )
{
   // Ramp defaults are stored in mm
   if ( !artcam.InMM ) 
      value = value*25;   
   
   artcam.StoreDouble("Defaults", name, value );
}


//=== Ramp_Initialise ==============================================
//
// History
// Who When     What
// --- -------- ---------------------------------------------------------
// sap 02/05/01 Written
// pah 02/04/04 Load defaults from registry
// pah 04/05/06 Dont scale angle
//-----------------------------------------------------------------------------

function Ramp_Initialise()
{
   // Load defaults from registry
   this.max_zig_len = Ramp_GetDefault("MaxZigLen", 10.0 ); 
   this.min_zig_len = Ramp_GetDefault("MinZigLen", 0.0 ); 
   this.zig_angle   = artcam.RetrieveDouble("Defaults", "ZigAngle", 10.0 ); 


   // Create members attached to the objects in our Div on the page.
   // This is done by evaluating the name that we called it when we wrote it in writeDiv
   // Since the object has this global name the evaluation returns the object
   // which we store in our object for convenience.
   // A bit like do data exchange in CDialog!

   // link up the divs that display the data etc
   this.mainDiv          = eval( this.name + "MainDiv" ); 
   this.terseDiv         = eval( this.name + "TerseDiv" );
   
   // Set up members for the data controls
   this.use_rampingCheck      = eval( this.name + "do_rampingCheck" );
   this.zig_angleEdit         = eval( this.name + "zig_angleEdit" );
   this.max_zig_lenEdit       = eval( this.name + "zig_lengthEdit" );
   this.min_zig_lenEdit       = eval( this.name + "zig_min_lengthEdit" );
   this.use_start_heightCheck = eval( this.name + "start_heightCheck" );
   this.start_heightEdit      = eval( this.name + "start_heightEdit" );
   
   this.use_ramp_angleCheck   = eval( this.name + "ramp_angleCheck" );
   this.use_ramp_lengthCheck  = eval( this.name + "ramp_lengthCheck" );
   this.use_min_lengthCheck   = eval( this.name + "min_lengthCheck" );

   // work out which ones are to be displayed and which hidden
   this.mainDiv.style.display  = "none";
   this.terseDiv.style.display = "none";

   this.rampHelpDiv   = eval( "div" + this.name + "Help" ); 

   this.onUseStartHeightClick();
   this.onUseRampAngleClick();

   // Assign values to controls
   this.max_zig_lenEdit.value = this.max_zig_len;
   this.min_zig_lenEdit.value = this.min_zig_len;
   this.zig_angleEdit.value = this.zig_angle;

   // sap 18/07/02 put the start height just above the material height by default
   // make the ramp start height 1mm (or inch eqivalent above start Z)
   var surface_z = artcam.MaterialMaxZ;
   if ( artcam.InMM() )
      surface_z += 1;
   else
      surface_z += 0.04;

   // Read default start height from registry
   var reg_height = Ramp_GetDefault("StartHeight", -9999 ); 
   if (reg_height > surface_z)
      surface_z = reg_height;          // Use biggest of default or material

   // Set start height control
   this.start_heightEdit.value = surface_z;
} 


//=== Ramp_OnOff ==============================================
//
// History
// DICC  Who When     What
// ----- --- -------- ---------------------------------------------------------
// 00000 sap 03/05/01 Written
//-----------------------------------------------------------------------------

function Ramp_OnOff()
{
   // work out which ones are to be displayed and which hidden
   if ( this.use_rampingCheck.checked == true )
   {
      this.mainDiv.style.display  = "";
      this.terseDiv.style.display = "none";
   }
   else
   {
      this.mainDiv.style.display  = "none";
      this.terseDiv.style.display = "none";
   }
}


// === Ramp_UpdateParametersFromToolpath ===================================
//
// Update ramp parameters from passed toolpath
//
// History
// Who When       What
// --- ---------- ---------------------------------------------------------
// bem 21/05/2001 Written
// sap 18/06/03   add stuff for new show hide flags
// ----------------------------------------------------------------------

function Ramp_UpdateParametersFromToolpath(toolpath)
{
   if (toolpath == null)
      return;
       
   this.use_rampingCheck.checked    = toolpath.GetFlag('DoRamping',this.use_rampingCheck.checked);

   this.max_zig_lenEdit.value  = toolpath.GetDouble('RampMaxZigLength',parseFloat(this.max_zig_lenEdit.value)); 
   this.min_zig_lenEdit.value  = toolpath.GetDouble('RampMinZigLength',parseFloat(this.min_zig_lenEdit.value)); 
   this.zig_angleEdit.value    = toolpath.GetDouble('RampZigAngle',    parseFloat(this.zig_angleEdit.value)); 

   this.use_start_heightCheck.checked = toolpath.GetFlag('RampUseStartHeight',this.use_start_heightCheck.checked); 
   this.start_heightEdit.value        = toolpath.GetDouble('RampStartHeight', parseFloat(this.start_heightEdit.value));; 

   this.use_ramp_angleCheck.checked  = toolpath.GetFlag('RampUseramp_angle',this.use_ramp_angleCheck.checked); 
   this.use_ramp_lengthCheck.checked = toolpath.GetFlag('RampUseramp_length',this.use_ramp_lengthCheck.checked); 
   this.use_min_lengthCheck.checked  = toolpath.GetFlag('RampUsemin_length',this.use_min_lengthCheck.checked); 

   // work out which ones are to be displayed and which hidden
   if (this.use_rampingCheck.checked)
      {
      this.mainDiv.style.display  = "";
      this.terseDiv.style.display = "none";
      }
   else
      {
      this.mainDiv.style.display  = "none";
      this.terseDiv.style.display = "none";
      }

   this.onUseStartHeightClick();
   this.onUseRampAngleClick();

   CheckEditClick(this.use_ramp_angleCheck,this.zig_angleEdit);
   CheckEditClick(this.use_ramp_lengthCheck,this.max_zig_lenEdit);
   CheckEditClick(this.use_min_lengthCheck,this.min_zig_lenEdit);
}

// === Ramp_SaveParametersToToolpath ===================================
//
// Save ramp parameters to passed toolpath
//
// History
// Who When     What
// --- -------- ---------------------------------------------------------
// bem 21/05/01 Written
// sap 18/06/03 add stuff for new show hide flags
// pah 02/04/04 Save defaults to registry
// pah 04/05/06 Dont scale angle
// ----------------------------------------------------------------------

function Ramp_SaveParametersToToolpath(toolpath)
{
   if (toolpath == null)
      return;
       
   toolpath.SetFlag('DoRamping',this.use_rampingCheck.checked);

   this.max_zig_len = parseFloat(this.max_zig_lenEdit.value);
   this.min_zig_len = parseFloat(this.min_zig_lenEdit.value);
   this.zig_angle   = parseFloat(this.zig_angleEdit.value);
   this.start_height = parseFloat(this.start_heightEdit.value);

   toolpath.SetDouble('RampMaxZigLength', this.max_zig_len ); 
   toolpath.SetDouble('RampMinZigLength', this.min_zig_len ); 
   toolpath.SetDouble('RampZigAngle',     this.zig_angle ); 

   toolpath.SetFlag('RampUseStartHeight', this.use_start_heightCheck.checked); 
   toolpath.SetDouble('RampStartHeight', this.start_height ); 

   toolpath.SetFlag('RampUseramp_angle',this.use_ramp_angleCheck.checked); 
   toolpath.SetFlag('RampUseramp_length',this.use_ramp_lengthCheck.checked); 
   toolpath.SetFlag('RampUsemin_length',this.use_min_lengthCheck.checked); 

   // Also set defaults in registry
   Ramp_SetDefault("MaxZigLen", this.max_zig_len ); 
   Ramp_SetDefault("MinZigLen", this.min_zig_len ); 
   this.zig_angle = artcam.StoreDouble("Defaults", "ZigAngle", this.zig_angle );
   Ramp_SetDefault("StartHeight", this.start_height );
}


// === Ramp_ToggleHelp =======================================
//
// Toggle display of our help
//

function Ramp_ToggleHelp()
{
ToggleVisibility(this.rampHelpDiv);
}


// === Ramp_onUseRampAngleClick =======================================
//
// Called when user toggles use of ramp angle for ramping
//
function Ramp_onUseRampAngleClick()
{
var disable_editing = true;
if (this.use_ramp_angleCheck.checked)
   disable_editing = false;

// this.start_heightLabel.style.color= disable_editing ? 'graytext' : 'windowtext';

this.zig_angleEdit.disabled = disable_editing;
this.zig_angleEdit.readOnly = disable_editing;  
this.zig_angleEdit.style.backgroundColor= disable_editing ? 'buttonface' : 'window';

}

// === CheckEditClick =======================================
//
// Called when user toggles use of ramp angle for ramping
//
function CheckEditClick( check, edit )
{
var disable_editing = true;
if (check.checked)
   disable_editing = false;

// this.start_heightLabel.style.color= disable_editing ? 'graytext' : 'windowtext';

edit.disabled = disable_editing;
edit.readOnly = disable_editing; 
edit.style.backgroundColor= disable_editing ? 'buttonface' : 'window';

}

// === Ramp_OnUseStartHeightClick =======================================
//
// Called when user toggles use of start height for ramping
//
function Ramp_OnUseStartHeightClick()
{

var disable_editing = true;
if (this.use_start_heightCheck.checked)
   disable_editing = false;

// this.start_heightLabel.style.color= disable_editing ? 'graytext' : 'windowtext';

this.start_heightEdit.disabled = disable_editing;
this.start_heightEdit.readOnly = disable_editing;  
this.start_heightEdit.style.backgroundColor= disable_editing ? 'buttonface' : 'window';

}

function Ramp_GetRampData(start_depth)
{
if ( gRampdo_rampingCheck.checked == false )
   {
   return "";
   }
var zig_ang = parseFloat(this.zig_angleEdit.value);
var max_zig_len = parseFloat(this.max_zig_lenEdit.value);
var min_zig_len = parseFloat(this.min_zig_lenEdit.value);
var use_start_height = this.use_start_heightCheck.checked;
var start_z = start_depth + parseFloat(this.start_heightEdit.value);
  
// convert zig_angle to radians
var zig_rad = ( zig_ang * ( 2* Math.PI )) / 360;
// convert zig_len to a distance along the ramp rather than along the block
max_zig_len = max_zig_len / Math.cos( zig_rad );
min_zig_len = min_zig_len / Math.cos( zig_rad );
  
// create the string that we pass back to artcam as the data
var data_array = new Array();

data_array[0] = max_zig_len;
data_array[1] = min_zig_len;
data_array[2] = zig_rad;
data_array[3] = use_start_height;
data_array[4] = start_z;
  
return data_array.toString();
}


//=== Ramp_OnApply ============================================================
//
// History
// Who When     What
// --- -------- ---------------------------------------------------------------
// sap 05/02/02 Written
// pah 27/11/06 Added zig but no zag option
// pah 24/10/07 Added zero length error message
//-----------------------------------------------------------------------------
function Ramp_OnApply( toolpathID, max_cut_depth, start_depth )
{

if ( !this.use_rampingCheck.checked )
   return;


var toolpath = artcam.Machining.GetToolpathData( toolpathID );

var zig_ang = -1.0;
var max_zig_len = -1.0;
var min_zig_len = -1.0;
var use_start_height = false;
var start_z = 1.0;

if ( this.use_ramp_angleCheck.checked )
   zig_ang = parseFloat(this.zig_angleEdit.value);

if ( this.use_ramp_lengthCheck.checked )
   max_zig_len = parseFloat(this.max_zig_lenEdit.value);

if ( this.use_min_lengthCheck.checked )
   min_zig_len = parseFloat(this.min_zig_lenEdit.value);

use_start_height = this.use_start_heightCheck.checked;
start_z = start_depth + parseFloat(this.start_heightEdit.value);

var first_drop = toolpath.SafeZ - toolpath.StartZ;

var ramp_start_z = start_depth;
if ( use_start_height )
   {
   ramp_start_z = start_z;
   first_drop = start_z - toolpath.StartZ;
   }

var total_ramp_distance = max_cut_depth + first_drop;

if ( zig_ang < 0.0 && max_zig_len < 0.0 && min_zig_len < 0.0 )
   {
   artcam.MessageBox(gNotEnoughDatatoProceed);
   return;
   }

if ( zig_ang < 0.0 && max_zig_len < 0.0 )
   {
   max_zig_len = min_zig_len;
   }

if ( zig_ang < 0.0 ) 
   {
   var zig_rad = Math.atan2( max_zig_len, total_ramp_distance / 2.0 );
   zig_ang = ( zig_rad * 360 ) / ( 2* Math.PI );
   }

if ( max_zig_len < 0.0 ) 
   {
   var zig_rad = ( zig_ang * ( 2* Math.PI )) / 360;
   max_zig_len = Math.abs((total_ramp_distance / 2.0 ) / Math.tan( zig_rad ));
   }

if ( min_zig_len < 0.0 )
   {
   min_zig_len = 0.0;
   }
   
if (max_zig_len == 0) {
   artcam.MessageBox(gsrMaxLengthZeroError);
   return;
}

var do_zig_zag = true;

artcam.Machining.AddRampsToToolpath( 
                                   toolpathID,
                                   max_zig_len,
                                   min_zig_len,
                                   zig_ang,
                                   use_start_height,
                                   start_z,
                                   do_zig_zag
                                   );

}