function plugin_main()
{
   HideAllLibraryDivs();

   paramsDiv.style.display = "";

   // Create the parameters in paramsDiv (this must exist)
   Plain_write_paramsDiv();

   // Initialise any button classes we have just created
   InitialiseButtonDivs();

   globalStore.OnCopyRotate = OnCopyRotate;

   RetrievePageSettings();

   if (artcam.DisplayHelp)
      ToggleHelp();
}

function Plain_write_paramsDiv()
{
   // Empty any existing content
   paramsDiv.innerHTML = "";

   // Create an array to hold the HTML
   var hArr = new Array();

   hArr.push("<table id=copyDiv border=0 cellspacing=0 cellpadding=0 style='table-layout:fixed'>");
   hArr.push("<tr HELPTAG style='DISPLAY:none'>");
   hArr.push("   <td colspan=4>");
   hArr.push("      <img src='../SharedImages/help.gif'>" + gCopyRotateHelp);
   hArr.push("      <br><br>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=4>");
   hArr.push("      <b>"+ gTransformRelativeTo + ":</b><br>");
   hArr.push("      <nobr>");
   hArr.push("         <input type=radio id='TxOriginRadio0' name='TxOriginRadio' checked><label for='TxOriginRadio0'>"+ gWorldOrigin +"</label><br>");
   hArr.push("         <input type=radio id='TxOriginRadio1' name='TxOriginRadio'><label for='TxOriginRadio1'>"+ gObjectOrigin + "</label>");
   hArr.push("      </nobr>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=4>");
   hArr.push("      <br>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=4>");
   hArr.push("   <b>"+ gRotationAxis + ":</b><br>");
   hArr.push("      <nobr>");
   hArr.push("         <input type=radio id='RotationAxisRadio0' name='RotationAxisRadio' checked><label for='RotationAxisRadio0'><b><font color = 'red'>X</font></b></label><br>");
   hArr.push("         <input type=radio id='RotationAxisRadio1' name='RotationAxisRadio'><label for='RotationAxisRadio1'><b><font color = 'green'>Y</font></b></label><br>");
   hArr.push("         <input type=radio id='RotationAxisRadio2' name='RotationAxisRadio'><label for='RotationAxisRadio2'><b><font color = 'blue'>Z</font></b></label><br>");
   hArr.push("      </nobr>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr HELPTAG style='DISPLAY:none'>");
   hArr.push("   <td colspan=4>");
   hArr.push(       gRotationAxisHelp);
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=4>");
   hArr.push("      <br>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td valign='top'>");
   hArr.push("      <b>"+gAngle+": </b>");
   hArr.push("   </td>");
   hArr.push("   <td colspan=3>");
   hArr.push("      <nobr>");
   hArr.push("         <input type=radio id='IncrementOrTotalRadio0' name='IncrementOrTotalRadio' checked><label for='IncrementOrTotalRadio0'>"+gIncrement+"</label><br>");
   hArr.push("         <input type=radio id='IncrementOrTotalRadio1' name='IncrementOrTotalRadio'><label for='IncrementOrTotalRadio1'>"+gTotal+"</label><br>");
   hArr.push("      </nobr>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td>");
   hArr.push("      &nbsp");
   hArr.push("   </td>");
   hArr.push("   <td colspan=3>");
   hArr.push("      <input id='AngleOfRotation' align=right size=4 maxLength=6 value='45' number dp='4'> <label for='AngleOfRotation'>"+gDegrees+"</label>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr HELPTAG style='DISPLAY:none'>");
   hArr.push("   <td colspan=4>");
   hArr.push(       gAngleHelp);
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=4>");
   hArr.push("      <br>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=2>");
   hArr.push("      <label for='NumCopies'><b>"+gNumCopies+"</b></label>");
   hArr.push("   </td>");
   hArr.push("   <td colspan=2>");
   hArr.push("      <input id='NumCopies' size=4 maxLength=6 value='4' number dp='0'>");
   hArr.push("      <br>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr HELPTAG style='DISPLAY:none'>");
   hArr.push("   <td colspan=4>");
   hArr.push(       gNumCopiesHelp);
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=4>");
   hArr.push("      <br>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr>");
   hArr.push("   <td colspan=4>");
   if (artcam.SelectedAssembly.GetObjectAddress() == artcam.ProjectAssembly.GetObjectAddress)
   {
      hArr.push("    <input type=checkbox id='NestCheckbox' disabled=true><label for='NestCheckbox' disabled=true><b>"+gNest+"<b></label>");
   }
   else
   {
      hArr.push("    <input type=checkbox id='NestCheckbox'><label for='NestCheckbox'><b>"+gNest+"<b></label>");
   }
   hArr.push("      <br>");
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("<tr HELPTAG style='DISPLAY:none'>");
   hArr.push("   <td colspan=4>");
   hArr.push(       gNestHelp);
   hArr.push("   </td>");
   hArr.push("</tr>");
   hArr.push("</table>");

   hArr.push("<br>");

   // Add the forward button HTML to the array
   hArr.push("<div class='mouseOut' button_name='forward_button' id=ForwardButton targetFunction='globalStore.OnCopyRotate' style='width=30px;float:right;'>");
   hArr.push("<img alt=" + gAcceptButtonAlt + " id=back_img src ='" + artcam.HtmlRootDir + "../SharedImages/accept.gif' align=absmiddle border=0 width=30 height=30>");
   hArr.push("</div>");

   // Add the back button HTML to the array
   AddBackButtonHTML(hArr);

   // Bung all our HTML into the div and display it
   paramsDiv.innerHTML = hArr.join("\n");
   SubclassNumberEditControls();
   paramsDiv.style.display = "";
}

