home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 January / PCWorld_2007-01_cd.bin / temacd / flstudio / flstudio608_install.exe / Help / FD.chm / html / engine.js < prev    next >
Text File  |  2006-01-06  |  23KB  |  571 lines

  1. // ---------------------------------------------------------------------------------
  2. // UTILS
  3. function includeJS(file) // executes external JS immediately after script tag exit(relative to HTML location)
  4. {
  5.     document.write('<script src="'+file+'"></script>');
  6. }
  7. function innerXML(node) // returns childNodes of XML serialised to a string
  8. {
  9.     var out='';
  10.     node = node.firstChild; 
  11.     if (node) do {
  12.         out+=node.xml+'\n';
  13.     } while (node=node.nextSibling);
  14.     return out;    
  15. }
  16. function escape2(source) // url-friendly escaping
  17. {
  18.     var i,c; 
  19.     var result='';
  20.     for (i=0;i<source.length;i++) {c=source.charAt(i); switch (true) {
  21.              case (c==' '):
  22.                 result+='+'; break;
  23.             case ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='.' || c=='/' || c=='\\'):
  24.                 result+=c; break;
  25.             default:
  26.                 result+='%'+(Number(source.charCodeAt(i)).toString(16)).toUpperCase();
  27.         }    
  28.   }
  29.     return result;
  30. }
  31.  
  32. // ---------------------------------------------------------------------------------
  33. // HELPER SUPPORT/ORDER LINKS GENERATORS
  34. function returnLink(action, productID) // returns link for the product/action specified
  35.     var linkContent='';
  36.     linkContent+='<a href="http://flredirect.e-officedirect.com/flredirect.exe?forumname=flstudio';
  37.     linkContent+='&action='+action;
  38.     linkContent+='&username='+escape2(userData[0]);
  39.     // linkContent+='&applicationID='+escape2(params[2])+'; // appID not needed
  40.     if (action=='buy') linkContent+='&P_code='+productID; // product code only in buy/upgrade links
  41.     linkContent+='" target="_blank" class="link-common">';
  42.     return linkContent;
  43. }
  44. function returnSupportLink() // support request link (reg problems)    
  45.     return returnLink('supportrequest',0);
  46. }
  47. function returnRegisterLink() // code request/register link
  48. {     
  49.     return returnLink('register',0);
  50. }
  51. function returnBuyLink(productID) // product buy/upgrade    
  52.     return returnLink('buy',productID);
  53. }
  54.  
  55. // ---------------------------------------------------------------------------------
  56. // INTERFACE
  57.  
  58. // handles container interface - tabs, toolbar & canvas
  59. container = {
  60.     tabs:[],
  61.     openTabPanel: function ()
  62.     {
  63.         document.write('<div class="tabPanel">');
  64.     },
  65.     closeTabPanel: function ()
  66.     {
  67.         document.write('<div class="decRight"> </div></div>');
  68.     },    
  69.     closeContainer: function ()
  70.     {
  71.         document.write('<div style="background:url(img_fd_panels/tabPanel_bottom_bg.gif); height:32px; position:relative"><div style="position:absolute;left:0;"><img src="img_fd_panels/tabPanel_bottom_left.gif"></div><div style="text-align:right;"><img src="img_fd_panels/tabPanel_bottom_right.gif"></div></div>');
  72.     },
  73.     addTab: function (id,caption) 
  74.     {
  75.         document.write('<div id="'+id+'_tab" myID="'+id+'" class="tabOff"><div id="'+id+'_inner" class="tabInner'+(container.tabs.length==0?"First":"")+'"><span>'+caption+'</span></div></div>');
  76.         var t = document.getElementById(id+'_tab');
  77.         container.tabs[container.tabs.length] = t;
  78.         t.onclick = container.switchToMe;
  79.     },
  80.     switchToMe: function() 
  81.     {
  82.         container.switchToTab(this.myID);
  83.     },
  84.     switchToTab: function (id) 
  85.     {
  86.         for (var i=0; i<container.tabs.length; i++) {
  87.             if (container.tabs[i].myID==id) {
  88.                 container.tabs[i].className = "tabOn";
  89.                 document.getElementById(container.tabs[i].myID+'_host').style.display="block";
  90.             } else {
  91.                 container.tabs[i].className = "tabOff";                
  92.                 document.getElementById(container.tabs[i].myID+'_host').style.display="none";                
  93.             }
  94.         }
  95.     },
  96.     openCanvas: function (id,toolbar) 
  97.     {
  98.         var cont = '';
  99.         cont += '<div id="'+id+'_host" class="showAll" style="display:none">';
  100.         if (!toolbar) {
  101.             cont += '<div class="toolbar" onclick="onkeydown();" onkeydown="container.switchRadio(this.myID)" myID="'+id+'">';
  102.             cont += '<label for="'+id+'_radio1"><input checked="checked" type="radio" id="'+id+'_radio1" name="'+id+'_radiogroup" value="radio" />Show all </label>';
  103.             cont += '<label for="'+id+'_radio2"><input type="radio" id="'+id+'_radio2" name="'+id+'_radiogroup" value="radio" />Show products I own </label>';
  104.             cont += '<label for="'+id+'_radio3"><input type="radio" id="'+id+'_radio3" name="'+id+'_radiogroup" value="radio" />Show products I do not own </label>';            
  105.             cont += '</div>';
  106.         } else cont += '<div class="toolbar">'+toolbar+'</div>';
  107.         cont += '<div class="hostCore"><div class="hostCore2">';
  108.         document.write(cont);
  109.         // ... content here
  110.     },
  111.     closeCanvas: function () 
  112.     {
  113.         document.write('</div></div></div>');
  114.     },
  115.     switchRadio: function (id) 
  116.     {
  117.         var rad1 = document.getElementById(id+'_radio1').checked;
  118.         var rad2 = document.getElementById(id+'_radio2').checked;
  119.         var rad3 = document.getElementById(id+'_radio3').checked;
  120.         switch (true) {
  121.             case rad1:
  122.                 document.getElementById(id+'_host').className = "showAll";
  123.                 break;
  124.             case rad2:
  125.                 document.getElementById(id+'_host').className = "showOwned";            
  126.                 break;
  127.             case rad3:
  128.                 document.getElementById(id+'_host').className = "showNotOwned";            
  129.                 break;
  130.         }
  131.     }
  132. }
  133.  
  134. // the dynamically expandable product panels
  135. panels = {    
  136.     id:0,
  137.     insertPanel: function(title,content,onByDefault,owned) // owned = "na" (state not available) will now show own/not-own notice
  138.     {
  139.         var id = panels.id++;
  140.         id = 'sp'+id;
  141.         var cont = '';
  142.         cont += '<div class="'+(owned?'switchOwned':'switchNotOwned')+'"><div class="switch'+(onByDefault?"On":"Off")+'" id="'+id+'_switch">';
  143.         cont += '<div class="switchHeader" ondblclick="onclick()" onselectstart="return false;" onclick="panels.switchPanel(\''+id+'\')">';
  144.         cont += '<table class="thin"><tr><td class="icon"><img id="'+id+'_icon" src="img_fd_panels/switchPanel_top_'+(!onByDefault?"show":"hide")+'icon.gif"></td><td> '+title+(owned!='na'?(owned?" <div class=\"ownText\">(you own this product)</div>":" <div class=\"notOwnText\">(you do not own this product)</div>"):'')+'</td><td class="cap"><img src="img_fd_panels/switchPanel_top_right.gif"></td></tr></table></div>';
  145.         cont += '<div id="'+id+'_core" class="core">'+content+'</div>';
  146.         cont += '<div class="switchFooter"><table class="thin"><tr><td class="icon"><img src="img_fd_panels/switchPanel_bottom_left.gif"></td><td class="cap"><img src="img_fd_panels/switchPanel_bottom_right.gif"></td></tr></table></div></div></div>';
  147.         document.write(cont);
  148.     },
  149.     switchPanel: function (id) 
  150.     {
  151.         var cN = document.getElementById(id+'_switch').className = ((document.getElementById(id+'_switch').className == 'switchOn')?'switchOff':'switchOn');
  152.         document.getElementById(id+'_icon').src = (cN!="switchOn")?"img_fd_panels/switchPanel_top_showicon.gif":"img_fd_panels/switchPanel_top_hideicon.gif";
  153.     },
  154.     insertProductPanel: function(i,owned) // makes a plugin/add-on dynamic table (based on the data.products index)
  155.     { 
  156.         var contents='';
  157.         if (data.products[i].prodType=='smp') {
  158.             contents+='<img src="img_products/sample_cds/'+data.products[i].code+'.jpg" align="left" style="margin:0 8px 8px 0">';
  159.         } else {
  160.             contents+='<img src="img_products/Register '+data.products[i].name+'.gif" align="left">';
  161.         }
  162.         contents+=data.products[i].description + '<br style="clear:both" />';
  163.         if (owned) {
  164.             contents+='<br><br><del><b>Purchase this product</b></del> <span>You already own this product<span>';
  165.         } else {
  166.             if (data.products[i].prodType=='smp') {
  167.                 contents+='<br><br><b>Download version</b>: click '+returnBuyLink(data.products[i].code)+'here</a> to order a downloadable version today.';
  168.                 contents+='<br><b>CD version</b>: visit <a href="http://www.samplefusion.com" target="_blank">www.SampleFusion.com</a> to order this product on a CD.';            
  169.             } else {
  170.                 contents+='<br><br><b>Purchase this product:</b> click '+returnBuyLink(data.products[i].code)+'here</a> to order today from our online shop.';
  171.             }
  172.         }
  173.         if (data.products[i].name=='SimSynth') {
  174.             panels.insertPanel('SimSynth Live',contents, false, owned);
  175.         } else {
  176.             panels.insertPanel(data.products[i].name,contents, false, owned);
  177.         }            
  178.     },
  179.     insertFLRegsPanel: function(i) // makes a "FL info" dynamic table (based on the data.flRegs index)
  180.     { 
  181.         function onlineOrder(params) // params: isUpgrade, price, code
  182.         {
  183.             contents+='<p><strong>'+(params.isUpgrade?'Upgrade':'Product')+' price: $'+params.price+' USD</strong></p>'+
  184.                                 '<p>'+returnBuyLink(params.code)+'Click here to '+(params.isUpgrade?'upgrade':'order')+'</a></p>';
  185.         }
  186.         function boxedOnlineOrder(params) // params: isUpgrade, boxPrice, onlinePrice, code, noDVD
  187.         {
  188.             contents+='<p><strong>'+(params.isUpgrade?'Upgrade':'Product')+' price (boxed): $'+params.onlinePrice+' USD</strong></p>'+
  189.                                 '<p><strong>'+(params.isUpgrade?'Upgrade':'Product')+' price (online): $'+params.boxPrice+' USD '+(params.noDVD?'(no DVD included)':'')+'</strong></p>'+
  190.                                 '<p>'+returnBuyLink(params.code)+'Click here to '+(params.isUpgrade?'upgrade':'order')+'</a></p>';
  191.         }
  192.     
  193.         // i=-1 - demo; 2, 1, 0, 999 = basic, fruityloops, producer no xxl, producer and xxl
  194.         
  195.         var titleEnd; // modifies the table title
  196.         var contents='<table style="width:expression(document.body.offsetWidth  - 60 + "px");" border="0" cellpadding="5" cellspacing="5">';
  197.         contents+='<tr valign="top">';
  198.         var cellSpan; // how many percent spans each table cell
  199.         if (i==-1) cellSpan='25%';
  200.         if (i==2) cellSpan='33%';
  201.         if (i==1) cellSpan='50%';
  202.         if (i==0) cellSpan='100%';    
  203.         if (i==999) cellSpan='';    
  204.     
  205.         if (i==999) {    // user has registered Producer Edition (no upgrades, or only Lifetime Upd. upgrade for boxed)
  206.             // if the edition is boxed, it means the user can buy Lifetime updates
  207.             if (isBoxed) {
  208.                 document.write('<br><br>'+returnBuyLink(31080)+'You can purchase <span style="font-weight:bold;">Lifetime Free Updates</span> for FL Studio XXL Edition ($29).</a><br><br>');
  209.             } else { // user has all
  210.                 document.write('<br><br>No FL-Studio upgrades are available for your registration.');
  211.             }
  212.         } else { // write the tables..
  213.             if (i==-1) { // demo: buy express
  214.                 titleEnd="purchases";
  215.                 contents+='<td width="'+cellSpan+'" class="fl-tbl">';
  216.                 contents+=data.flRegs[2].description;
  217.                 if (i==-1) {
  218.                     if (isBasic) {
  219.                         contents+='<p><strong>Upgrade price: $39 USD</strong></p>'+
  220.                                             '<p>'+returnBuyLink(31060)+'Click here to order</a></p>';
  221.                     } else {
  222.                         contents+='<p><strong>Product price: $49 USD</strong></p>'+
  223.                                             '<p>'+returnBuyLink(31000)+'Click here to order</a></p>';
  224.                         
  225.                     }
  226.                 }                
  227.                 contents+='</td>';            
  228.             } else {
  229.                 titleEnd="upgrades";
  230.             }
  231.             if (i==2 || i==-1) { // demo or express
  232.                 contents+='<td width="'+cellSpan+'" class="fl-tbl">';
  233.                 contents+=data.flRegs[1].description;
  234.                 if (i==-1) {    // demo: buy fruityloops
  235.                     if (isBasic) {
  236.                         contents+='<p><strong>Upgrade price: $79 USD</strong></p><p>'+returnBuyLink(31070)+'Click here to order</a></p>';
  237.                     } else {
  238.                         contents+='<p><strong>Product price: $99 USD</strong></p><p>'+returnBuyLink(31010)+'Click here to order</a></p>';                    
  239.                     }
  240.                 }        
  241.                 if (i==2) { // express: upgrade to fruityloops (from express)
  242.                     if (isCreative) {
  243.                         contents+='<p><strong>Upgrade price: $69 USD</strong></p>'+
  244.                                             '<p>'+returnBuyLink(31075)+'Click here to upgrade</a></p>';                    
  245.                     } else {
  246.                             contents+='<p><strong>Product price: $59 USD</strong></p>'+
  247.                                                 '<p>'+returnBuyLink(31050)+'Click here to upgrade</a></p>';
  248.                     }
  249.                 }                
  250.                 contents+='</td>';
  251.             }
  252.             if (i!=0) { // demo, express, fl options for producer
  253.                 contents+='<td width="'+cellSpan+'" class="fl-tbl">';
  254.                 contents+=data.flRegs[0].description;
  255.                 if (i==-1) {    // demo: buy producer
  256.                     if (isBasic) {
  257.                         contents+=    '<p><strong>Upgrade price: $129 USD</strong></p>'+
  258.                                                 '<p>'+returnBuyLink(31071)+'Click here to order</a></p>';    
  259.                     } else {
  260.                         contents+=    '<p><strong>Product price: $149 USD</strong></p>'+
  261.                                                 '<p>'+returnBuyLink(31020)+'Click here to order</a></p>';    
  262.                     }
  263.                 }            
  264.                 if (i==1) { // fl edition: upgrade to producer from fruityloops
  265.                     if (isBoxed) {
  266.                         // $79
  267.                         contents+='<p><strong>Upgrade price (boxed): please check your local dealer</strong></p>'+
  268.                                             '<p><strong>Upgrade price (online): $69 USD</strong></p>'+
  269.                                             '<p>'+returnBuyLink(31081)+'Click here to upgrade</a></p>';
  270.                     }    else {
  271.                         contents+='<p><strong>Upgrade price: $59 USD</strong></p>'+
  272.                                             '<p>'+returnBuyLink(31040)+'Click here to upgrade</a></p>';
  273.                     }
  274.                 }    
  275.                 if (i==2) { // express: upgrade to producer from express (express can't be boxed)
  276.                     if (isCreative) {
  277.                         contents+='<p><strong>Upgrade price: $119 USD</strong></p>'+
  278.                                             '<p>'+returnBuyLink(31076)+'Click here to upgrade</a></p>';                    
  279.                     } else {
  280.                         contents+='<p><strong>Upgrade price: $99 USD</strong></p>'+
  281.                                             '<p>'+returnBuyLink(31051)+'Click here to upgrade</a></p>';
  282.                         
  283.                     }
  284.                 }                    
  285.                 contents+='</td>';
  286.             }            
  287.             
  288.             // XXL
  289.             contents+='<td width="'+cellSpan+'" class="fl-tbl">';
  290.             contents+=data.flDesc.xxl;
  291.             if (isBoxed) {
  292.                 if (i==1) { // from fruityloops
  293.                     // $269
  294.                     contents+='<p><strong>Upgrade price (boxed): please check your local dealer</strong></p>'+
  295.                                         '<p><strong>Upgrade price (online): click the link for more info (no DVD included)</strong></p>'+
  296.                                         '<p>'+returnBuyLink('')+'Click here to upgrade</a></p>';
  297.                 } else if (i==0) { // from producer
  298.                     // was $199 USD
  299.                     contents+='<p><strong>Upgrade price (boxed): please check your local dealer</strong></p>'+
  300.                                         '<p><strong>Upgrade price (online): click the link for more info (no DVD included)</strong></p>'+
  301.                                         '<p>'+returnBuyLink('')+'Click here to upgrade</a></p>';
  302.                 } else {
  303.                     contents+='<p><strong>Upgrade price: click the link for more info</strong></p>'+
  304.                         '<p>'+returnBuyLink('')+'Click here to upgrade</a></p>';
  305.                 }
  306.             } else {
  307.                 if (i==-1) { // buy
  308.                     if (isBasic) {
  309.                         contents+='<p><strong>Upgrade price: click the link for more info</strong></p>'+
  310.                                             '<p>'+returnBuyLink('')+'Click here to upgrade</a></p>';
  311.                     } else {
  312.                         contents+='<p><strong>Product price (boxed): $449 USD</strong></p>'+
  313.                                             '<p><strong>Product price (online): $339 USD (no DVD included)</strong></p>'+
  314.                                             '<p>'+returnBuyLink('')+'Click here to upgrade</a></p>';            
  315.                     }
  316.                 } else { // upgrade (from any online version)
  317.                     contents+='<p><strong>Upgrade price: click the link for more info</strong></p>'+
  318.                                         '<p>'+returnBuyLink('')+'Click here to upgrade</a></p>';
  319.                 }
  320.             }
  321.             contents+='</td>';
  322.             
  323.             
  324.             contents+='</tr></table>';
  325.             panels.insertPanel('Available FL-Studio '+titleEnd,contents, "na");
  326.         }
  327.     }    
  328. }
  329.  
  330. // ---------------------------------------------------------------------------------
  331. // PARSERS
  332.  
  333. function parseProductData() // read & parse the data.xml file with products and settings
  334. {
  335.     var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  336.     xmlDoc.async="false";
  337.     xmlDoc.load("data.xml");
  338.     var xmlRoot = xmlDoc.documentElement.selectSingleNode('/fddata');
  339.     var node; // reused while parsing
  340.  
  341.     data = {};// intentionally on root to be globally accessible
  342.     
  343.     // FL descriptions
  344.     data.flDesc = {
  345.         xxl:innerXML(xmlRoot.selectSingleNode('flDesc/desc[@id="desc_xxl"]')),
  346.         producer:innerXML(xmlRoot.selectSingleNode('flDesc/desc[@id="desc_producer"]')),
  347.         fl:innerXML(xmlRoot.selectSingleNode('flDesc/desc[@id="desc_fl"]')),
  348.         express:innerXML(xmlRoot.selectSingleNode('flDesc/desc[@id="desc_express"]')),
  349.         fl4creative:innerXML(xmlRoot.selectSingleNode('flDesc/desc[@id="desc_fl4creative"]')),
  350.         express4basic:innerXML(xmlRoot.selectSingleNode('flDesc/desc[@id="desc_express4basic"]'))
  351.     };
  352.     // xxl / box codes
  353.     data.xxlCodes = xmlRoot.selectSingleNode('xxlCodes').text.split(',');
  354.     data.boxCodes = xmlRoot.selectSingleNode('boxCodes').text.split(',');    
  355.     // FL registrations
  356.     node = xmlRoot.selectSingleNode('flRegs').firstChild;
  357.     data.flRegs = [];
  358.     do {
  359.         data.flRegs[data.flRegs.length] = {
  360.             code:node.attributes.getNamedItem('code').nodeValue,
  361.             name:node.attributes.getNamedItem('name').nodeValue,
  362.             registered:false,
  363.             needed:false
  364.         }
  365.     } while (node = node.nextSibling);
  366.     // patch content in:
  367.     data.flRegs[0].description = data.flDesc.producer;
  368.     data.flRegs[1].description = data.flDesc.fl;    
  369.     data.flRegs[2].description = data.flDesc.express;
  370.     // other product registrations
  371.     node = xmlRoot.selectSingleNode('products').firstChild;
  372.     data.products = [];
  373.     do {
  374.         data.products[data.products.length] = {
  375.             code:node.attributes.getNamedItem('code').nodeValue,
  376.             name:node.attributes.getNamedItem('name').nodeValue,
  377.             prodType:node.attributes.getNamedItem('prodType').nodeValue,            
  378.             description:innerXML(node),
  379.             registered:false,
  380.             needed:false
  381.         }
  382.     } while (node = node.nextSibling);
  383.     // create merged array with all products
  384.     data.allProducts = [];
  385.     for (var i=0; i<data.flRegs.length; i++) {
  386.         data.allProducts[data.allProducts.length] = data.flRegs[i];
  387.     }
  388.     for (var i=0; i<data.products.length; i++) {
  389.         data.allProducts[data.allProducts.length] = data.products[i];
  390.     }    
  391. }
  392. function readRegData() // read FL.js 
  393. {
  394.     // ----------------------------------------
  395.     // include reg file & decode params array
  396.     if (typeof(params)=="undefined") {
  397.         // --------------------
  398.         // read file
  399.         var regFilePath = 'file:///'+((location.href.substring((location.href.indexOf(':') == 2)?14:7, location.href.lastIndexOf("\\") + 1)+'FL.js').replace(/:/g, '|')).replace(/\\/g, '/') ; // full FL.js location        
  400.         document.write('<script language="JavaScript" type="text/javascript" src="'+regFilePath+'"></script>');
  401.     }
  402. }
  403. function parseRegData() // parse reg info
  404. {
  405.     if (typeof(params)=="undefined") {
  406.         // --------------------        
  407.         // parse base64 to params
  408.         var source=((paramsSource).slice(1)).toUpperCase(); // dump "G" at start & capitalize
  409.         var i=0,j=0;
  410.         var base16='0123456789ABCDEF';
  411.         var buffer=source.split('G');
  412.         params = ['','','','']; // globally accessible
  413.         for (i=0;i<buffer.length;i++) {
  414.             params[i]='';
  415.             for (j=0;j<buffer[i].length;j+=2) {
  416.                 params[i]+=String.fromCharCode(16*base16.indexOf(buffer[i].charAt(j))+base16.indexOf(buffer[i].charAt(j+1)));
  417.             }
  418.         }    
  419.     }
  420.     // ----------------------------------------
  421.     // parse userData array    
  422.     userData = ['','','','']; // globally accessible
  423.     // parse
  424.     userData[0]=params[1].substring(0,params[1].indexOf(':'));
  425.     userData[1]=params[1].substring(params[1].indexOf(':')+1,params[1].lastIndexOf(':'));
  426.     userData[2]=params[1].substring(params[1].indexOf('[')+1,params[1].indexOf(']'));
  427.     userData[3]=params[1].substring(params[1].indexOf('|')+1,params[1].lastIndexOf('|')).slice('|');    
  428. }    
  429. function processData()
  430.     var i,j;
  431.     
  432.     // scan codes
  433.     var codes=userData[3].split('|');
  434.     
  435.     // a little mapping job from VSTi/DXi plugin codes to the regular codes
  436.     for (var i=0; i<codes.length; i++) {
  437.         switch (codes[i]) {
  438.             case '37110': // SSLive
  439.                 codes[codes.length] = '33110';
  440.                 break;
  441.             case '37041': // Sytrus
  442.                 codes[codes.length] = '37040';            
  443.                 break;
  444.             case '37021': // DX10
  445.                 codes[codes.length] = '37020';            
  446.                 break;
  447.             case '37310': // WASP
  448.                 codes[codes.length] = '33300';            
  449.                 break;
  450.         }
  451.     }    
  452.  
  453.     for (i=0;i<codes.length;i++) {
  454.         // check if the code means boxed version
  455.         for (j=0;j<data.boxCodes.length;j++) {
  456.             if (data.boxCodes[j]==Number(codes[i])) isBoxed=true;
  457.         }    
  458.         
  459.         if (codes[i]=='21020' || codes[i]=='21420') { // creative
  460.             isCreative=true;
  461.             data.flRegs[2].name='FL Studio Creative Edition';
  462.             // patch the regInfo
  463.             data.flRegs[1].description = data.flDesc.fl4creative;
  464.         }
  465.         if (codes[i]=='21000' || codes[i]=='21010') { // basic
  466.             isBasic=true;
  467.             data.flRegs[2].description = data.flDesc.express4basic;
  468.         }
  469.         
  470.         // set a product registered if a code is found
  471.         for (j=0;j<data.allProducts.length;j++) {
  472.             if (data.allProducts[j].code==Number(codes[i])) {
  473.                 data.allProducts[j].registered=true;
  474.             }
  475.         }
  476.     }
  477.     
  478.     // correct reg levels for special cases
  479.     if (isBasic) {
  480.         data.flRegs[0].registered = false;
  481.         data.flRegs[1].registered = false;
  482.         data.flRegs[2].registered = false;
  483.     } else if (isCreative) {
  484.         data.flRegs[0].registered = false;
  485.         data.flRegs[1].registered = false;
  486.         data.flRegs[2].registered = true;            
  487.     }
  488.     
  489.     // scan pluglist to mark needed plugins
  490.     var pluglist=params[4].split(':');
  491.     for (i=0;i<pluglist.length;i++) {
  492.         for (j=0;j<data.allProducts.length;j++) {
  493.             if (data.allProducts[j].name.toUpperCase()==pluglist[i].toUpperCase()) {
  494.                 data.allProducts[j].needed=true;
  495.             }
  496.         }
  497.     }
  498.     // detect XXL installation
  499.     var hits = 0;
  500.     for (i=0;i<data.xxlCodes.length;i++) {
  501.         for (j=0;j<data.allProducts.length;j++) {
  502.             if (data.allProducts[j].code==data.xxlCodes[i] && data.allProducts[j].registered) {
  503.                 hits++;
  504.             }        
  505.         }
  506.     }    
  507.     if (hits == data.xxlCodes.length) isXXL = true;
  508. }
  509. // ---------------------------------------------------------------------------------
  510. // DEBUG UTILS
  511. function initDebugRoutines()
  512. {
  513.     function debugDump() {
  514.         var cont = '';
  515.         cont += '<hr><p>DEBUG INFO (parameters listed):</p>';
  516.         for (i=0;i<params.length;i++) {
  517.             cont += '<br>'+i+': '+(((params[i]==undefined)||(params[i]==''))?'<b>N/A</b>':'"'+params[i]+'"');
  518.         }
  519.         cont+= '<br>'+location.hash;
  520.         var el = document.createElement('div');
  521.         document.getElementsByTagName('body').item(0).appendChild(el);
  522.         el.innerHTML = cont;
  523.     }        
  524.     if (allowDebugDump) {
  525.         window.attachEvent("onload",debugDump);
  526.     }
  527.     if (allowDebugParams) {
  528.         params = []; // globally accessible
  529.         params[0]="FLDI";
  530.         params[1]="StanislavNVasilev54875:60846:|21420|31020|";
  531.         params[2]="";    params[3]="2"; params[4]="";        
  532.         // xxl
  533.         //params[1]= "StanislavNVassilev54875:60846:|31020|33110|37030|37040|33000|37050|31000|";        
  534.     }
  535. }
  536.  
  537. // ---------------------------------------------------------------------------------
  538. // INIT
  539.  
  540. allowDebugDump = false; // dumping of received params
  541. allowDebugParams = false; // injects debug set of params 
  542. initDebugRoutines();
  543.  
  544. // init flags (autodetected/set later)
  545. isCreative=false; // Express special case
  546. isBoxed=false; 
  547. isBasic=false; // Demo special case
  548. isXXL = false;
  549. isDemo = false; 
  550.  
  551. function stage1() 
  552. {
  553.     parseProductData();
  554.     readRegData();
  555. }
  556. function stage2() 
  557. {
  558.     parseRegData();
  559.     processData();
  560. }
  561.  
  562. // NOTE: stage1 includes loading external JS file via document.write which requires that parsing is done later while "waiting" for data, so it's split in stage2 and called later in the HTMLs
  563.  
  564. // ready, steady, go...
  565. stage1();
  566.  
  567. // Dorothy, I think we're not in Kansas anymore...