//only works for assemblies
function OnCopyRotate()
{
   var selected_component = artcam.SelectedAssembly;
   if (selected_component == null)
   {
      artcam.Alert("No selected assembly",0);
      return;
   }

   var parent_assembly = selected_component.GetParent();
   var whole_project_selected = false;
   if (parent_assembly == null)
   {
      //the selection was the 3DP
      whole_project_selected = true;
      parent_assembly = artcam.ProjectAssembly;
   }

   var assembly_name = selected_component.Name;

   //get input values into local variables
   var compCentreChecked = TxOriginRadio[1].checked;
   var xAxisChecked = RotationAxisRadio[0].checked;
   var yAxisChecked = RotationAxisRadio[1].checked;
   var zAxisChecked = RotationAxisRadio[2].checked;
   var numOfCopies = NumCopies.getValue();
   var totalAngleSelected = IncrementOrTotalRadio[1].checked;
   var nestChecked = NestCheckbox.checked;
   var angle = AngleOfRotation.getValue();

   if (numOfCopies < 1)
   {
      return;
   }

   if (totalAngleSelected)
   {
      if (numOfCopies < 2)
         return;
      else if (Math.abs(angle - 360) < 0.01)
         angle = angle / numOfCopies;
      else
         angle = angle / (numOfCopies - 1);

      numOfCopies--; //include original as one of the copies
   }

   //our new assemblies will sit inside the following assembly
   var container_assembly;
   if (nestChecked || whole_project_selected)
   {
      container_assembly = artcam.CreateAssembly(assembly_name);
      if (container_assembly == null)
      {
         artcam.Alert("artcam.CreateAssembly() - failed",0);
         return;
      }
      container_assembly.InDisplayList = false;
      
      // We need a copy of the original too in this case
      if (CopyAssemblyTo(selected_component, container_assembly) == null)
      {
         return;
      }
   }
   else
   {
      container_assembly = parent_assembly;
   }

   // Create the rotated copies
   for (copyIndex = 0; copyIndex < numOfCopies; copyIndex++)
   {
      var new_assembly = CopyAssemblyTo(selected_component, container_assembly);
      if (new_assembly == null)
         return;

      var x_angle = 0.0;
      var y_angle = 0.0;
      var z_angle = 0.0;

      if(xAxisChecked)
         x_angle += angle * (copyIndex + 1);
      if(yAxisChecked)
         y_angle += angle * (copyIndex + 1);
      if(zAxisChecked)
         z_angle += angle * (copyIndex + 1);

      new_assembly.Transform(0.0,0.0,0.0,                    // trans
                             1.0,1.0,1.0,                    // scale
                             x_angle,y_angle,z_angle,        // rotate
                             0.0,0.0,0.0,                    // about point
                             compCentreChecked,
                             false);
   }

   if (nestChecked || whole_project_selected)
   {
      // Now add it to the tree
      parent_assembly.AppendChild(container_assembly);

      //hide the original selection rather than remove it -  makes it easier to get back to where you started
      if (whole_project_selected)
      {
         // Don't hide the root assembly, instead loop through each of it's children and hide those
         var child_index;
         for (child_index = 0; child_index < selected_component.NumChildren; ++child_index)
         {
            var child = selected_component.GetChildAtIndex(child_index);
            if (child != null && child.GetObjectAddress() != container_assembly.GetObjectAddress())
               child.DrawFlag = false;
         }
         for (child_index = 0; child_index < selected_component.Num3dModels; ++child_index)
         {
            var child = selected_component.Get3dModelAtIndex(child_index);
            if (child != null)
               child.DrawFlag = false;
         }
         for (child_index = 0; child_index < selected_component.NumGemSets; ++child_index)
         {
            var child = selected_component.GetGemSetAtIndex(child_index);
            if (child != null)
               child.DrawFlag = false;
         }      
      }
      else
      {
         selected_component.DrawFlag = false;
      }
   }

   artcam.ProjectAssembly.UpdateAssemblyMonitor();
   artcam.Refresh3dView();
   StorePageSettings();
   OnBackButton();
}


function CopyAssemblyTo(sourceAssembly, destAssemblyParent)
{
   var new_assembly = sourceAssembly.Copy();
   if (new_assembly == null)
   {
      artcam.Alert("artcam.CreateAssembly() - failed",0);
      return null;
   }

   destAssemblyParent.AppendChild(new_assembly)
   new_assembly.InDisplayList = false;

   return new_assembly;
}


function StorePageSettings()
{
   artcam.StoreInt("CopyRotate3DA", "Origin", TxOriginRadio[0].checked ? 0 : 1);

   var i = 0;
   var found = false;
   while (i < RotationAxisRadio.length && !found)
   {
      if (RotationAxisRadio[i].checked)
      {
         artcam.StoreInt("CopyRotate3DA", "RotationAxis", i);
         found = true;
      }
      ++i;
   }

   artcam.StoreInt("CopyRotate3DA", "IncrementOrTotal", IncrementOrTotalRadio[0].checked ? 0 : 1);

   artcam.StoreDouble("CopyRotate3DA", "Angle", AngleOfRotation.getValue());

   artcam.StoreInt("CopyRotate3DA", "NumCopies", NumCopies.getValue());

   artcam.StoreInt("CopyRotate3DA", "Nest", NestCheckbox.checked ? 1 : 0);
}

function RetrievePageSettings()
{
   if (artcam.RetrieveInt("CopyRotate3DA", "Origin", 0) == 0)
      TxOriginRadio[0].checked = true;
   else
      TxOriginRadio[1].checked = true;

   var storedValue = artcam.RetrieveInt("CopyRotate3DA", "RotationAxis", 0);
   RotationAxisRadio[storedValue].checked = true;

   if (artcam.RetrieveInt("CopyRotate3DA", "IncrementOrTotal", 0) == 0)
      IncrementOrTotalRadio[0].checked = true;
   else
      IncrementOrTotalRadio[1].checked = true;

   AngleOfRotation.setValue(artcam.RetrieveDouble("CopyRotate3DA", "Angle", 45));

   NumCopies.setValue(artcam.RetrieveInt("CopyRotate3DA", "NumCopies", 4));

   if (artcam.RetrieveInt("CopyRotate3DA", "Nest", 0) == 0)
      NestCheckbox.checked = false;
   else
      NestCheckbox.checked = true;
}

