PageSourceSearch

https://premioeleanor.it/_Include/Funzioni.js

js premioeleanor.it collected 2026-10-01 15:59:04 UTC 288,017 bytes, 6,813 lines download raw bytes

1/*<script type="text/javascript" language="javascript"><!--*/
2//#######################################
3//####     F U N Z I O N I . J S     ####
4//#######################################
5//	11/05/2010	ver. 2.18.16.2	- [40] Classe [HtmlPlus_SlideShow] funzione [Play]: aggiunto controllo sul numero di immagini, che se è una sola
6//				modifico la property "repeat" in FALSE; così da fermare la ripetizione delle immagini dopo aver mostrato la prima.
7//	07/05/2010	ver. 2.18.16.1	- [40] Funzioni [AddClassName] e [RemoveClassName]: corretto problema di spazi (ne aggiungeva in testa); messo ricerca
8//				del ClassName non più con "Ignore Case".
9//	05/05/2010	ver. 2.18.16	- [40] Modifica funzione [ReplaceArgDict]: aggiunto argomento "optO_TextArguments" che restituisce la lista degli
10//				argomenti trovati nella stringa [Text]. Modificata la RegularExpression per cercare i parametri: ora accetto ogni carattere ASCII
11//				dallo spazio in sù escluse le graffe.
12//	13/04/2010	ver. 2.18.15	- [40] Aggiunto funzione [IsNull]; corretto classe [HtmlPlus_SlideShow]: dava problemi nel mostrare le immagini che
13//				aveva già caricate.
14//	13/04/2010	ver. 2.18.14	- [40] Classe [HtmlPlus_PageScroller] migliorato il funzionamento: ora è possibile indicare un "pageWidth" minore della
15//				dimensione del DIV di scorrimento; ovvero posso avere 15 items, visibili 10 alla volta e indicare che ne voglio vedere 3 nuovi per pagina.
16//	15/03/2010	ver. 2.18.13	- [40] Classe [HtmlPlus_Popup]: se la proprietà [abortOnClickOut] è TRUE allora il popup sichiuderà anche premendo ESC.
17//	12/03/2010	ver. 2.18.12	- [40] Classe [HtmlPlus_Popup]: aggiunto possibilità di indicare se cliccando fuori dal Popup questo si deve chiduere;
18//				per default la funzionalità è attivata (vedere proprietà [abortOnClickOut]).
19//	02/03/2010	ver. 2.18.11.1	- [40] Corretto problema su [HtmlPlus_Popup], pulsante Abort che non funzionava in tutte le condizioni. Problema
20//				sulla funzione [FindArrayItem], non funzionava proprio come doveva, rifatta da capo. Funzione [findParentObj]: migliorato il codice
21//				interno e dato la possibilità di ricercare con RegExp anche sull'argomento [optTagNameFilter].
22//	01/03/2010	ver. 2.18.11	- [40] Aggiunto funzioni [GetUID] e [GetLastUID], che restituiscono, come per FUNZIONI.ASP, un ID univoco. Questa
23//				funzione non tiene conto della relativa funzione in VB lato server, quindi le due potrebbero, in rari casi, generare lo stesso valore.
24//				Ho anche risolto un baco su [HtmlPlus_Popup], che si verificava quando si sfruttava la nuova funzionalità: apertura Popup in frame TOP.
25//	18/02/2010	ver. 2.18.10	- [40] Aggiunta funzione [FindArrayItem]: cerca un Item in un array, su tutti i frame. Modificato [findObj] che ora
26//				estende la sua ricerca. Modificato [HtmlPlus_Popup] che ora gli si può indicare se il popup deve apparire sul frame corrente o su [top].
27//	08/02/2010	ver. 2.18.9		- [40] Aggiunta funzione [CStrRE] che codifica una stringa per poter essere cercata con una RegularExpression.
28//	11/01/2010	ver. 2.18.8		- [40] Classe [HtmlPlus_ServerEval]: risolto problemi di comunicazione con "AspResponder"; migliorato modalità debug.
29//	18/12/2009	ver. 2.18.7		- [40] Classe [HtmlPlus_BarcodeReader]: migliorato software, che ora ha per default (ed è in grado di accettare) una
30//				lista di coppie di caratteri "preambolo"-"postambolo", per risolvere problemi con alcuni browser che interpretano alcuni caratteri ascii
31//				come comandi sul browser stesso, come ad esempio "Refresh della pagina", "Aggiungi a preferiti", "Fullscreen" ecc.
32//	24/11/2009	ver. 2.18.6.3	- [40] Corretto errore su [GetValue]: non riusciva a ottenere le varie parti del numero in certe condizioni.
33//	24/11/2009	ver. 2.18.6.2	- [40] Corretto errore su [STDEvent]: non leggeva bene il valore [keyCode] da Firefox; corretto [getPos] che non calcolava
34//				bene la posizione dell'oggetto in presenza di barre di scorrimento con "scrollLeft/Top" maggiori di ZERO.
35//	17/11/2009	ver. 2.18.6.1	- [40] Corretto errore su [HtmlPlus_AutoScroll]: usavo GetCssStyle per leggere 'clientHeight', anzichè GetProperty.
36//	13/11/2009	ver. 2.18.6		- [40] Aggiunta funzione [SetDailyTime] per settare l'ora ad un oggetto Date; corretto piccoli errori in varie procedure.
37//	10/11/2009	ver. 2.18.5.1	- [40] Errore in [HtmlPlus_SlideShow]: calcolava la ridimensione dell'immagine credendo fosse per IMG1 anzichè IMG2; ho
38//				risolto memorizzando le dimensioni delle immagini nell'item stessa.
39//	23/10/2009	ver. 2.18.5		- [40] Modifica alla classe [HtmlPlus_Popup]: oggetto ombra ora è padre del contenuto, e ho dovuto togliere "opacity".
40//	23/10/2009	ver. 2.18.4		- [40] Modifica alla classe [HtmlPlus_Popup], che ora usa sempre lo stile default, e poi aggiunge, se indicato, lo
41//				stile personalizzato.
42//	21/10/2009	ver. 2.18.3.2	- [40] Funzione [HtmlPlus_DimensionFill]: corretto baco, si usava impropriamente [GetCssStyle] per leggere "clientHeight",
43//				ma questo appartiene all'oggetto HTML, e non all'oggetto [style].
44//	21/10/2009	ver. 2.18.3.1	- [56] La funzione [GetCssStyle] se non esegue nessun comando restituisce [null] al posto di ['']
45//	16/10/2009	ver. 2.18.3		- [40] Aggiunta funzione [GetDocInfo] che restituisce informazioni particolari sul documento; aggiunta funzione [GetCssStyle]
46//				che restituisce l'effettivo valore di un attributi di stile; corretto errori di compatibilità con W3C sulle funzioni [ReplaceArgList],
47//				[HtmlEncode] e [SetCssStyle], corretto problema di compatibilità su [HtmlPlus_DimensionFill], che ora usa [GetDocInfo], corretto problema
48//				di compatibilità su [HtmlPlus_Positionator], che calcolava male le posizioni su Firefox.
49//	13/10/2009	ver. 2.18.2		- [40] Aggiunta funzione [FileInclude]: aggiunge una inclusione di un file JS oppure CSS.
50//	13/10/2009	ver. 2.18.1		- [40] Aggiunta classe [HtmlPlus_Positionator]: dato un oggetto (da posizionare), ed un insieme di altri oggetti, posiziona
51//				il primo "attorno" oppure "all'interno" dell'area del secondo.
52//	12/10/2009	ver. 2.18.0.1	- [40] Corretto bachi nelle procedure modificate precedentemente.
53//	12/10/2009	ver. 2.18.0		- [40] Aggiunta funzione [GetValue]: dato un valore con unità di misura, restituisce il numero e UM divisi, in dictionary;
54//				aggiunta funzione [CDateHtml_GetFormat], del tutto simile a quella in ASP; modificata funzione [CDateHtml], che ora supporta ogni formato
55//				come in ASP; modifiche alla classe [HtmlPlus_Popup], che ora, il popup è completamente disegnato nell'elemento [content]; aggiunta al popup
56//				della possibilità di usare "position:fixed": la classe non imposta più tale attributo di stile, che quindi dovrà essere fatto da CSS, su
57//				valore "absolute" o "fixed"; aggiunta funzione [CDateHtml_GetFormatInfo], che restituisce informazioni sul formato data del browser;
58//				modificata funzone [CDate]: ora usa [CDateHtml_GetFormat] per indicare il formato di data/ora.
59//	02/10/2009	ver. 2.17.2		- [40] Aggiunta funzione [CStrXML], in analogia alla versione ASP.
60//	25/07/2009	ver. 2.17.1.1	- [40] Funzione [CStrHtml]: non sostituiva gli a-capo con i relativi "<br>"; classe [HtmlPlus_Popup]: su invio comando
61//				al Popup "Initialize" mancava un "CStrJS" per il valore da passare, serializzato.
62//	24/07/2009	ver. 2.17.1		- [40] Classe [HtmlPlus_ServerEval]: aggiunto argomento "optDebugMode" al metodo [Run].
63//	23/07/2009	ver. 2.17.0		- [40] Migliorata classe [HtmlPlus_ClipMaker] e [HtmlPlus_SlideShow].
64//	23/07/2009	ver. 2.16.12	- [40] Aggiunto funzione [CDate], che cerca di convertire la data in stringa secondo il formato indicato.
65//	01/07/2009	ver. 2.16.11.4	- [40] Risolto baco su [HtmlPlus_ClipMaker]: non lavorava il primo fotogramma, appena richiesto il Play.
66//	26/06/2009	ver. 2.16.11.3	- [40] Funzione [CDateHtml]: corretto piccolo baco su calcolo formato "datetime".
67//	16/06/2009	ver. 2.16.11.2	- [56] Modificato massimale di [HtmlPlus_VerticalFill] da 5000 a 50000px.
68//	12/06/2009	ver. 2.16.11.1	- [40] Procedura [SetCookie]: corretto metodo per settare la scadenza del cookie con la scadenza della sessione.
69//	05/06/2009	ver. 2.16.11	- [40] Modificata funzione [SetCookie]: aggiunto possibilità di indicare che il cookie deve scadere con lo scadere
70//				della sessione, indicando l'argomento "Expire" su Null.
71//	28/05/2009	ver. 2.16.10	- [40] Aggiunto funzioni [ReplaceArgList] e [ReplaceArgDict], che funzionano come quelle in "Funzioni.asp".
72//	25/05/2009	ver. 2.16.9		- [56] Modificato funzione [OggettiRifDlgFind]
73//	14/05/2009	ver. 2.16.8.1	- [40] Funzione [SetCssStyle]: consento che il valore di un attributo possa essere formato da ZERO caratteri; risolto
74//				errore su [HtmlPlus_TextboxWithLabelInside]: il cursorse nel Textbox perdeva la posizione quando era settato un valore e successivamente
75//				acquistava il focus.
76//	30/03/2009	ver. 2.16.8		- [40] Aggiunta [SetClassName], che esegue le procedure [AddClassName] e [RemoveClassName] in base ad un
77//				argomento.
78//	26/03/2009	ver. 2.16.7.1	- [40] Risolti problemi alla funzione [HtmlPlus_DimensionFill].
79//	26/03/2009	ver. 2.16.7		- [40] Aggiunta funzione [HtmlPlus_DimensionFill]: viene usata dalle HtmlPlus_VerticalFill e HtmlPlus_OrizzontalFill.
80//	23/03/2009	ver. 2.16.6		- [40] Aggiunte funzioni [AddClassName], [RemoveClassName], [ContainsClassName]: servono per aggiungere, rimuovere
81//				e verificare voci nel ClassName di un oggetto Html.
82//	17/03/2009	ver. 2.16.5		- [40] Aggiunta funzione [CNumJS]; modificata funzione [CStrJS]: aggiunto argomento "AddDelimeters";
83//				classe [STDEvent]: aggiunta possibilità di passare per argomento un altro oggetto [STDEvent], utile quando si deve invocare
84//				una funzione creata per gestire un evento da un'altra procedura che gestisce già l'evento.
85//	10/03/2009	ver. 2.16.4		- [40] Funzioni [HtmlPlus_OrizzontalFill] e [HtmlPlus_VerticalFill]: ora usa [SetProperty] per impostare i valori,
86//				ottenendo così la possibilità di usare le funzioni anche su tag <DIV> e altri.
87//	06/03/2009	ver. 2.16.3		- [40] Aggiunta funzione [CCurHtml], che per ora restituisce lo stesso valore di [CNumHtml].
88//	13/02/2009	ver. 2.16.2.2	- [40] Funzioni [SerializeValue] e [DeserializeValue]: corretto problema di riconoscimento tipo
89//				"Array"/"Dictionary"; aggiunto procedure [SerializeValue__ArrayColl_addArrayType] e [SerializeValue__ArrayColl_getArrayType].
90//	10/02/2009	ver. 2.16.2.1	- [40] Funzioni [HtmlPlus_OrizzontalFill] e [HtmlPlus_VerticalFill]: non funzionavano correttamente quando venivano
91//				usate su oggetti contenuti in un IFrame con Scrollbar dove quest'ultime non erano presenti per causa dell'oggetto controllato dalle
92//				funzioni.
93//	19/01/2009	ver. 2.16.2		- [56] Aggiunto funzioni[Traduci_Lingue_Index][Traduci_Lingue_LCID][Traduci_Lingue_Code][Traduci_Lingue_Count].
94//	28/11/2008	ver. 2.16.1		- Funzione [CDateHtml]: aggiunto tipi formato "datetime" e "time".
95//	28/11/2008	ver. 2.16.0		- Aggiunto procedure alla classe [Date] con l'uso di "prototype"; aggiunto [CreateList] e [CreateDictionary] per
96//				creare oggetti Array con procedure aggiunte; rimosso classe [HtmlPlus_Grid], perchè spostata in file apposito.
97//	16/09/2008	ver. 2.15.3.2	- Risolti problemi in [OggettiRif_DlgFind]: ora ho un parametro unico per configurare i comportamenti, chiamato CFG.
98//	15/09/2008	ver. 2.15.3.1	- Classe [HtmlPlus_Popup]: risolto baco su calcolo posizione Popup, mancava un "break"; aggiunto controllo sui
99//				valori di posizione calcolati: se la coordinata (X o Y) è miniore di 10 allora imposto a 10.
100//	12/09/2008	ver. 2.15.3		- Aggiunta funzione [OggettiRif_DlgFind]: apre la maschera standard di ricerca di records OggettiRif; fatte anche
101//				numerose migliorie grafiche e di funzionamento su [HtmlPlus_Popup]: aggiunta possibilità di definire la posizione del popup tramite
102//				una percentuale, risolto problema dell'ombra per siti più piccoli del browser, aggiunta variabile THIS nel codice dell'IFRAME.
103//	03/09/2008	ver. 2.15.2.1	- Classe [HtmlPlus_Popup]: risolto baco su ombra, che non veniva mostrata come tale in caso di animazione "Zoom".
104//	25/08/2008	ver. 2.15.2		- Modifica classe [HtmlPlus_Grid]: aggiunte funzioni "SetTrSelect" e "SetTrViewed".
105//	07/08/2008	ver. 2.15.1		- Modifica classe [HtmlPlus_Grid]: rinominata funzione "TrEvents_onDblClick" in "TrEvents_OpenRecord".
106//	04/08/2008	ver. 2.15.0		- Aggiunta classe [HtmlPlus_Grid]: serve per dare funzionalità Java ad una tabella.
107//	31/07/2008	ver. 2.14.3.1	- Corretto baco funzione [SerializeValue]
108//	23/07/2008	ver. 2.14.3		- Classe [HtmlPlus_ServerEval]: aggiunta funzione [Parameters], che contiene l'array dei parametri passati; nella
109//				classe [DevelopingMode_AddItem] aggiunta condizione: se "window.DevelopingMode" non è TRUE allora la classe non funziona.
110//				Procedure [SerializeValue] e [DeserializeValue]: risolto baco su conversione valore EMPTY (stringa vuota).
111//	11/07/2008	ver. 2.14.2		- Aggiunta classe [HtmlPlus_ServerEval]: serve ad invocare comandi lato server.
112//	27/06/2008	ver. 2.14.1.3	- Modificato procedure [HtmlPlus_BarcodeReader] e [DevelopingMode_AddItem].
113//	20/06/2008	ver. 2.14.1.2	- Procedure [SerializeValue] e [DeserializeValue]: risolti diversi bachi che si manifestavano quando un Array o
114//				un Dictionary erano senza elementi; ho risolto anche il problema di capire in DeserializeValue se un oggetto è un Dictionary
115//				o Array, soluzione però che funziona solo se l'oggetto è stato generato da SerializeValue.
116//	19/06/2008	ver. 2.14.1.1	- Soluzione baco [DevelopingMode]: al momento è stata bloccata la procedura [DevelopingModeMenu_AddItem], e
117//				presto si dovrà cercare il motivo dell'errore e risolverlo.
118//	18/06/2008	ver. 2.14.1		- Aggiunta funzione [DevelopingModeMenu_AddItem] per gestire il menù DevelopingModeMenu, e aggiunto impiego nella
119//				classe [HtmlPlus_BarcodeReader].
120//	30/05/2008	ver. 2.14.0.3	- Corretti commenti qua e la..
121//	20/03/2008	ver. 2.14.0.2	- Classe [HtmlPlus_Popup]: corretto baco: andava in loop poichè ogni volta richiamava l'evento OnLoad.
122//	13/02/2008	ver. 2.14.0.1	- Funzione[DeserializeValue] risolto baco: non deserializzava gli Interi ma solo i Float.
123//	18/01/2008	ver. 2.14.0		- Modificato Funzione [GetBrowserInfo] in modo che ritorni il tipo sistema operativo utilizzato per il dispositivo, e 
124//				aggiunto funzione per vedere che tipo di hardware è utilizzato. Modificata Funzione [SetProperty] se settando opacity si utilizza un 
125//				dispositivo non PC opacity non viene settata.
126//	08/01/2008	ver. 2.13.0		- Aggiunta Funzione [CNumHTML], ha lo stesso funzionamento di quella esistente in VBScript.
127//	27/12/2007	ver. 2.12.1.1	- Classe [HtmlPlus_Popup]: risolto baco per IE6 in caso che il contenuto sia un IFRAME.
128//	27/12/2007	ver. 2.12.1		- Funzione [GetBrowserInfo]: aggiunto 'CpuSpeed' che restituisce un numero che indica la velocità del processore.
129//	27/12/2007	ver. 2.12.0.2	- Funzione [toNumber]: corretto comportamento nel caso che non c'è alcun numero memorizzato nel testo passato;
130//				Classe [HtmlPlus_Popup]: fatta correzione nella funzione di gestione del ridimensionamento del browser, in caso di isModal=true
131//				e isOpen=false.
132//	21/12/2007	ver. 2.12.0.1	- Procedure [SerializeValue] e [DeserializeValue]: corrette in caso di conversione in Array e Dictionary.
133//	20/12/2007	ver. 2.12.0		- Aggiunte funzioni per la gestione dei [COOKIE], aggiunta classe [HtmlPlus_Popup], e aggiunte e corrette altre
134//				piccole cose.
135//	14/12/2007	ver. 2.11.1		- Aggiunta funzione [IsUndefined]. Funzione [toNumber]: corretto baco che si verificava se il numero passato era
136//				già un numero.
137//	07/12/2007	ver. 2.11.0		- Aggiunta classe [HtmlPlus_SlideShow] per la gestione degli slide show.
138//	05/12/2007	ver. 2.10.0.1	- Corretto baco funzione CStrJS.
139//	04/12/2007	ver. 2.10.0		- Aggiunta classe [HtmlPlus_ClipMaker] per la gestione delle animazioni.
140//	03/12/2007	ver. 2.9.7		- Modificata funzione [HtmlPlus_Autoscroll], aggiunto la possibilità di far scorrere gli oggetti orizzontalmente.F
141//	07/11/2007	ver. 2.9.6		- Aggiunta funzione [CStrJS], che funziona come quella fatta in VBScript. Aggiunta poi [ViewPointerPosition].
142//	10/10/2007	ver. 2.9.5		- Aggiunta alla classe [UrlParserClass]: ho aggiunto la funzione [GetPartialUrl] che restituisce una parte percorso
143//				secondo le indicazioni (true/false) passate negli argomenti.
144//  03/10/2007	ver. 2.9.4.1	- Corretto baco in funzione [HtmlPlus_AnimationOnMouseEvents] e corretto baco nella funzione [ValueType]
145//  18/09/2007	ver. 2.9.4		- Inserita nuova funzione [CPropertyJS] da utilizzare per trasformare il nome di una proprietà dal formato CSS
146//				al formato JScript. Risolto baco su funzione [SetCssStyle], in pratica nella RegEx per segnalare un carattere "\", JScript ne
147//				necessita 2. Es.: per passare "\s*" a RegEx si deve scrivere così "\\s*".
148//  14/09/2007	ver. 2.9.3.2	- Modificate Funzioni [CStrUrlParam] e [StringToUrl] risolto dei bachi.
149//  13/09/2007	ver. 2.9.3.1	- Modificate Funzione [SetProperty] e HtmlPlus_AnimationOnMouseEvents, risolto dei bachi.
150//  06/09/2007	ver. 2.9.3		- Modificate Funzione [GetProperty], in caso che la proprietà sia 'opacity' controlliamo il browser e la settiamo
151//				in base allo stesso.
152//  31/08/2007	ver. 2.9.2		- Modificate le funzioni[CStrUrlParam] e [StringToUrl]  in quanto esistevano in java procedure apposite
153//  27/07/2007	ver. 2.9.1		- Modificata Classe HtmlPlus_AnimationOnMouseEvents, per la gestione di parametri mozilla o Ie (vedi alpha opacity)
154//  27/07/2007	ver. 2.9.0		- Aggiunte le funzioni LFill, RFill, HTMLEncode, HTMLDecode, SerializeValue, DeserializeValue. Testare la
155//				serializzazione e la deserializzazione degli arary e delle dictionary.
156//	23/07/2007	ver. 2.8.6		- Aggiunta funzione [TestiLiberi_OpenWindow].
157//	19/06/2007	ver. 2.8.5		- Risolto Baco funzione [toNumber] aggiunto metodo .valueOf all'oggetto Number.
158//	15/06/2007	ver. 2.8.4		- Aggiunta funzione [IfNull].
159//	25/05/2007	ver. 2.8.3		- Funzione [GetBrowserInfo]: aggiunta Info "ScreenWidth" e "ScreenHeight".
160//	23/05/2007	ver. 2.8.2.1	- Classe [HtmlPlus_AutoScroll]: risolto problema di incompatibilità con Firefox.
161//	02/04/2007	ver. 2.8.2		- Classe [HtmlPlus_BarcodeReader]: ora l'Azione chiamata può sapere qual'è il KeyChars corrente.
162//	30/03/2007	ver. 2.8.1		- Classe [HtmlPlus_BarcodeReader]: su lettura di un barcode, ho fatto in modo di eseguire solo una Azione.
163//	28/03/2007	ver. 2.8.0		- Aggiunta classe [HtmlPlus_BarcodeReader] per leggere i codici a barre dal browser (non necessariamente da un
164//				Textbox) e [IsTrue] [IsFalse] per riconoscere i valori dichiaratamente impostati su TRUE e su FALSE.
165//	19/03/2007	ver. 2.7.0		- Classe [HtmlPlus_AutoScroll]: rifatta nuova versione, con possibilità di indicare un Html di separatore pagina.
166//	22/01/2007	ver. 2.6.2		- Aggiunta funzione [GetBrowserInfo], e migliorata la funzione [GetProperty].
167//	15/01/2007	ver. 2.6.1.1	- Modifica funzione [SetProperty]: resa compatibile con FireFox.
168//	07/12/2006	ver. 2.6.1		- Aggiunte funzioni [Help_OpenWindow] e [CStrUrlParam]
169//	06/12/2006	ver. 2.6.0.2	- Modifica funzione [HtmlPlus_TextboxWithLabelInside]: resa compatibile con FireFox.
170//	27/11/2006	ver. 2.6.0.1	- Modifica della funzione [SetCssStyle].
171//	24/11/2006	ver. 2.6.0		- Diverse modifiche. Tra cui aggiunta di STDEvent, HtmlPlus_PageScroller, GetProperty e SetProperty.
172//	21/11/2006	ver. 2.5.2.1	- Modifica alla classe [UrlParserClass]: aggiunto campo objectType.
173//	17/11/2006	ver. 2.5.2		- Modifica a [findObj]: aggiunta ricerca per getElementById.
174//	06/10/2006	ver. 2.5.1.3	- Risolto baco IMPORTANTE nella funzione [Traduci_Varchar_Write]: non era in grado di salvare correttamente
175//				il nuovo testo se questo non era la lingua di indice ZERO e se il valore Indice non era passato come numero ma come testo.
176//				Ho anche migliorato in performance le procedure LTrim, RTrim e Trim.
177//	11/08/2006	ver. 2.5.1.2	- Risolto piccolo problema alla funzione [SetHtmlControlValue].
178//	11/08/2006	ver. 2.5.1.1	- Risolto un problema alla nuova classe [HtmlPlus_TextboxWithLabelInside]: se il form che ospita il textbox ha
179//				un pulsante predefinito (che fa il send alla pressione del tasto INVIO) il textbox non riusciva a memorizzare il valore prima
180//				dell'invio del form.
181//	09/08/2006	ver. 2.5.1		- Sostituito "document.getElementById" con "findObj".
182//	09/08/2006	ver. 2.5.0		- Aggiunta classe [HtmlPlus_TextboxWithLabelInside] per mostrare una etichetta nel Textbox quando questo è vuoto.
183//	08/08/2006	ver. 2.4.0		- Aggiunte procedure [InArray] e altre per la ricerca di stringhe ed oggetti all'interno di un array;
184//				corretto anche difetto alla classe [UrlParserClass]: la funzione GetPath restituiva '/' in situazioni particolari.
185//	07/08/2006	ver. 2.3.1		- Migliorie alla classe [UrlParserClass]: aggiunta funxione ExistsProtocol.
186//	05/07/2006	ver. 2.3.0		- Aggiunta classe [HtmlPlus_AnimationOnMouseEvents] per animare oggetti html.
187//	05/07/2006	ver. 2.2.2		- Risolto piccolo problema alla funzione [SetHtmlControlValue].
188//	15/06/2006	ver. 2.2.1		- Spostata procedura per aprire un allegato da Funzioni.ASP a questo file.
189//	12/06/2006	ver. 2.2.0		- Aggiunte variabili che indicano il browser in uso; aggiunta classe per la riproduzione di suoni.
190//	31/05/2006	ver. 2.1.2		- Migliorati i commenti...
191//	03/05/2006	ver. 2.1.1		- Migliorati i commenti...
192//	03/05/2006	ver. 2.1.0		- Aggiunta implementazione di funzioni ValueType e modificato SetHtmlControlValue: ora posso settare
193//				un SELECT con Multisel passando un Array. Devo però implementare la funzionalità oppostua sulla funzione GetHtmlControlValue.
194
195//Assegnano delle variabili per il riconoscimento del browser in uso.
196var IE = (navigator.appVersion.indexOf("MSIE")!=-1 && document.all)? 1:0;
197var NS = (navigator.appName=="Netscape" && navigator.plugins["LiveAudio"])? 1:0;
198var ver4 = (IE || NS)? 1:0;
199
200function GetBrowserInfo(InfoName) {
201	var str1, cont1, cont2;
202	switch (InfoName.toLowerCase()) {
203		case 'name':			//il comando restituisce questo: IE7="MSIE", Firefox2="Netscape"
204			str1 = navigator.appName;
205			switch (str1) {
206				case 'Microsoft Internet Explorer':
207					return 'MSIE';
208				case 'Netscape':
209					return 'Netscape';
210				default:
211					return str1;
212			}
213		case 'version':			//il comando restituisce questo: IE7=4.0, Firefox2=5.0
214			str1 = navigator.appVersion;
215			switch (GetBrowserInfo('name')) {
216				case 'MSIE':
217					str1 = str1.substr(str1.indexOf(' MSIE ') + 6);
218					return toNumber(str1, 0);
219				case 'Netscape':
220					return toNumber(str1, 0);
221				default:
222					return str1;
223			}
224		case 'screenwidth':		//restituisce la larghezza (in pixel) dell'area utile di lavoro dello schermo (tipicamente 1024)
225			switch (GetBrowserInfo('name')) {
226				case 'MSIE':
227					return window.screen.availWidth;
228				case 'Netscape':
229					return window.screen.availWidth;
230				default:
231					return 0;
232			}
233		case 'screenheight':	//restituisce la larghezza (in pixel) dell'area utile di lavoro dello schermo (tipicamente 1024)
234			switch (GetBrowserInfo('name')) {
235				case 'MSIE':
236					return window.screen.availHeight;
237				case 'Netscape':
238					return window.screen.availHeight;
239				default:
240					return 0;
241			}
242		case 'os':				//indica il sistema operativo. Può essere:  'Windows', 'Linux', 'Mac'
243			if (navigator.platform.substr(0,3) == 'Win') {
244				return 'Windows';
245			} else if (navigator.platform.substr(0,3) == 'Mac') {
246				return 'Mac';
247			} else if (navigator.platform.substr(0,6) == 'Linux ') {
248				return 'Linux';
249			} else if (navigator.platform.substr(0,6) == 'CE.Net') {
250				return 'WinCE';
251			} else if (navigator.platform.substr(0,6) == 'Series') {
252				return 'Symbian';
253			} else {
254				return null;
255			}
256		case 'hardwaretype':	//indica il tipo di hardware. Può essere:  'pc', 'palm', 'smartphone'
257			switch (GetBrowserInfo('os')) {
258				case 'Windows':
259				case 'Mac':
260				case 'Linux':
261					return 'pc';
262				case 'WinCE':
263					return 'palm';
264				case 'Symbian':
265					return 'smartphone';
266				default:
267					return null;
268			}
269		case 'iscookieenabled':	//restituisce TRUE se i cookie sono abilitati
270			return IsCookieEnabled();
271		case 'cpuspeed':		//restituisce un numero che rappresenta la velocità di calcolo. Prove:  PC P4HT 3.2GHz -> 3.558 ;  Palmare PXA270 624MHz -> 0.25
272			if (GetBrowserInfo('IsCookieEnabled')) {
273				str1 = GetCookie('CpuSpeed.v1');
274				if (str1 === null) {
275					SetCookie('CpuSpeed.v1', 1, 365);
276					cont2 = new Date();
277					for (cont1 = 0; cont1 < 1000000; cont1++) str1 = 1000 / cont1;
278					cont1 = new Date();
279					str1 = 1000 / (cont1 - cont2);
280					SetCookie('CpuSpeed.v1', str1, 365);
281				}
282			} else {
283				//Se i cookie non sono abilitati non mi metto a calcolare la velocità del processore, perchè è una operazione che potrebbe chiedere
284				//più di 1 secondo, a seconda del pc, o addirittura di più se l'hardware è un vecchio pc o un palmare (commento del 2007).
285				switch (GetBrowserInfo('HardwareType')) {
286					case 'pc':
287						str1 = 1;
288						break;
289					default:
290						str1 = 0.2;
291						break;
292				}
293			}
294			return str1;
295		case 'recommendedfps':	//valore FPS consigliato, in base alle prestazioni del pc
296			str1 = GetBrowserInfo('CpuSpeed');
297			if (str1 < 1) {
298				str1 = 10;
299			} else if (str1 > 5) {
300				str1 = 30;
301			} else {
302				str1 = 10 + (str1 - 1) / 4 * 20;
303			}
304			return str1;	//per ora non ho un sistema per intuire il valore da consigliare
305		default:
306			return null;
307	}
308}
309
310function FileInclude(Fullname) {
311	//Include un file JS o CSS nel documento corrente. Restituisce TRUE se il file è stato incluso, FALSE se non era necessario, NULL se ci sono errori.
312	var vett1, obj1, i, tipo, fReturn;
313	fReturn = null;
314	if (document.getElementsByTagName) {
315		tipo = Fullname.substr(Fullname.lastIndexOf('.') + 1);
316		switch (tipo.toLowerCase()) {
317			case 'js':	tipo = 'js'; break;
318			case 'css':	tipo = 'css'; break;
319			default:	tipo = null; break;
320		}
321		if (tipo) {
322			if (!window.FileInclude__info) {
323				window.FileInclude__info = {js:{}, css:{}};
324				vett1 = document.getElementsByTagName("script");
325				for (var i=0,len=vett1.length; i < len; i++) if (vett1[i].src) FileInclude__info.js[vett1[i].src] = true;
326				vett1 = document.getElementsByTagName("link");
327				for (var i=0,len=vett1.length; i < len; i++) if (vett1[i].href && vett1[i].rel.toLowerCase()=='stylesheet') FileInclude__info.css[vett1[i].href] = true;
328			}
329			fReturn = false;
330			switch (tipo) {
331				case 'js':
332					if (!FileInclude__info.js[Fullname]) {
333						obj1 = document.createElement('script');
334						obj1.type = 'text/javascript';
335						obj1.language = 'javascript';
336						obj1.src = Fullname;
337						FileInclude__info.js[Fullname] = true;
338						document.getElementsByTagName('head')[0].appendChild(obj1);
339						fReturn = true;
340					}
341					break;
342				case 'css':
343					if (!FileInclude__info.css[Fullname]) {
344						obj1 = document.createElement('link');
345						obj1.type = 'text/css';
346						obj1.rel = 'stylesheet';
347						obj1.media = 'all';
348						obj1.href = Fullname;
349						FileInclude__info.css[Fullname] = true;
350						document.getElementsByTagName('head')[0].appendChild(obj1);
351						fReturn = true;
352					}
353					break;
354				default:
355					fReturn = null;
356			}
357		}
358	}
359	return fReturn;
360}
361
362// ### ViewPointerPosition
363// Passando un oggetto come parametro, restituisce le coodrinate del mouse rispetto all'oggetto passato e all'oggetto Window
364function ViewPointerPosition(HtmlObject) {
365	var obj1 = HtmlObject;
366	if (ValueType(obj1) == 'string') obj1 = findObj(obj1);
367	addEvent(obj1, 'mousemove', function (ev) {
368					var eventObj = new STDEvent(ev);
369					window.status = '[ViewPointerPosition] client = ' + eventObj.clientX + ', ' + eventObj.clientY + '; offset = ' + eventObj.offsetX + ', ' + eventObj.offsetY + '; screen = ' + eventObj.screenX + ', ' + eventObj.screenY + ';'  ;
370					}
371			);
372}
373
374
375//Aggiunge una nuova voce al menù [DevelopingMode]. Se quest'ultimo non esiste allora viene creato dalla funzione stessa. Argomenti:
376//	Text :		il testo della voce di menù;
377//	Function :	puntatore a funzione o stringa in JavaScript da eseguire su click sulla voce di menù.
378function DevelopingModeMenu_AddItem(Text, Function) {
379	this.objMenu = findObj('DivDevelopingModeMenu');
380	this.objMenu_List;
381	this.hideTimer;
382	this._initialize = function() {
383		var obj1;
384		
385		if (!this.objMenu) {
386			this.objMenu = document.createElement('DIV');
387			document.body.appendChild(this.objMenu);
388			//alert('1'); return;
389			this.objMenu.id = 'DivDevelopingModeMenu';
390			this.objMenu.style.cssText = 'cursor:hand; position:absolute; z-index:10000; top:0px;right:0px; width:5px;height:5px; overflow:hidden; background-color:#ffff00; border:1px solid #ff0000; color:black; font-size:8pt; text-align:left;';
391			this.objMenu.title = '[DevelopingModeMenu] clicca per aprire';
392			addEvent(this.objMenu, 'click', this._DivMenu_Show);
393			addEvent(this.objMenu, 'mouseout', this._DivMenu_Hide);
394			
395			this.objMenu._DivMenu_Hide__timeout = function () {
396					this.style.overflow = 'hidden';
397					this.style.width = '5px';
398				}
399			
400			obj1 = document.createElement('DIV');
401			this.objMenu.appendChild(obj1);
402			obj1.innerHTML = '[DevelopingModeMenu]';
403			obj1.style.cssText = 'font-weight:bold;';
404
405			this.objMenu_List = document.createElement('UL');
406			this.objMenu.appendChild(this.objMenu_List);
407			this.objMenu_List.style.cssText = 'margin-top:0px;margin-left:20px;margin-right:0px;margin-bottom:0px;';
408		} else {
409			//alert('x'); return;
410			this.objMenu = findObj('DivDevelopingModeMenu');
411			this.objMenu_List = this.objMenu.getElementsByTagName('UL')[0];
412		}
413	}
414	this._addItem = function(Text, Function) {
415		var objItem, objItem_A;
416		objItem = document.createElement('LI');
417		this.objMenu_List.appendChild(objItem);
418		
419		objItem_A = document.createElement('A');
420		objItem.appendChild(objItem_A);
421		objItem_A.href = 'java' + 'script:void(0);';
422		objItem_A.innerHTML = Text;
423		
424		switch (typeof(Function)) {
425			case 'string':
426				//addEvent(objItem_A, 'click', 'function() {' + Function + '}');
427				objItem_A.href = 'javas'+'cript:' + Function + ';';
428				break;
429			case 'function':
430				addEvent(objItem_A, 'click', Function);
431				break;
432		}
433		addEvent(objItem, 'mousemove', this._DivMenu_Show);
434		addEvent(objItem, 'mouseout', this._DivMenu_Hide);
435	}
436
437	this._DivMenu_Show = function () {
438		if (this.hideTimer) window.clearTimeout(this.hideTimer);
439		this.hideTimer = 0;
440		if (objMenu.style.display != 'block') {
441			objMenu.style.overflow = 'visible';
442			objMenu.style.width = '300px'; 
443			objMenu.style.height = 'auto';
444		}
445	}
446	this._DivMenu_Hide = function () {
447		if (!this.hideTimer) this.hideTimer = window.setTimeout('findObj(\'DivDevelopingModeMenu\')._DivMenu_Hide__timeout();', 1000);
448	}
449	this._DivMenu_Hide__timeout = function () {
450		objMenu.style.width = '5px';
451		objMenu.style.height = '5px';
452		objMenu.style.overflow = 'hidden';
453		hideTimer = 0;
454	}
455	if (window.DevelopingMode) {
456		this._initialize();
457		if (Text && Function) this._addItem(Text, Function);
458	}
459}
460
461
462// ###   getPos - Info-Data Flavio Spezi (ver. 2.0 - 03/11/2005)   ###
463// Restituisce la coordinata X o Y dell'oggetto HtmlElement.
464// Parametri:	HtmlElement :		l'oggetto di cui conoscere le coordinate.
465//				TopOrLeft :			la coordinata richiesta; se si passa TOP restituirà la coordinata Y, altrimenti X.
466// ATTENZIONE: la procedura non funziona correttamente se l'oggetto passato si trova all'interno di una tabella, la quale
467//		ha impostato l'attributo BORDER ad un valore maggiore di zero, non ha una configurazione STYLE che configura lo
468//		spessore del bordo e la cella che contiene l'oggetto non ha una configurazione STYLE che configura lo spessore
469//		del bordo. Per risolvere questo eventuale problema, impostare l'attributo POSITION dell'oggetto richiesto al
470//		valore RELATIVE oppure ABSOLUTE.
471function getPos(HtmlElement, TopOrLeft) {
472	var fReturn = 0;
473	var obj = HtmlElement;
474	var topOrLeftValue = ((TopOrLeft.substring(0, 1).toLowerCase() == 't') ? 'Top' : 'Left');
475	var styleVal;
476	//var str1 = HtmlElement.tagName;		//riattivare per fare i test
477	while (obj) {
478		styleVal = obj['offset' + topOrLeftValue];
479		if (styleVal) {
480			styleVal = toNumber(styleVal.toString(), null);
481			if (styleVal > 0) {
482				fReturn += styleVal;
483				//str1 += ' offset=' + styleVal;		//riattivare per fare i test
484			}
485		}
486		//str1 += '\n';			//riattivare per fare i test
487		obj = obj.offsetParent;
488	}
489	obj = HtmlElement.parentNode;
490	while (obj && obj.tagName != 'BODY') {
491		styleVal = GetProperty(obj, 'scroll' + topOrLeftValue);
492		if (styleVal) {
493			styleVal = toNumber(styleVal.toString(), null);
494			if (styleVal > 0) {
495				fReturn -= styleVal;
496				//str1 += ' scroll(1)=' + styleVal;		//riattivare per fare i test
497			}
498		}
499		obj = obj.parentNode;
500	}
501	//alert(str1);		//riattivare per fare i test
502	return fReturn;
503}
504
505//Dato un oggetto DOCUMENT (o un oggetto HTML da cui si determinerà il rispettivo DOCUMENT), e dato un "INFO" restituisce il rispettivo valore.
506//Informazioni disponibili (possibili valori per l'argomento NAME):
507//	'RootElement' :		restituisce l'oggetto PARENT del documento.
508//	'IsTopFrame' :		restituisce FALSE se [window] è disegnato in un FRAME, altrimenti restituisce TRUE.
509function GetDocInfo(HtmlObject, Name) {
510	var objDoc = (HtmlObject.tagName ? HtmlObject.ownerDocument : HtmlObject);
511	switch (Name) {
512		//Restituisce il primo elemento del documento, ossia quello su cui partono tutti i riferimenti di posizione
513		case 'RootElement':		return (objDoc.compatMode == 'CSS1Compat' ? objDoc.documentElement : objDoc.body);
514		//Restituisce FALSE se [window] è disegnato in un FRAME, altrimenti restituisce TRUE.
515		case 'IsTopFrame':		return !((HtmlObject.parentWindow ? HtmlObject.parentWindow : HtmlOb
515ject.defaultView).frameElement);
516		default:				return null;
517	}
518}
519
520// Converte un nome di proprietà di stile css nel formato java.  Es.: "border-color" -> "borderColor".
521// Se la proprietà è già scritta in stile Js la funzione restituisce PropertyName.
522function CPropertyJS(PropertyName) {
523	var fReturn;
524	var indice;
525	var arrayString;
526	
527	arrayString = PropertyName.split('-');
528
529	fReturn = arrayString[0];
530	for (indice = 1; indice < arrayString.length; indice++) {
531		arrayString[indice] = arrayString[indice].substr(0, 1).toUpperCase() + arrayString[indice].substr(1);
532		fReturn = fReturn.concat(arrayString[indice]);
533	}
534	return fReturn;
535}
536
537// ###   GetProperty - Info-Data Flavio Spezi (ver. 2.0 - 06/09/2007)
538// Restituisce la proprietà richiesta. Se la proprietà non viene trovata, viene restituito il valore NULL.
539// La ricerca avviene per stile e per proprietà.
540// Testata su Internet Explorer 6 e su Mozilla Firefox 2.0.
541function GetProperty(Obj, PropertyName, EmptyIsNotValid) {
542	var nome, trovato, filtro;
543	var ok, fReturn;
544	var nomeProprieta;
545	
546	ok = false;
547	if (Obj) {
548		switch (PropertyName){ 
549			case 'opacity' :
550				// se la proprietà richiesta è opacity
551				switch(GetBrowserInfo('name')){
552					case 'MSIE':
553						trovato = false;
554						for (filtro in Obj.filters) {
555							switch (filtro.toLowerCase()) {
556								case 'alpha':
557								case 'dximagetransform.microsoft.alpha' : 
558									trovato = true;
559									break;
560							}
561							if (trovato) {
562								fReturn = Obj.filters(filtro).opacity;
563								ok = true;
564								break;
565							}
566						}
567						break;
568					case 'Netscape':
569						fReturn = null;
570						if (!fReturn) fReturn = GetProperty(Obj, '-moz-opacity', true);
571						if (!fReturn) fReturn = GetProperty(Obj, 'OPACITY', true);
572						if (fReturn) {
573							fReturn = fReturn * 100;
574							ok = true;
575						}
576						break;
577					default : 
578						fReturn = null;
579						if (!fReturn) fReturn = GetProperty(Obj, 'OPACITY', true);
580						if (fReturn) {
581							fReturn = fReturn * 100;
582							ok = true;
583						}
584						break;
585				}
586				break;
587			case 'uniqueID':
588				switch(GetBrowserInfo('name')){
589					case 'MSIE':
590						fReturn = Obj.uniqueID;
591						break;
592					default:
593						//Pare che questa istruzione non funzioni, e che non esiste un "uniqueID" standard.
594						fReturn = Obj.elementId;
595						break;
596				}
597				break;
598			default :
599				nomeProprieta = CPropertyJS(PropertyName);
600				if (!ok && Obj.style) {
601					try {
602						fReturn = Obj.style[nomeProprieta];
603						ok = true;
604					} catch (e) {
605						ok = false;
606					}
607					if ((ok) && (!fReturn && fReturn!='') || (fReturn=='' && EmptyIsNotValid)) ok = false;
608				}
609				if (!ok) {
610					try {
611						fReturn = Obj[nomeProprieta];
612						ok = true;
613					} catch (e) {
614						ok = false;
615					}
616					if (ok && !fReturn && fReturn!='') ok = false;
617				}
618				if (!ok && Obj.style) {
619					try {
620						for (nome in Obj.style) {
621							if (nome.toLowerCase() == nomeProprieta.toLowerCase()) {
622								fReturn = Obj.style[nome];
623								ok = true;
624								break;
625							}
626						}
627					} catch (e) {
628						ok = false;
629					}
630					if ((ok) && (!fReturn && fReturn!='') || (fReturn=='' && EmptyIsNotValid)) ok = false;
631				}
632				if (!ok) {
633					try {
634						for (nome in Obj) {
635							if (nome.toLowerCase() == nomeProprieta.toLowerCase()) {
636								fReturn = Obj[nome];
637								ok = true;
638								break;
639							}
640						}
641					} catch (e) {
642						ok = false;
643					}
644					if ((ok) && (!fReturn && fReturn!='') || (fReturn=='' && EmptyIsNotValid)) ok = false;
645				}
646				if (!ok && Obj.attributes) {
647					try {
648						fReturn = Obj.getAttribute(nomeProprieta);
649						ok = true;
650					} catch (e) {
651						ok = false;
652					}
653					if ((ok) && (!fReturn && fReturn!='') || (fReturn=='' && EmptyIsNotValid)) ok = false;
654				}
655				if (false && !ok && Obj.currentStyle) {		//Disattivato, perchè inopportuno: esiste GetCssStyle per conoscere valori in questo modo.
656					try {
657						fReturn = Obj.currentStyle[nomeProprieta];
658						ok = true;
659					} catch (e) {
660						ok = false;
661					}
662					if ((ok) && (!fReturn && fReturn!='') || (fReturn=='' && EmptyIsNotValid)) ok = false;
663				}
664				break;
665		}
666	}
667	if (!ok) fReturn = null;
668	//alert(Obj.tagName + ': ' + PropertyName + '=' + fReturn + '; ok=' + ok);
669	return fReturn;
670}
671
672
673// ###   SetProperty - Info-Data Flavio Spezi (ver. 2.0 -27/08/2007)
674// Setta la proprietà richiesta. Restituisce TRUE se è stato sovrascritto un valore di STILE o di TAG.
675// Testata su Internet Explorer 6 e su Mozilla Firefox 2.0.
676function SetProperty(Obj, PropertyName, PropertyValue) {
677	var filtro, trovato, val1;
678	var ok, fReturn;
679	var nomeProprieta;
680	
681	fReturn = false;
682	ok = false;
683	if (Obj) {
684		switch (PropertyName) {
685			case 'opacity':
686				// il valore "opacity" deve essere da 0 a 100 ossia da trasparente a completamente opaco
687				switch (GetBrowserInfo('name')) {
688					case 'MSIE':
689						switch (GetBrowserInfo('hardwaretype')) {
690							case 'pc':
691								trovato = false;
692								for (filtro in Obj.filters) {
693									switch (filtro.toLowerCase()) {
694										case 'alpha':
695										case 'dximagetransform.microsoft.alpha':
696											trovato = true;
697											break;
698									}
699									if (trovato) break;
700								}
701								if (trovato) {
702									Obj.filters(filtro).Opacity = parseInt(PropertyValue);
703								} else {
704									Obj.style.filter += ' progid:DXImageTransform.Microsoft.Alpha(Opacity=' + parseInt(PropertyValue) + ')';
705								}
706								fReturn = true;
707								break;
708							default:
709								fReturn = true;
710								break;
711						}
712						break;
713					case 'Netscape':
714						//Si deve usare "-moz-opacity" oppure "opacity" ?...
715						//Utilizziamo "opacity" per le nuove versioni di Firefox.. 1.5 (versione ipotizzata)
716						//Si utilizzava "-moz-opacity" per le vecchie versioni di Mozilla
717						Obj.style.opacity = parseInt(PropertyValue) / 100;
718						fReturn = true;
719						break;
720					default:
721						Obj.style.opacity = parseInt(PropertyValue) / 100;
722						fReturn = true;
723				}
724				break;
725			default:
726				nomeProprieta = CPropertyJS(PropertyName);
727				if (!ok) {
728					if (Obj.style) {
729						if (Obj.style[nomeProprieta] !== undefined) {
730							Obj.style[nomeProprieta] = PropertyValue;
731							ok = true;
732						}
733					}
734					if (Obj[nomeProprieta] !== undefined) {
735						Obj[nomeProprieta] = PropertyValue;
736						ok = true;
737					}
738				}
739				if (!ok) {
740					Obj.style[nomeProprieta] = PropertyValue;
741				}
742				freturn = true;
743				break;
744		}
745	}
746	//alert(Obj.tagName + ': ' + PropertyName + '=' + fReturn + '; ok=' + ok);
747	return fReturn;
748}
749
750//Restituisce il valore CORRENTE dello stile, che sarà quello della collection STYLE se è definito, altrimenti sarà quello ereditato dai file CSS.
751function GetCssStyle(HtmlObject, StyleName) {
752    if (HtmlObject.tagName) {
753		if (HtmlObject.currentStyle) {
754			return HtmlObject.currentStyle[StyleName];
755		} else if (window.getComputedStyle) {
756			var compStyle = window.getComputedStyle(HtmlObject, '');
757			return compStyle.getPropertyValue(StyleName);
758		}
759	}
760    return null;
761}
762
763
764/*	----E' SOLO UNA IDEA, E' DA IMPLEMENTARE PER BENE---- (inizio)
765//Restituisce il nome dello stile nel browser corrente. Se [optFromBrowser] è true significa che [StyleName] è il nome usato dal browser corrente, e
766//la funzione restituirà il nome standard dello stile.
767function STDStyleName(StyleName, optFromBrowser) {
768	if (!window.STDStyleName__coll) {
769		window.STDStyleName__coll = new Array();
770		window.STDStyleName__coll['opacity'] = {'IE7':'', 'W3C':'opacity'};
771	}
772}	----E' SOLO UNA IDEA, E' DA IMPLEMENTARE PER BENE---- (fine)
773*/
774
775// Setta uno stile o un elenco di stili (formattati così come sarebbero formattati nell'attributo STYLE di un TAG)
776// ad un oggetto HTML.
777// FORSE OBSOLETA...perchè ora esiste "ObjHtml.style.cssText "
778function SetCssStyle(HtmlObject, CssStyle) {
779	var cssStyleSenzaStringhe;
780	var cont1, cont2;
781	var str1, str2;
782	
783	str1 = new String(CssStyle);
784	str1 = str1.replace(/\\\\/g, '##');		//Sostituisco la doppia barra con doppio #
785	//Sostituisco le stringhe con dei #, uno per carattere di stringa.
786	cont1 = str1.search(/['"]/g);
787	while (cont1 > -1) {
788		str2 = str1.substr(cont1, 1);
789		//Cerco la chiusura di stringa, escludendo quelle situazioni in cui il sepStringa è preceduro da uno Escape (\)
790		for (cont2 = cont1+1; cont2 < str1.length; cont2++) {
791			if (str1.substr(cont2, 1) == str2 && str1.substr(cont2-1, 1) != '\\') break;
792		}
793		str1 = str1.substr(0, cont1) + StringRepeater('#', cont2 - cont1 + 1) + str1.substr(cont2 + 1);
794		cont1 = str1.search(/['"]/g);
795	}
796	cssStyleSenzaStringhe = str1;
797	
798	//Cerco le definizioni di stile e le applico all'oggetto.
799	var re = new RegExp('([@:a-z][a-z\\-]+)\\s*:\\s*([^;]*)', 'gi');
800	var reMatch;
801	while ((reMatch = re.exec(cssStyleSenzaStringhe)) !== null) {
802		//reMatch è un array che contiene informazioni sul match corrente.
803		str1 = reMatch[1];	//reMatch[1] restituisce il nomeAttributo, che è sicuramente lo stesso valore che trovo come sottostringa di CssStyle a parità di posizione.
804		str2 = RTrim(CssStyle.substr(reMatch.index + reMatch[0].length - reMatch[2].length, reMatch[2].length));
805		SetProperty(HtmlObject, str1, str2);
806		//HtmlObject.setAttribute(str1, str2);
807		//eval('HtmlObject.style.' + str1 + ' = "' + str2 + '";');
808	}
809}
810
811
812
813/* ==== AddClassName  /  RemoveClassName  /  ContainsClassName ==== */
814//Procedure che aggiungono, tolgono e verificano la presenza di un ClassName in un oggetto.
815//L'argomento HtmlObject può essere anche il valore ClassName di un oggetto.
816
817//AddClassName: aggiunge il ClassName all'oggetto. Restituisce il nuovo valore dell'attributo.
818//Se [optFirstPosition] è TRUE mette il ClassName come primo elemento, lo lo sposta se c'era già.
819function AddClassName(HtmlObject, ClassName, optFirstPosition) {
820	var cont1, str1, vett1, trovato, fReturn;
821	//Lettura valore corrente
822	switch (ValueType(HtmlObject)) {
823		case 'string':	str1 = HtmlObject; break;
824		case 'Object':	str1 = HtmlObject.className; break;
825	}
826	if (!str1) {
827		fReturn = ClassName;
828	} else {
829		vett1 = str1.split(' ');
830		trovato = false;
831		fReturn = '';
832		for (cont1=0; cont1 < vett1.length; cont1++) {
833			if (vett1[cont1] == ClassName) {
834				if (!optFirstPosition || cont1 == 0) {
835					fReturn += ' ' + ClassName;
836					trovato = true;
837				}
838			} else {
839				fReturn += ' ' + vett1[cont1];
840			}
841		}
842		if (trovato) {
843			fReturn = fReturn.substr(1);
844		} else {
845			if (optFirstPosition) {
846				fReturn = ClassName + fReturn;
847			} else {
848				fReturn = fReturn.substr(1) + ' ' + ClassName;
849			}
850		}
851	}
852	//Scrittura valore nell'oggetto HTML
853	switch (ValueType(HtmlObject)) {
854		case 'Object':	HtmlObject.className = fReturn; break;
855	}
856	return fReturn;
857}
858//RemoveClassName: rimuove il ClassName dall'oggetto. Restituisce il nuovo valore dell'attributo.
859function RemoveClassName(HtmlObject, ClassName) {
860	var cont1, str1, vett1, trovato, fReturn;
861	//Lettura valore corrente
862	switch (ValueType(HtmlObject)) {
863		case 'string':	str1 = HtmlObject; break;
864		case 'Object':	str1 = HtmlObject.className; break;
865	}
866	if (!str1) {
867		fReturn = '';
868	} else {
869		vett1 = str1.split(' ');
870		trovato = false;
871		fReturn = '';
872		for (cont1=0; cont1 < vett1.length; cont1++) {
873			if (vett1[cont1] == ClassName) {
874				trovato = true;
875			} else {
876				fReturn += ' ' + vett1[cont1];
877			}
878		}
879		if (fReturn) fReturn = fReturn.substr(1);
880	}
881	//Scrittura valore nell'oggetto HTML
882	switch (ValueType(HtmlObject)) {
883		case 'Object':	HtmlObject.className = fReturn; break;
884	}
885	return fReturn;
886}
887//SetClassName: esegue [AddClassName] se l'argomento [Add] è True, oppure [RemoveClassName] se l'argomento [Add] è False.
888function SetClassName(HtmlObject, ClassName, Add, optFirstPosition) {
889	if (Add) {
890		return AddClassName(HtmlObject, ClassName, optFirstPosition);
891	} else {
892		return RemoveClassName(HtmlObject, ClassName);
893	}
894}
895//ContainsClassName: restituisce TRUE se viene trovato il ClassName indicato nell'omonimo attributi dell'oggetto.
896function ContainsClassName(HtmlObject, ClassName) {
897	var cont1, str1, vett1, trovato, fReturn;
898	//Lettura valore corrente
899	switch (ValueType(HtmlObject)) {
900		case 'string':	str1 = HtmlObject; break;
901		case 'Object':	str1 = HtmlObject.className; break;
902	}
903	if (!str1) {
904		fReturn = false;
905	} else {
906		vett1 = str1.split(' ');
907		trovato = false;
908		for (cont1=0; cont1 < vett1.length; cont1++) {
909			if (vett1[cont1].toLowerCase() == ClassName.toLowerCase()) {
910				trovato = true;
911				break;
912			}
913		}
914		fReturn = trovato;
915	}
916	return fReturn;
917}
918
919
920/* ==== COOKIE ==== */
921// NOTE: un Cookie creato dal browser è leggibile ma non modificabile dal server, e viceversa. Se entrambi scrivono un Cookie con medesimo nome
922// succede che ci troveremo entrambi i Cookie. Quando si leggeranno i valori, il server leggerà il primo che incontra. Mentre il browser, non
923// fornendo procedure per leggere i singoli valori, posso ottenere ciò che voglio.
924// Per non trovarmi a dover scegliere quale valore leggere (se quello scritto dal client o dal server) nego la possibilità di scrittura di un
925// cookie se questo è già stato scritto dal suo antagonista.
926function GetCookie(Name) {
927	var re = new RegExp('([;][ ])?([^=]+)=([^;]*)', 'g');
928	var reMatch;
929	while ((reMatch = re.exec(document.cookie)) !== null) {
930		if (CStrByAscii(reMatch[2]) == Name) return DeserializeValue(CStrByAscii(reMatch[3].substr(1)));
931	}
932	return null;
933}
934function GetCookieOwner(Name) {
935	//Restituisce "S", "C" o NULL in caso che il Cookie sia di proprietà del SERVER, CLIENT o se non esiste.
936	//Restituisce "n" se il Cookie non è stato creato dalle procedure [SetCookie].
937	//Attensione: per sapere se un Cookie è di proprietà di uno o l'altro, si deve leggere il primo catarrete, che puo essere "S" o "C". Quindi
938	//questo meccanismo non garantisce in maniera assoluta se un Cookie è di una certa proprietà o se è stato creato con altre procedure e
939	//casualmente il suo contenuto inizia con una di quelle lettere.
940	var re = new RegExp('([;][ ])?([^=]+)=([^;]*)', 'g');
941	var reMatch;
942	while ((reMatch = re.exec(document.cookie)) !== null) {
943		if (CStrByAscii(reMatch[2]) == Name) {
944			return (('SC'.indexOf(reMatch[3].charAt(0)) > -1) ? reMatch[3].charAt(0) : 'n');
945		}
946	}
947	return null;
948}
949function SetCookie(Name, Value, Expire) {
950	//ATTENZIONE: questa funzione è autorizzata a scrivere Cookie solo se esso non è stato già creato dal server.
951	switch (IfNull(GetCookieOwner(Name), 'C')) {
952		case 'C':	//Cookie creato dal client o non esistente, autorizzazione concessa.
953			var scadenza, percorso;
954			switch (ValueType(Expire)) {
955				case 'null':		//il cookie scadrà con lo scadere della sessione
956					scadenza = '';	//new Date(); scadenza.setTime(scadenza.getTime() - 24 * 3600 * 1000 * 100);
957					break;
958				case 'Date':		//data esatta
959					scadenza = Expire;
960					break;
961				case 'number':		//numero di giorni a partire da oggi
962					scadenza = new Date();
963					scadenza.setTime(scadenza.getTime() + 24 * 3600 * 1000 * Expire);
964					break;
965				default:			//fra 3 mesi
966					scadenza = new Date();
967					scadenza.setMonth(scadenza.getMonth() + 3);
968					break;
969			}
970			if (ValueType(scadenza) == 'Date') scadenza = scadenza.toGMTString();
971			document.cookie = CStrAscii(Name) + '=C' + CStrAscii(SerializeValue(Value)) + '; path=/;' + (scadenza ? ' expires='+scadenza+';' : '');
972			return true;
973		default:	//Cookie creato dal server o provenienza sconosciuta, autorizzazione negata.
974			return false;
975	}
976}
977function DelCookie(Name) {
978	SetCookie(Name, '', -1);
979}
980function IsCookieEnabled() {
981	var fReturn = true;
982	if (fReturn) fReturn = SetCookie('testCookie', 'test', null);
983	if (fReturn) fReturn = (GetCookie('testCookie') == 'test');
984	return fReturn;
985}
986
987
988
989// ##	STD Event - Info-Data Flavio Spezi (ver. 1.0 - 24/11/2006)
990// Interfaccia per oggetto Event. Istanziando questo oggetto, il primo argomento di un handler di evento, la classe restituisce le
991// proprietà in stile IE. (info prese su http://www.javascriptkit.com/domref/domevent.shtml#e2)
992// "STD" sta per "Standard".
993function STDEvent(EventObjectByArgument) {
994	//Preparazione variabili e setting variabili principali
995	this.objectType = 'STDEvent';
996	this._ie = (window.event ? true : false);
997	this.eventObj;
998	this.altKey;	this.ctrlKey;	this.shiftKey;		this.button;
999	this.clientX;	this.clientY;	this.fromElement;	this.toElement;
1000	this.keyCode;	this.offsetX;	this.offsetY;		this.srcElement;
1001	this.type;
1002	
1003	this._initialize = function (EventObjectByArgument) {
1004		var fatto, fReturn;
1005		//Se l'argomento [EventObjectByArgument] è già un oggetto di tipo [STDEvent] allora lo restituisco senza fare altro.
1006		fatto = false;
1007		if (ValueType(EventObjectByArgument) == 'Object') {
1008			if (EventObjectByArgument.objectType == 'STDEvent') {
1009				fReturn = EventObjectByArgument;
1010				fatto = true;
1011			}
1012		}
1013		if (!fatto) {
1014			this._settingVariabili(EventObjectByArgument);
1015			fReturn = this;
1016		}
1017		return fReturn;
1018	}
1019	this._settingVariabili = function (EventObjectByArgument) {
1020		this.eventObj = (this._ie ? window.event : EventObjectByArgument);
1021		this.altKey = this.eventObj.altKey;
1022		this.ctrlKey = this.eventObj.ctrlKey;
1023		this.shiftKey = this.eventObj.shiftKey;
1024		if (this._ie) {
1025			this.button = this.eventObj.button;
1026		} else {
1027			switch (this.eventObj.button) {
1028				case 0: this.button = 1; break;
1029				case 2: this.button = 2; break;
1030				case 1: this.button = 4; break;
1031				default: this.button = 0;
1032			}
1033		}
1034		this.clientX = this.eventObj.clientX;
1035		this.clientY = this.eventObj.clientY;
1036		this.fromElement = this._scegliGiusto(this.eventObj.fromElement, this.eventObj.relatedElement);
1037		this.toElement = this._scegliGiusto(this.eventObj.toElement, this.eventObj.relatedElement);
1038		this.keyCode = (this.eventObj.keyCode ? this.eventObj.keyCode : this.eventObj.charCode);
1039		this.offsetX = this._scegliGiusto(this.eventObj.offsetX, this.eventObj.layerX);
1040		this.offsetY = this._scegliGiusto(this.eventObj.offsetY, this.eventObj.layerY);
1041		//this.srcElement = this._scegliGiusto(this.eventObj.srcElement, this.eventObj.target);		pare che non sia [target] ma [currentTarget]
1042		this.srcElement = this._scegliGiusto(this.eventObj.srcElement, this.eventObj.currentTarget);
1043		this.type = this.eventObj.type;
1044	}
1045	this._scegliGiusto = function (perIE, perAltri) {
1046		if (this._ie) {
1047			return perIE;
1048		} else {
1049			return perAltri;
1050		}
1051	}
1052	/*
1053	this.altKey = function () { return this.eventObj.altKey; }
1054	this.ctrlKey = function () { return this.eventObj.ctrlKey; }
1055	this.shiftKey = function () { return this.eventObj.shiftKey; }
1056	this.button = function () {
1057		if (this._ie) {
1058			return this.eventObj.button;
1059		} else {
1060			switch (this.eventObj.button) {
1061				case 0: return 1; break;
1062				case 2: return 2; break;
1063				case 1: return 4; break;
1064				default: return 0;
1065			}
1066		}
1067	}
1068	
1069	//Proprietà
1070	this.clientX = function () { return this.eventObj.clientX; }
1071	this.clientY = function () { return this.eventObj.clientY; }
1072	this.fromElement = function () { return this._scegliGiusto(this.eventObj.fromElement, this.eventObj.relatedElement); }
1073	this.toElement = function () { return this._scegliGiusto(this.eventObj.toElement, this.eventObj.relatedElement); }
1074	this.keyCode = function () { return this._scegliGiusto(this.eventObj.keyCode, this.eventObj.charCode); }
1075	this.offsetX = function () { return this._scegliGiusto(this.eventObj.offsetX, this.eventObj.layerX); }
1076	this.offsetY = function () { return this._scegliGiusto(this.eventObj.offsetY, this.eventObj.layerY); }
1077	this.srcElement = function () { return this._scegliGiusto(this.eventObj.srcElement, this.eventObj.target); }
1078	this.type = function () { return this.eventObj.type; }
1079	*/
1080	//Metodi
1081	this.cancelBubble = function(Valore) {
1082		if (this._ie) {
1083			this.eventObj.cancelBubble = ((Valore)? true : false);
1084		} else {
1085			this.eventObj.stopPropagation((Valore)? true : false);
1086		}
1087	}
1088	this.returnValue = function(Valore) {
1089		if (this._ie) {
1090			this.eventObj.returnValue = ((Valore)? true : false);
1091		} else {
1092			this.eventObj.preventDefault((Valore)? false : true);
1093		}
1094	}
1095	
1096	return this._initialize(EventObjectByArgument);
1097}
1098
1099
1100
1101// ###   toNumber - Info-Data Flavio Spezi (ver. 2.0 - 03/11/2005)   ###
1102// Restituisce il numero dalla forma string alla forma numerica
1103// Parametri:	NumericString :		il numero da restituire.
1104//				ReturnIfInvalid :	se il numero indicato è errato, verrà restituito questo valore.
1105//				AnyError :			se TRUE, la procedura restituirà ReturnIfInvalid per qualsiasie errore;
1106//									se FALSE (default) restituisce la parte numerica valida.
1107function toNumber(NumericString, ReturnIfInvalid, AnyError) {
1108	// Costanti di programmazione
1109	var numeriValidi = '0123456789', segniValidi = '+-', sepDecimaliValidi = '.,';
1110	// Variabili di programmazione
1111	var strNumero, strCifra;
1112	var segno = '+', intero = '', decimale = '';
1113	var trovatoSegno = false, trovatoDecimale = false, err = 0;
1114	var i, fReturn;
1115
1116	if (typeof(NumericString) == 'number') {
1117		fReturn = NumericString;
1118	} else if (!NumericString || NumericString == '') {
1119		fReturn = ReturnIfInvalid;
1120	} else {
1121		strNumero = '';
1122		try {
1123			strNumero = NumericString.toString();
1124		} catch(e) {
1125		}
1126		strCifra = strNumero.charAt(0);
1127		if (segniValidi.indexOf(strCifra) > -1) {
1128			segno = strCifra;
1129			trovatoSegno = true;
1130		}
1131		for (i = ((trovatoSegno)? 1 : 0); i < strNumero.length; i++) {
1132			strCifra = strNumero.charAt(i);
1133			if (numeriValidi.indexOf(strCifra) > -1) {
1134				if (!trovatoDecimale) {
1135					intero += strCifra;
1136				} else {
1137					decimale += strCifra;
1138				}
1139			} else if ((!trovatoDecimale) && (sepDecimaliValidi.indexOf(strCifra) > -1)) {
1140				trovatoDecimale = true;
1141			} else {
1142				err = 1;	//troppi separatori o carattere non riconosciuto
1143				break;
1144			}
1145		}
1146		if ((intero != '' || decimale != '') && (err == 0 || !AnyError)) {
1147			if (intero == '') intero = '0';
1148			if (decimale == '') decimale = '0';
1149			fReturn = (new Number(segno + intero + '.' + decimale)).valueOf();
1150		} else {
1151			fReturn = ReturnIfInvalid;
1152		}
1153	}
1154	return fReturn;
1155}
1156
1157
1158function IsNull(Value) {
1159	return ((Value === null || Value === void(0)) ? true : false);
1160}
1161
1162function IfNull(Value, ValueIfNull) {
1163	if (IsNull(Value)) {
1164		return ValueIfNull;
1165	} else {
1166		return Value;
1167	}
1168}
1169function NullIf(Value, NullValue) {
1170	if (Value == NullValue || Value === NullValue) {
1171		return null;
1172	} else {
1173		return Value;
1174	}
1175}
1176
1177function CNum(NumericString) {
1178	return toNumber(NumericString, null, true);
1179}
1180function CStrXML(Value) {
1181	return CStrXml(Value);
1182}
1183function CStrXml(Value) {
1184	var fReturn;
1185	if (Value === null || Value === void(0)) {
1186		fReturn = Value;
1187	} else {
1188		fReturn = HTMLEncode(Value);
1189	}
1190	return fReturn;
1191}
1192function CNumHTML(Value, Decimals) {
1193	//Restituisce il numero in formato stringa arrotondato al numero di cifre indicate
1194	var fReturn;
1195	fReturn = CNum(Value);
1196	if (fReturn === null || fReturn === void(0)) {
1197		fReturn = Value;
1198	} else {
1199		fReturn = Value.toFixed(Decimals);
1200	}
1201	return fReturn;
1202}
1203function CNumHtml(Value, Decimals) {
1204	return CNumHTML(Value, Decimals);
1205}
1206function CCurHTML(Value, Decimals) {
1207	//Restituisce il numero in formato stringa, arrotondato al numero di cifre indicate e con il separatore delle migliaia
1208	//Attezione: procedura da implementare.
1209	return CNumHTML(Value, Decimals);
1210}
1211function CCurHtml(Value, Decimals) {
1212	return CNumHTML(Value, Decimals);
1213}
1214function CStrHTML(Value) {
1215	return CStrHtml(Value);
1216}
1217function CStrHtml(Value) {
1218	var fReturn;
1219	if (Value === null || Value === void(0)) {
1220		fReturn = Value;
1221	} else {
1222		fReturn = HTMLEncode(Value);
1223		if (fReturn) fReturn = fReturn.replace(/\x20\x20/g, '&nbsp;');
1224		if (fReturn) fReturn = fReturn.replace(/\x0d\x0a/g, '<br/>');
1225		if (fReturn) fReturn = fReturn.replace(/(\x0d|\x0a)/g, '<br/>');
1226	}
1227	return fReturn;
1228}
1229
1230function CStrJS(Value, AddDelimeters) {
1231	if (Value === null || Value === void(0)) {
1232		return (AddDelimeters ? 'null' : null);
1233	} else {
1234		return (AddDelimeters ? '\'' : '') + escape(Value).replace(/%/g, '\\x') + (AddDelimeters ? '\'' : '');
1235	}
1236}
1237function CNumJS(Value) {
1238	if (Value === null || Value === void(0)) {
1239		return 'null';
1240	} else {
1241		return Value.toString().replace(/,/g, '.');
1242	}
1243}
1244function CStrRE(Value) {
1245	//Sostituisce i caratteri escape del parametro [PatternString] con la corretta codifica per un pattern RegExp.
1246	//Es.  "Come stai? Bene, grazie."  ->  "Come stai\? Bene, grazie\."
1247	var re, reMatch, precPos, fReturn;
1248	re = new RegExp('[\\.\\$\\^\\{\\[\\(\\|\\)\\*\\+\\?\\\\]', 'g');
1249	precPos = 0;
1250	fReturn = '';
1251	while ((reMatch = re.exec(Value)) !== null) {
1252		fReturn += Value.substr(precPos, reMatch.index - precPos) + '\\' + reMatch[0];
1253		precPos = reMatch.index + 1;
1254	}
1255	fReturn += Value.substr(precPos);
1256	return fReturn;	
1257}
1258
1259function CStrUrlParam(Testo) {
1260      //Converte l'argomento [Testo] in una stringa adatta per essere passata come "valore di parametro" di un percorso URL.
1261      //Per esempio, la stringa "Cip & ciop" viene convertita in: "Cip%20%26%20ciop".
1262      var fReturn = Testo;
1263      fReturn = encodeURIComponent(Testo);
1264      /*
1265      fReturn = fReturn.replace(/\x26/g, '%26');                       //"&"
1266      fReturn = fReturn.replace(/\x23/g, '%23');                       //"="
1267      fReturn = fReturn.replace(/\x25/g, '%25');                       //"%"
1268      fReturn = fReturn.replace(/\+/g, '%2B');							//"+"
1269      fReturn = fReturn.replace(/\x23/g, '%23');                       //"#"
1270      fReturn = fReturn.replace(/\x0D/g, '%0D');                       //vbCr
1271      fReturn = fReturn.replace(/\x0A/g, '%0A');                       //vbLf
1272      */
1273      return fReturn;
1274}
1275function CStrAscii(Value) {
1276	//NOTA: La funzione [escape] converte tutti i caratteri speciali nel rispettivo valore in forma "%hh", ad eccezione di questi: "@*/+".
1277	//		Questa è la lista dei caratteri riconosciuti come speciali: " ~!@#$%^&*(){}[]=:/,;?+'""\"
1278	var fReturn = escape(Value);
1279	fReturn = fReturn.replace(/\x40/g, '%40');	//Conversione "@"
1280	fReturn = fReturn.replace(/\x2A/g, '%2A');	//Conversione "*"
1281	fReturn = fReturn.replace(/\x2F/g, '%2F');	//Conversione "/"
1282	fReturn = fReturn.replace(/\x2B/g, '%2B');	//Conversione "+"
1283	fReturn = fReturn.replace(/\x2D/g, '%2D');	//Conversione "-"
1284	fReturn = fReturn.replace(/\x2E/g, '%2E');	//Conversione "."
1285	//fReturn = fReturn.replace(/\x2D/g, '%2D');	//Conversione "-"
1286	//fReturn = fReturn.replace(/%20/g, '+');		//Ripristino " " in "+"
1287	return fReturn;
1288}
1289function CStrByAscii(Value) {
1290	var fReturn = unescape(Value);
1291	fReturn = fReturn.replace(/\x2B/g, ' ');	//Conversione "+" in " "
1292	return fReturn;
1293}
1294
1295function GetValue(Value) {
1296	//Dato un valore numerico con unità di misura, restituisce le due componenti separatamente. La stringa [Value] può essere formata così:
1297	//		"<numero><um>", "<numero> <um>", "<um><numero>", "<um> <numero>", "<numero>"
1298	//Il separatore decimale può essere: ".", ",".
1299	var re, reMatch, strReNum, strReUm, strReSep;
1300	var fReturn = {source:null, number:null, um:null};
1301	fReturn.source = Value;
1302	strReNum = '([0-9]*[\\.,][0-9]+|[0-9]+[\\.,]|[0-9]+)';
1303	strReUm = '([a-z]{1,4}|[%€\\$£#])';
1304	strReSep = '\\s*'
1305	re = new RegExp('^(' + strReNum + strReSep + strReUm + '|' + strReUm + strReSep + strReNum + '|' + strReNum + ')$', 'i');
1306	reMatch = re.exec(fReturn.source);
1307	if (reMatch) {
1308		if (reMatch[2]) {
1309			fReturn.number = toNumber(reMatch[2]);
1310			fReturn.um = reMatch[3];
1311		} else if (reMatch[4]) {
1312			fReturn.number = toNumber(reMatch[5]);
1313			fReturn.um = reMatch[4];
1314		} else if (reMatch[6]) {
1315			fReturn.number = toNumber(reMatch[6]);
1316			fReturn.um = null;
1317		}
1318	}
1319	return fReturn;
1320}
1321
1322function GetUID() {
1323	var cont1, valPrec, fReturn;
1324	fReturn = (new Date()).CDateHtml('yyyymmddhhnnss');
1325	cont1 = 0;
1326	valPrec = GetLastUID();
1327	if (valPrec !== null) {
1328		if (fReturn == valPrec.substr(0, fReturn.length)) {
1329			cont1 = CNum(valPrec.substr(fReturn.length)) + 1;
1330		}
1331	}
1332	fReturn += LFill(cont1.toString(), '0', 3);
1333	SetCookie('JS.GetLastUID', fReturn, 1);
1334	return fReturn;
1335}
1336function GetLastUID() {
1337	var fReturn;
1338	fReturn = GetCookie('JS.GetLastUID');
1339	return fReturn;
1340}
1341
1342
1343function StringToUrl(Testo) {      //## OBSOLETA ##
1344
1345      //Converte l'argomento [Testo] in una stringa adatta per essere usata come "argomenti" di un percorso URL.
1346      //Per esempio, la stringa "param1=Cip & ciop&param2=x = y - z" viene convertito in: "param1=Cip%20&%20ciop&param2=x%20=%20y%20-%20z".
1347      //ATTENZIONE: se i valori di parametro contengono caratteri come "&" questi non vengono convertiti. Quindi è preferibile NON UTILIZZARE
1348      //QUESTA PROCEDURA.
1349      var fReturn = Testo;
1350      fReturn = encodeURI(Testo);
1351      /*
1352      fReturn = fReturn.replace(/\x25/g, '%25');                        //"%"
1353      fReturn = fReturn.replace(/\x26/g, '%26');                        //"&"
1354      fReturn = fReturn.replace(/\+/g,   '%2B');						//"+"
1355      fReturn = fReturn.replace(/\x23/g, '%23');                        //"#"
1356      fReturn = fReturn.replace(/\x0D/g, '%0D');                        //vbCr
1357      fReturn = fReturn.replace(/\x0A/g, '%0A');                        //vbLf
1358      */
1359      fReturn = fReturn.replace(/\[Dialog_SepParam\]/g, '&');    //ripristino "&"
1360      return fReturn;
1361}
1362
1363
1364function LTrim(Stringa, optChars) {
1365	var str1 = Stringa.toString();
1366	var chr = (optChars) ? optChars : ' ';
1367	var cont1 = 0, limite = str1.length;
1368	if (limite > -1 ){
1369		while(chr.indexOf(str1.charAt(cont1)) > -1) {cont1++; if (cont1>=limite) break;}
1370		return str1.substr(cont1);
1371	} else {
1372		return str1;
1373	}
1374}
1375function RTrim(Stringa, optChars) {
1376	var str1 = Stringa.toString();
1377	var chr = (optChars) ? optChars : ' ';
1378	var cont1 = str1.length - 1, limite = -1;
1379	if (cont1 > -1 ){
1380		while(chr.indexOf(str1.charAt(cont1)) > -1) {cont1--; if (cont1<=limite) break;}
1381		return str1.substr(0, cont1 + 1);
1382	} else {
1383		return str1;
1384	}
1385}
1386function Trim(Stringa, optChars) {
1387	var str1 = Stringa.toString();
1388	var chr = (optChars) ? optChars : ' ';
1389	var cont1 = 0, cont2 = str1.length - 1;
1390	if (cont2 > -1 ){
1391		while(chr.indexOf(str1.charAt(cont1)) > -1) {cont1++; if (cont1>=cont2) break;}
1392		while(chr.indexOf(str1.charAt(cont2)) > -1) {cont2--; if (cont2<=cont1) break;}
1393		return str1.substr(cont1, cont2 - cont1 + 1);
1394	} else {
1395		return str1;
1396	}
1397}
1398
1399function LFill(Testo, Carattere, Lunghezza) {
1400	//Aggiunge [Carattere] a sinistra di [Testo] fino ad arrivare a [Lunghezza].
1401	//Se la lunghezza di [Testo] è maggiore di [Lunghezza], allora restituisce [Testo] senza variazioni.
1402	var fReturn, k, cont1;
1403	
1404	fReturn = '';
1405	k = Testo.length;
1406	if (k > Lunghezza) {
1407		fReturn = Testo;
1408	}else{
1409		cont1 = 0;
1410		while (cont1 < Lunghezza - k){
1411			fReturn += Carattere;
1412			cont1 += 1;
1413		}
1414		fReturn += Testo;
1415	}
1416	return fReturn;
1417}
1418function RFill(Testo, Carattere, Lunghezza) {
1419	//Aggiunge [Carattere] a destra di [Testo] fino ad arrivare a [Lunghezza].
1420	//Se la lunghezza di [Testo] è maggiore di [Lunghezza], allora restituisce [Testo] senza variazioni.
1421	var fReturn, k, cont1;
1422	
1423	fReturn = '';
1424	k = Testo.length;
1425	if (k > Lunghezza) {
1426		fReturn = Testo;
1427	}else{
1428		cont1 = 0;
1429		fReturn += Testo;		
1430		while (cont1 < Lunghezza - k){
1431			fReturn += Carattere;
1432			cont1 += 1;
1433		}
1434	}
1435	return fReturn;
1436}
1437
1438function StringRepeater(strInput, intCount) {
1439	var arrTmp = new Array(intCount + 1);
1440	return arrTmp.join(strInput);
1441}
1442
1443function ReplaceArgList(Text, ArgumentList) {
1444	/*	Restituisce il [Text] indicato sostituendo gli argomenti presenti nel testo. Questi sono indicati in stile .NET.
1445		Esempi:  "Ciao {0}", "Ciao {0}, ti saluta {1}.", "Ciao {0}, ti saluta {1}. Scritto da {2} per {0}."
1446		Argomenti:
1447			Text :			testo da compilare; i segnaposti saranno indicati con questo formato: {<num.arg.base 0>}; per restituire "{" usare "{{";
1448							per restituire "}" usare "}}".
1449			ArgumentList :	lista degli argomenti; verranno sostituiti ai segnaposti in base alla posizione dell'elemento nell'array.
1450		Nota: se l'array non contiene l'argomento voluto dal segnaposto, questo non verrà sostituito.
1451		-- procedura convertita da quella di "Funzioni.asp" --
1452	*/
1453	var re, reMatch, reMatchPrec;
1454	var fReturn, cont1, noMatches;
1455	re = /(\{\{|}}|\{[0-9]+})/g;
1456	noMatches = true;
1457	fReturn = '';
1458	reMatchPrec = null;
1459	while ((reMatch = re.exec(Text)) !== null) {
1460		noMatches = false;
1461		if (reMatchPrec === null) {
1462			fReturn = Text.substr(0, reMatch.index);
1463		} else {
1464			cont1 = reMatchPrec.index + reMatchPrec[0].length;		//posizione dell'ultimo carattere del match precedente (base 1)
1465			fReturn += Text.substr(cont1, reMatch.index - cont1);
1466		}
1467		switch (reMatch[0]) {
1468			case '{{':
1469				fReturn += '{';
1470				break;
1471			case '}}':
1472				fReturn += '}';
1473				break;
1474			default:
1475				cont1 = CNum(reMatch[0].substr(1, reMatch[0].length - 2));
1476				if (cont1 === null) cont1 = -1;
1477				if (cont1 < 0 || cont1 >= ArgumentList.length) {
1478					fReturn += reMatch[0];
1479				} else {
1480					fReturn += ArgumentList[cont1];
1481				}
1482				break;
1483		}
1484		reMatchPrec = reMatch;
1485	}
1486	if (!noMatches) {
1487		cont1 = reMatchPrec.index + reMatchPrec[0].length;		//posizione dell'ultimo carattere del match precedente (base 1)
1488		fReturn += Text.substr(cont1);
1489	} else {
1490		fReturn = Text;
1491	}
1492	return fReturn;
1493}
1494function ReplaceArgDict(Text, ArgumentDictionary, optO_TextArguments) {
1495	var re, reMatch, noMatches;
1496	var gruppoCurr, gruppoPrec;
1497	var posizCurr, posizPrec;
1498	var argList, argInText;
1499	var cont1;
1500	var fReturn;
1501	re = /(\{([^\x00-\x1f\{}]+)})/g;
1502	noMatches = true;
1503	fReturn = '';
1504	posizPrec = -1;
1505	argList = new Array();		//argomenti da passare a [ReplaceArgList]
1506	argInText = (ValueType(optO_TextArguments) == 'Array' ? optO_TextArguments : new Array());	//argomenti trovati nella stringa [Text]
1507	while ((reMatch = re.exec(Text)) !== null) {
1508		noMatches = false;
1509		gruppoCurr = reMatch[2];				//restituisce il solo nome del gruppo
1510		if (IsNull(InArray(argInText, gruppoCurr))) argInText.push(gruppoCurr);
1511		posizCurr = reMatch.index + 1;			//aggiungo 1 perchè devo scavalcare il primo carattere, aperta graffa "{".
1512		//Accodo il testo al di fuori del gruppo, tra il gruppo precedente e quello corrente
1513		if (posizPrec == -1) {
1514			fReturn = Text.substr(0, posizCurr);
1515		} else {
1516			cont1 = posizPrec + gruppoPrec.length;		//posizione dell'ultimo carattere del match precedente (base 1)
1517			fReturn += Text.substr(cont1, posizCurr - cont1);
1518		}
1519		//Eseguo la sostituzione <nome> -> <indice>
1520		if (IsUndefined(ArgumentDictionary[gruppoCurr])) {
1521			fReturn += gruppoCurr;
1522		} else {
1523			argList.push(ArgumentDictionary[gruppoCurr]);
1524			cont1 = argList.length - 1;
1525			fReturn += cont1.toString();
1526		}
1527		//Mi tengo il Gruppo corrente da una parte
1528		gruppoPrec = gruppoCurr;
1529		posizPrec = posizCurr;
1530	}
1531	if (!noMatches) {
1532		cont1 = posizPrec + gruppoPrec.length;		//posizione dell'ultimo carattere del match precedente (base 1)
1533		fReturn += Text.substr(cont1);
1534	} else {
1535		fReturn = Text;
1536	}
1537	//if (ValueType(optO_TextArguments) == 'Array') optO_TextArguments.push(argInText);
1538	return ReplaceArgList(fReturn, argList);
1539}
1540
1541
1542function IsTrue(Value) {
1543	var str1;
1544	if (ValueType(Value) == 'undefined') str1 = ''; else str1 = Value.toString().toLowerCase();
1545	switch (str1) {
1546		case 't': case 'true':
1547		case 'v': case 'vero':
1548		case 'y': case 'yes':
1549		case 's': case 'si': case 'sì':
1550		case 'on':
1551		case '1': case '-1':
1552			return true;
1553		default:
1554			return false;
1555	}
1556}
1557function IsFalse(Value) {
1558	var str1;
1559	if (ValueType(Value) == 'undefined') str1 = ''; else str1 = Value.toString().toLowerCase();
1560	switch (str1) {
1561		case 'f': case 'false': case 'falso':
1562		case 'n': case 'no':
1563		case 'off':
1564		case '0':
1565			return true;
1566		default:
1567			return false;
1568	}
1569}
1570function IsUndefined(Value) {
1571	return (Value === void(0));
1572}
1573
1574
1575function CDate(DateString, optFormat) {
1576	var strFormato = optFormat;
1577	var cont1, cont2, str1;
1578	var fReturn = null;
1579	
1580	var creaPattern = function (StrFormato) {
1581		var pattern = '';
1582		var posiz = new Array();
1583		var subPts = {YEAR:'(\\d{1,4})', NUM:'(\\d{1,2})', sepd:'[/\\-]', sept:'[:\\.]', sep:'[ ]+', TMP:'[ ]?(am|pm|a|p)'};
1584		for (var cont1 = 0; cont1 < StrFormato.length; cont1++) {
1585			switch (StrFormato.charAt(cont1)) {
1586				case 'y':	pattern += subPts.YEAR;	posiz.push('y');	break;
1587				case 'm':	pattern += subPts.NUM;	posiz.push('m');	break;
1588				case 'd':	pattern += subPts.NUM;	posiz.push('d');	break;
1589				case 'h':	pattern += subPts.NUM;	posiz.push('h');	break;
1590				case 'n':	pattern += subPts.NUM;	posiz.push('n');	break;
1591				case 's':	pattern += subPts.NUM;	posiz.push('s');	break;
1592				case 't':	pattern += subPts.TMP;	posiz.push('t');	break;
1593				case '/':	pattern += subPts.sepd;	break;
1594				case '.':	pattern += subPts.sept;	break;
1595				case ' ':	pattern += subPts.sep;	break;
1596				case '\\':	pattern += '[' + StrFormato.charAt(cont1+1) + ']';	cont1++; break;
1597			}
1598		}
1599		return {'pattern':pattern, 'posiz':posiz};
1600	}
1601	
1602	switch (ValueType(DateString)) {
1603		case 'Date':
1604			fReturn = DateString;
1605			break;
1606		case 'string':
1607			//Ottengo grossomodo la stringa di formato
1608			if (strFormato) strFormato = strFormato.toLowerCase();
1609			if (!strFormato) strFormato = '';
1610			/* switch (strFormato) {
1611				case '':
1612				case 'date':		strFormato = 'd/m/y';			break;
1613				case 'time':		strFormato = 'h.n.s';			break;
1614				case 'datetime':	strFormato = 'd/m/y h.n.s';		break;
1615				case 'iso':			strFormato = 'y-m-d\\Th.n.s';	break;
1616			}	*/
1617			switch (strFormato) {
1618				case '':
1619				case 'date':		strFormato = CDateHtml_GetFormat(1, 1, 1, 0, 0, 0); break;
1620				case 'time':		strFormato = CDateHtml_GetFormat(0, 0, 0, 1, 1, 1); break;
1621				case 'datetime':	strFormato = CDateHtml_GetFormat(1, 1, 1, 1, 1, 1); break;
1622				case 'iso':			strFormato = 'y-m-d\\Th.n.s';	break;
1623			}
1624			//Standardizzo la stringa di formato
1625			str1 = 'ymdhnst ';
1626			for (cont1 = 0; cont1 < str1.length; cont1++) {
1627				strFormato = strFormato.replace(new RegExp('[' + str1.charAt(cont1) + ']', 'gi'), str1.charAt(cont1));
1628			}
1629			strFormato = strFormato.replace(/[/\-]+/g, '/');
1630			strFormato = strFormato.replace(/[:\.]+/g, '.');
1631			//Converto la stringa di formato in regularExpression
1632			var ricercheColl = new Array();
1633			var rePattern, rePattern_Pos;
1634			switch (strFormato) {
1635				case 'd/m/y':	case 'd/m/y h.n':	case 'd/m/y h.n.s':
1636					for (cont1 = 0; cont1 < Math.pow(2, 3); cont1++) {
1637						str1 = 'd/m/y h.n.st';
1638						if (cont1 % 2 > 0) str1 = str1.replace('/y', '');
1639						if (cont1 % 4 > 0) str1 = str1.replace('t', '');
1640						if (cont1 % 8 >
1640 0) str1 = str1.replace('.s', '');
1641						str1 = Trim(str1);
1642						ricercheColl.push(creaPattern(str1));
1643					}
1644					ricercheColl.push(creaPattern('d/m/y'));
1645					ricercheColl.push(creaPattern('d/m'));
1646					break;
1647				case 'm/d/y':	case 'm/d/y h.n':	case 'm/d/y h.n.s':
1648					for (cont1 = 0; cont1 < Math.pow(2, 3); cont1++) {
1649						str1 = 'm/d/y h.n.st';
1650						if (cont1 % 2 > 0) str1 = str1.replace('/y', '');
1651						if (cont1 % 4 > 0) str1 = str1.replace('t', '');
1652						if (cont1 % 8 > 0) str1 = str1.replace('.s', '');
1653						str1 = Trim(str1);
1654						ricercheColl.push(creaPattern(str1));
1655					}
1656					ricercheColl.push(creaPattern('m/d/y'));
1657					ricercheColl.push(creaPattern('m/d'));
1658					break;
1659				case 'y/m/d':	case 'y/m/d h.n':	case 'y/m/d h.n.s':
1660					for (cont1 = 0; cont1 < Math.pow(2, 3); cont1++) {
1661						str1 = 'y/m/d h.n.st';
1662						if (cont1 % 2 > 0) str1 = str1.replace('y/', '');
1663						if (cont1 % 4 > 0) str1 = str1.replace('t', '');
1664						if (cont1 % 8 > 0) str1 = str1.replace('.s', '');
1665						str1 = Trim(str1);
1666						ricercheColl.push(creaPattern(str1));
1667					}
1668					ricercheColl.push(creaPattern('y/m/d'));
1669					ricercheColl.push(creaPattern('m/d'));
1670					break;
1671				default:
1672					ricercheColl.push(creaPattern(strFormato));
1673					break;
1674			}
1675			if (ricercheColl.length) {
1676				for (cont1 = 0; cont1 < ricercheColl.length; cont1++) {
1677					rePattern = ricercheColl[cont1].pattern;
1678					rePattern_Pos = ricercheColl[cont1].posiz;
1679					var re = new RegExp('^[ ]*' + rePattern + '[ ]*$', 'i');
1680					var reMatch = re.exec(DateString);
1681					if (reMatch) {
1682						var valori = {y:0, m:0, d:1, h:0, n:0, s:0, t:''};
1683						for (cont1 = 0; cont1 < rePattern_Pos.length; cont1++) {
1684							valori[rePattern_Pos[cont1]] = reMatch[cont1+1];
1685						}
1686						if (valori['y'] === 0) {
1687							if (valori['m'] > 0) valori['y'] = (new Date()).getFullYear();
1688						} else if (valori['y'].length < 3) {
1689							valori['y'] = CNum(valori['y']);
1690							valori['y'] += (valori['y'] > 50 ? 1900 : 2000);
1691						}
1692						if (valori['m'] !== 0) valori['m'] = CNum(valori['m']) - 1;
1693						if (valori['t'].toLowerCase() == 'pm') valori['h'] = CNum(valori['h']) + 12;
1694						fReturn = new Date(valori['y'], valori['m'], valori['d'], valori['h'], valori['n'], valori['s']);
1695						break;
1696					}
1697				}
1698			}
1699			break;
1700	}
1701	return fReturn;
1702}
1703
1704function CDateHtml__OLD(Format, DateObj) {
1705	var dVal = (DateObj ? DateObj : this);
1706	var strFormato = Format;
1707	var fReturn;
1708	if (strFormato) strFormato = strFormato.toLowerCase();
1709	switch (strFormato) {
1710		case 'iso':
1711			fReturn = dVal.getFullYear() +
1712					'-' + (dVal.getMonth()<9?'0':'') + (dVal.getMonth()+1).toString() +
1713					'-' + (dVal.getDate()<10?'0':'') + dVal.getDate().toString() +
1714					'T' + (dVal.getHours()<10?'0':'') + dVal.getHours().toString() +
1715					':' + (dVal.getMinutes()<10?'0':'') + dVal.getMinutes().toString() +
1716					':' + (dVal.getSeconds()<10?'0':'') + dVal.getSeconds().toString();
1717			break;
1718		case '':
1719		case 'time':
1720			fReturn = (dVal.getHours()<10?'0':'') + dVal.getHours().toString() +
1721					':' + (dVal.getMinutes()<10?'0':'') + dVal.getMinutes().toString() +
1722					':' + (dVal.getSeconds()<10?'0':'') + dVal.getSeconds().toString();
1723		case 'datetime':
1724			fReturn = (dVal.getDate()<10?'0':'') + dVal.getDate().toString() +
1725					'/' + (dVal.getMonth()<9?'0':'') + (dVal.getMonth()+1).toString() +
1726					'/' + dVal.getFullYear() +
1727					' ' + (dVal.getHours()<10?'0':'') + dVal.getHours().toString() +
1728					':' + (dVal.getMinutes()<10?'0':'') + dVal.getMinutes().toString() +
1729					':' + (dVal.getSeconds()<10?'0':'') + dVal.getSeconds().toString();
1730			break;
1731		case 'date':
1732		default:
1733			fReturn = (dVal.getDate()<10?'0':'') + dVal.getDate().toString() +
1734					'/' + (dVal.getMonth()<9?'0':'') + (dVal.getMonth()+1).toString() +
1735					'/' + dVal.getFullYear();
1736			break;
1737	}
1738	return fReturn;
1739}
1740function CDateHtml(Format, DateObj) {
1741	/*Converte il valore di tipo DATETIME in una stinga. L'argomento [Formato] puo essere:
1742		- "date", "time", "datetime":	la funzione restituisce la data, l'ora o data-ora nel formato della lingua corrente;
1743		- "iso":		la funzione restituisce la data in un formato ordinabile (secondo lo standard ISO 8601);
1744		- "":			come con "date";
1745		- <lingua>:		passando una lingua gestita dal sito, restituisce la data nel formato della lingua indicata;
1746		- <formato data ora valido>:	passando una stringa di formattazione, si ottiene una stringa data-ora in formato personalizzato; la stringa
1747						converte questi caratteri in rispettivi informazioni DataOra (non è case-sensitive):
1748							y-anno  m-mese  d-giorno  w-settimana  h-ora  n-minuto  s-secondo  t-am/pm  ("\": carattere escape).
1749	*/
1750	var DataOra = (DateObj ? DateObj : this);
1751	var strFormato, lanCorrente, fReturn;
1752	var listaAmPm, isPomeriggio, numChars, primoVal, segnapostiTrovati;
1753	var cont1, str1, char1, valore;
1754	if (IsUndefined(DataOra) || DataOra === null) {
1755		fReturn = null;
1756	} else if (DataOra) {
1757		valore = DataOra;
1758		if (Format == window.Lan) {
1759			lanCorrente = Format;
1760			strFormato = CDateHtml_GetFormat(4, 2, 2, 0, 0, 0, 0);
1761		} else {
1762			lanCorrente = window.Lan;
1763			switch (IfNull(Format, '').toLowerCase()) {
1764				case '':
1765				case 'date'		: strFormato = CDateHtml_GetFormat(4, 2, 2, 0, 0, 0, 0); break;
1766				case 'time'		: strFormato = CDateHtml_GetFormat(0, 0, 0, 2, 2, 2, 0); break;
1767				case 'datetime'	: strFormato = CDateHtml_GetFormat(4, 2, 2, 2, 2, 2, 0); break;
1768				case 'iso'		: strFormato = 'yyyy-mm-dd\\Thh:nn:ss'; break;
1769				default			: strFormato = Format; break;
1770			}
1771		}
1772		listaAmPm = CDateHtml_GetFormatInfo().amPm;
1773		//Determino la lista dei segnaposti validi
1774		segnapostiTrovati = '';
1775		for (cont1 = 0; cont1 < strFormato.length; cont1++) {
1776			char1 = strFormato.charAt(cont1).toLowerCase();
1777			if (('ymdwhnst\\').indexOf(char1) > -1) {
1778				if (char1 == '\\') {
1779					cont1 += 1;
1780				} else if (segnapostiTrovati.indexOf(char1) == -1) {
1781					segnapostiTrovati += char1;
1782				}
1783			}
1784		}
1785		//Formatto la data
1786		fReturn = '';
1787		for (cont1 = 0; cont1 < strFormato.length; cont1++) {
1788			char1 = strFormato.charAt(cont1).toLowerCase();
1789			if (('ymdwhnst\\').indexOf(char1) > -1) {
1790				if (char1 == '\\') {
1791					cont1 += 1;
1792					str1 = strFormato.charAt(cont1);
1793				} else {
1794					for (numChars = cont1 + 1; numChars < strFormato.length; numChars++) {
1795						if (char1 != strFormato.charAt(numChars).toLowerCase()) break;
1796					}
1797					numChars = numChars - cont1;		//Ora, numChars indica il numero di caratteri consegutivi uguali.
1798					cont1 = cont1 + numChars - 1;		//Sposto il puntatore del For-To-Next al carattere successivo.
1799					switch (char1) {
1800						case 'y': if (numChars <= 2) numChars = 2; else numChars = 4; break;
1801						case 'm': if (numChars > 4) numChars = 4; break;
1802						case 'd': if (numChars > 2) numChars = 2; break;
1803						case 'w': if (numChars <= 2) numChars = 2; else if (numChars > 4) numChars = 4; break;
1804						case 'h': if (numChars > 2) numChars = 2; break;
1805						case 'n': if (numChars > 2) numChars = 2; break;
1806						case 's': if (numChars > 2) numChars = 2; break;
1807						case 't': numChars = 1; break;
1808					}
1809					switch (char1) {
1810						case 'y':
1811							str1 = valore.getFullYear().toString();
1812							str1 = str1.substr(str1.length - numChars);
1813							break;
1814						case 'm':
1815							if (numChars <= 2) {
1816								str1 = (valore.getMonth() + 1).toString();
1817								str1 = LFill(str1, '0', numChars);
1818							} else {
1819								str1 = valore.GetMonthName();
1820								if (numChars == 3) str1 = str1.substr(0, numChars);
1821								str1 = str1.substr(0, 1).toUpperCase() + str1.substr(1).toLowerCase();
1822							}
1823							break;
1824						case "d": str1 = LFill(valore.getDate().toString(), '0', numChars); break;
1825						case 'w':
1826							str1 = valore.GetWeekName();
1827							if (numChars <= 3) str1 = str1.substr(0, numChars);
1828							str1 = str1.substr(0, 1).toUpperCase() + str1.substr(1).toLowerCase();
1829							break;
1830						case 'h':
1831							str1 = valore.getHours();
1832							if (segnapostiTrovati.toLowerCase().indexOf('t') > -1) {
1833								isPomeriggio = (str1 >= 12);
1834								if (str1 == 0) {
1835									str1 = 12;
1836								} else if (str1 > 12) {
1837									str1 = str1 - 12;
1838								}
1839							}
1840							str1 = LFill(str1.toString(), '0', numChars);
1841							break;
1842						case 'n': str1 = LFill(valore.getMinutes().toString(), "0", numChars); break;
1843						case 's': str1 = LFill(valore.getSeconds().toString(), "0", numChars); break;
1844						case 't':
1845							if (segnapostiTrovati.toLowerCase().indexOf('h') > -1) {
1846								str1 = listaAmPm[(isPomeriggio ? 1 : 0)];
1847							} else {
1848								str1 = '';
1849							}
1850							break;
1851					}
1852				}
1853				fReturn += str1;
1854			} else {
1855				fReturn += char1;
1856			}
1857		}
1858		fReturn = CStrHtml(fReturn);
1859	} else {
1860		fReturn = DataOra;
1861	}
1862	return fReturn;
1863}
1864Date.prototype.CDateHtml = CDateHtml;
1865
1866function DateAdd(TimeUnit, Value, DateObj) {
1867	var dVal = (DateObj ? DateObj : this);
1868	var newDate;
1869	switch (TimeUnit) {
1870		case 'ms':newDate = new Date(dVal); newDate.setMilliseconds(newDate.getMilliseconds() + Value); break;
1871		case 's': newDate = new Date(dVal); newDate.setSeconds(newDate.getSeconds() + Value); break;
1872		case 'n': newDate = new Date(dVal); newDate.setMinutes(newDate.getMinutes() + Value); break;
1873		case 'h': newDate = new Date(dVal); newDate.setHours(newDate.getHours() + Value); break;
1874		case 'd': newDate = new Date(dVal); newDate.setDate(newDate.getDate() + Value); break;
1875		case 'w': newDate = new Date(dVal); newDate.setDate(newDate.getDate() + Value * 7); break;
1876		case 'm': newDate = new Date(dVal); newDate.setMonth(newDate.getMonth() + Value); break;
1877		case 'y': newDate = new Date(dVal); newDate.setFullYear(newDate.getFullYear() + Value); break;
1878	}
1879	return newDate;
1880}
1881Date.prototype.DateAdd = DateAdd;
1882
1883function DateAddUTC(TimeUnit, Value, DateObj) {
1884	var millisecond = 1;
1885	var second = millisecond * 1000;
1886	var minute = second * 60;
1887	var hour = minute * 60;
1888	var day = hour * 24;
1889	var week = day * 7;
1890	var dVal = (DateObj ? DateObj : this).valueOf();
1891	var newDate;
1892	
1893	switch (TimeUnit) {
1894		case 'ms':newDate = new Date(dVal + millisecond * Value); break;
1895		case 's': newDate = new Date(dVal + second * Value); break;
1896		case 'n': newDate = new Date(dVal + minute * Value); break;
1897		case 'h': newDate = new Date(dVal + hour * Value); break;
1898		case 'd': newDate = new Date(dVal + day * Value); break;
1899		case 'w': newDate = new Date(dVal + week * Value); break;
1900		case 'm': newDate = new Date(dVal);
1900 newDate.setUTCMonth(newDate.getUTCMonth() + Value); break;
1901		case 'y': newDate = new Date(dVal); newDate.setUTCFullYear(newDate.getUTCFullYear() + Value); break;
1902	}
1903	return newDate;
1904}
1905Date.prototype.DateAddUTC = DateAddUTC;
1906
1907function GetWeekName(DateObj) {
1908	var objData = (DateObj ? DateObj : this);
1909	var vett1 = objData.toLocaleDateString().split(' ');
1910	var cont1;
1911	for (cont1=0; cont1<vett1.length; cont1++) {
1912		if (vett1[cont1].length > 2 && CNum(vett1[cont1]) != objData.getFullYear()) return vett1[cont1];
1913	}
1914}
1915Date.prototype.GetWeekName = GetWeekName;
1916
1917function GetMonthName(DateObj) {
1918	var objData = (DateObj ? DateObj : this);
1919	var vett1 = objData.toLocaleDateString().split(' ');
1920	var cont1;
1921	for (cont1=1; cont1<vett1.length; cont1++) {
1922		if (vett1[cont1].length > 2 && CNum(vett1[cont1]) != objData.getFullYear()) return vett1[cont1];
1923	}
1924}
1925Date.prototype.GetMonthName = GetMonthName;
1926
1927function SetDailyTime(Milliseconds, DateObj) {
1928	//Setta l'ora alla data corrente.
1929	var objData = (DateObj ? DateObj : this);
1930	var h, n, s, ms, val, resto;
1931	val = Milliseconds;
1932	resto = val % 3600000;	objData.setHours((val - resto) / 3600000);	val = resto;
1933	resto = val % 60000;	objData.setMinutes((val - resto) / 60000);	val = resto;
1934	resto = val % 1000;		objData.setSeconds((val - resto) / 1000);	val = resto;
1935	objData.setMilliseconds(val);
1936}
1937Date.prototype.SetDailyTime = SetDailyTime;
1938
1939
1940function CDateHtml_GetFormat(optYearDigits, optMonthDigits, optDayDigits, optHoutDigits, optMinuteDigits, optSecondDigits, optWeekDigits) {
1941	//Restituisce il formato di DATA-ORA per CDateHtml secondo la lingua indicata nel primo parametro. I successivi parametri sono
1942	//numerici, e va indicato il numero di cifre (zero per indicare nessun valore) da usare per quella info. Il mese e la settimana
1943	//posono essere anche a 3 o 4 cifre, che quindi restituirà il mese espresso in lettere, abbreviato a 3 o per esteso.
1944	var formatoDict, formato, sepData, sepOra;
1945	var fReturn, str1, cont1;
1946	
1947	//Cerco di determinare la posizione degli elementi della data, e il formato di ora.
1948	formatoDict = CDateHtml_GetFormatInfo();
1949	formato = formatoDict.format;
1950	sepData = formatoDict.dateSep;
1951	sepOra = formatoDict.hourSep;
1952	
1953	fReturn = '';
1954	for (cont1 = 0; cont1 < formato.length; cont1++) {
1955		switch (formato.charAt(cont1)) {
1956			case 'w': str1 = StringRepeater('w', (optWeekDigits ? optWeekDigits : 0)); break;
1957			case 'd': str1 = StringRepeater('d', (optDayDigits ? optDayDigits : 0)); break;
1958			case 'm': str1 = StringRepeater('m', (optMonthDigits ? optMonthDigits : 0)); break;
1959			case 'y': str1 = StringRepeater('y', (optYearDigits ? optYearDigits : 0)); break;
1960			case 'h': str1 = StringRepeater('h', (optHoutDigits ? optHoutDigits : 0)); break;
1961			case 'n': str1 = StringRepeater('n', (optMinuteDigits ? optMinuteDigits : 0)); break;
1962			case 's': str1 = StringRepeater('s', (optSecondDigits ? optSecondDigits : 0)); break;
1963			case 't': str1 = (optHoutDigits > 0 ? 't' : ''); break;
1964			case '/': str1 = (optMonthDigits > 2 ? ' ' : sepData); break;
1965			case '.': str1 = sepOra; break;
1966			case ' ': str1 = ' '; break;
1967			default:  str1 = ''; break;
1968		}
1969		fReturn += str1;
1970	}
1971	fReturn = Trim(fReturn, ' ' + sepData + sepOra);
1972	
1973	return fReturn;
1974}
1975function CDateHtml_GetFormatInfo() {
1976	//Restituisce un dictionary con informazioni su come è formattata la data ed ora nel pc del client. I valori ritornati sono:
1977	//	'format'	: il formato della data-ora, per determinare la posizione dei vari elementi; es: "w d/m/y h.n.s", "w m/d/y h.n.s";
1978	//	'dateSep'	: il separatore usato per separare i componenti della data;
1979	//	'hourSep'	: il separatore usato per separare i componenti dell'ora;
1980	//	'amPm'		: array con i valori usati per indicare AM e PM, in quest'ordine.
1981	var fReturn, re, reMatch;
1982	var str1, cont1, data1;
1983	var ora24, trovatoWeek;
1984	//Analizzo una data-ora, dove non rischio di scambiare un valore per un altro (giorno con mese e così via).
1985	//Attenzione: ho difficoltà a distinguere il mese con il giorno della settimana, quindi considero sempre che la settimana è la prima cosa che
1986	//deve apparire.
1987	data1 = new Date(2001, 3, 4, 17, 18, 19);
1988	re = new RegExp('(2001|01|3|4|17|5|18|19|[a-z]{2,20})', 'gi');
1989	fReturn = {format:'', dateSep:'/', hourSep:':', amPm:['am','pm']};
1990	fReturn.format = 'w ';
1991	//Inizio analisi data
1992	trovatoWeek = false;
1993	while ((reMatch = re.exec(data1.toLocaleDateString())) !== null) {
1994		switch (reMatch[1]) {
1995			case '2001':str1 = 'y'; break;
1996			case '01':	str1 = 'y'; break;
1997			case '3':	str1 = 'm'; break;
1998			case '4':	str1 = 'd'; break;
1999			default:
2000				if (!trovatoWeek) {
2001					trovatoWeek = true;
2002					str1 = '';
2003				} else {
2004					str1 = 'm';
2005				}
2006				break;
2007		}
2008		if (str1) fReturn.format += (fReturn.format.charAt(fReturn.format.length-1)==' ' ? '' : '/') + str1;
2009	}
2010	//Inizio analisi ora
2011	fReturn.format += ' ';
2012	while ((reMatch = re.exec(data1.toLocaleTimeString())) !== null) {
2013		switch (reMatch[1]) {
2014			case '17':	str1 = 'h'; ora24 = true; break;
2015			case '5':	str1 = 'h'; ora24 = false; break;
2016			case '18':	str1 = 'n'; break;
2017			case '19':	str1 = 's'; break;
2018			default:	str1 = ''; break;
2019		}
2020		if (str1) fReturn.format += (fReturn.format.charAt(fReturn.format.length-1)==' ' ? '' : '.') + str1;
2021	}
2022	if (!ora24) fReturn.format += ' t';
2023	//Determino il separatore delle ore (attenzione: non ho possibilità di conoscere il dateSep perchè javascript non mi restituisce la data in forma numerica)
2024	re = new RegExp('18(.)19', 'gi');
2025	reMatch = re.exec(data1.toLocaleTimeString());
2026	fReturn.hourSep = reMatch[1];
2027	return fReturn;
2028}
2029
2030
2031//###############################################################################
2032//####		Elenco di procedure per la gestione di valori all'interno di un array.
2033
2034
2035function CreateList(oArrayObj) {
2036	var fReturn = oArrayObj;
2037	if (!fReturn) fReturn = new Array();
2038	fReturn.objectType = function () {return 'List';}
2039	fReturn.Exists = function (Value) {
2040		for (var i in this) {if (this[i] == Value) return true;}
2041		return false;
2042	}
2043	SerializeValue__ArrayColl_addArrayType(fReturn, 'Array');
2044	return fReturn;
2045}
2046function CreateDictionary(oArrayObj) {
2047	var fReturn = oArrayObj;
2048	if (!fReturn) fReturn = new Array();
2049	fReturn.objectType = function () {return 'Dictionary';}
2050	fReturn.RemoveKeys = function (Keys) {
2051		var i, j, obj1, vett1;
2052		if (ValueType(Keys) == 'Array') {
2053			vett1 = Keys;
2054		} else {
2055			vett1 = new Array(); vett1.push(Keys);
2056		}
2057		for (i = 0; i < vett1.length; i++) {
2058			j = 0;
2059			for (obj1 in this) {
2060				if (obj1 == vett1[i]) {
2061					if (1*obj1 != obj1) {delete this[obj1];} else {this.splice(j, 1);}
2062				} else {
2063					j++;
2064				}
2065			}
2066		}
2067	}
2068	SerializeValue__ArrayColl_addArrayType(fReturn, 'Dictionary');
2069	return fReturn;
2070}
2071
2072
2073function InArray(ArrayObject, Value) {
2074	//Cerca il valore nell'array, e restituisce la rispettiva KEY. Se non viene trovato restituisce NULL.
2075	var str1, fReturn;
2076	fReturn = null;
2077	if (ValueType(ArrayObject) == 'Array') {
2078		if (typeof(Value) == 'object') {
2079			for (str1 in ArrayObject) {
2080				if (ArrayObject[str1] === Value) {
2081					fReturn = str1;
2082					break;
2083				}
2084			}
2085		} else {
2086			for (str1 in ArrayObject) {
2087				if (ArrayObject[str1] == Value) {
2088					fReturn = str1;
2089					break;
2090				}
2091			}
2092		}
2093	}
2094	return fReturn;
2095}
2096/*
2097function InArrayRev(ArrayObject, Value) {
2098	//Cerca il valore nell'array, e restituisce la rispettiva KEY. Se non viene trovato restituisce NULL.
2099	//La ricerca avviene in ordine inverso.
2100}
2101function InKeyArray(ArrayObject, KeyValue) {
2102	//Cerca la KEY nell'array, e restituisce la rispettiva posizione. Se non viene trovato restituisce NULL.
2103}
2104*/
2105function TextInArray(ArrayObject, String) {
2106	//Cerca il valore di tipo string nell'array (no case sensitive), 
2107	var str1, valore, fReturn;
2108	fReturn = null;
2109	valore = String.toString();
2110	if (ValueType(ArrayObject) == 'Array') {
2111		for (str1 in ArrayObject) {
2112			if (valore.localeCompare(ArrayObject[str1].toString()) == 0) {
2113				fReturn = str1;
2114				break;
2115			}
2116		}
2117	}
2118	return fReturn;
2119	
2120}
2121function FindArrayItem(ArrayName, ItemKey, optWindow) {
2122	//Cerca l'item [ItemKey] nell'array [ArrayName]. Argomenti:
2123	//	ArrayName:		nome dell'array su cui cercare l'item.
2124	//	ItemKey:		la chiave dell'item da restituire.
2125	//	optWindow:		(opzionale) oggetto [Window] su cui cercare.
2126	var p, i, x, y, objWin;
2127	if (!(objWin = optWindow)) objWin = window;
2128	if (!y && (x = objWin[ArrayName])) y = x[ItemKey];
2129	if (!y && objWin.frames && !optWindow) {
2130		if (!y && objWin.frames.top) {y = FindArrayItem(ArrayName, ItemKey, objWin.frames.top.window);}
2131		if (!y) for (i=0; i < objWin.frames.length && !y; i++) {y = FindArrayItem(ArrayName, ItemKey, objWin.frames[i].window);}
2132	}
2133	return y;
2134}
2135
2136
2137function ValueType(Value) {
2138	//Restituisce il tipo di valore o oggetto
2139	var fReturn;
2140	if (Value === void(0)) {
2141		fReturn = 'undefined';
2142	} else if (Value === null) {
2143		fReturn = 'null';
2144	} else if (Value === '') {
2145		fReturn = 'empty';
2146	} else {
2147		fReturn = typeof(Value);	//Può essere: string, number, boolean, object, function
2148		if (fReturn == 'object') {
2149			//Cerco di vedere se Value è uno di questi specifici oggetti. Notare che questi hanno la prima lettera maiuscola. Quindi si
2150			//può sfruttare questa informazione per sapere se il tipo restituito 'OBJECT' è un tipo generico oppure esattamente 'Object'.
2151			if (Value instanceof Array) {
2152				fReturn = 'Array';
2153			} else if (Value instanceof Date) {
2154				fReturn = 'Date';
2155			} else if (Value instanceof RegExp) {
2156				fReturn = 'RegExp';
2157			} else {	//if (Value instanceof Object) {
2158				fReturn = 'Object';
2159			}
2160		} else if (fReturn == 'function') {
2161			fReturn = 'Function';
2162		}
2163	}
2164	return fReturn;
2165}
2166
2167function HTMLEncode(Value){
2168	// Converte la stringa passata nel formato HTML
2169	var k, cont1;		//cont1 mi serve per iterare sulla stringa
2170	var cont2;			//mi serve per memmorizzare il carattere di partenza pgni volta che trovo un carattere da codificare
2171	var chars, ascChars;
2172	var trovato;
2173	var fReturn;
2174	
2175	if (Value === void(0) || Value === null) {
2176		fReturn = null;
2177	} else {
2178		fReturn = '';
2179		k = Value.length;
2180		cont1 = 0;
2181		cont2 = 0;
2182		trovato = false;
2183		
2184		while (cont1 < k) {
2185			ascChars = Value.charCodeAt(cont1);
2186			if (ascChars >= 128) {
2187				chars = '&#' + ascChars + ';';
2188				trovato = true;
2189			} else {
2190				switch (Value.charAt(cont1)) {
2191					case '"':	chars = '&quot;';	trovato = true; break;
2192					case '&':	chars = '&amp;';	trovato = true; break;
2193					case '<':	chars = '&lt;';		trovato = true; break;
2194					case '>':	chars = '&gt;';		trovato = true; break;
2195				}
2196			}
2197			if (trovato) {
2198				fReturn += Value.substr(cont2, cont1 - cont2) + chars;
2199				cont2 = cont1 + 1;
2200				trovato = false;
2201			}
2202			cont1 += 1;
2203		}	
2204		if (!trovato) fReturn += Value.substr(cont2);
2205	}
2206	return fReturn;
2207}
2208
2209function HTMLDecode(TestoHtml){
2210	// converte caratteri codificati da Html a Unicode
2211	var re, indice, reMatch, str1;
2212	var nuovoVal;
2213	var fReturn;
2214	
2215	indice = 0;
2216	fReturn = '';
2217	nuovoVal = -1;
2218	re = new RegExp('&(#x[0-9a-fA-F]+|#[0-9]+|[a-zA-Z]{1,9}[0-9]{0,3});', 'g');
2219	reMatch = re.exec(TestoHtml);
2220	while (reMatch !== null){
2221		str1 = reMatch[1];
2222		if (str1.substr(0,2) == '#x') {
2223			nuovoVal = parseInt(str1.substr(2), 16);
2224		} else if (str1.substr(0,1) == '#') {
2225			nuovoVal = str1.substr(1);
2226		} else {
2227			switch (str1){
2228				case 'quot'  : nuovoVal = 34; break;
2229				case 'amp'  : nuovoVal = 38; break;
2230				case 'lt'  : nuovoVal = 60; break;
2231				case 'gt'  : nuovoVal = 62; break;
2232				case 'nbsp'  : nuovoVal = 160; break;
2233				case 'iexcl'  : nuovoVal = 161; break;
2234				case 'cent'  : nuovoVal = 162; break;
2235				case 'pound'  : nuovoVal = 163; break;
2236				case 'curren'  : nuovoVal = 164; break;
2237				case 'yen'  : nuovoVal = 165; break;
2238				case 'brvbar'  : nuovoVal = 166; break;
2239				case 'sect'  : nuovoVal = 167; break;
2240				case 'uml'  : nuovoVal = 168; break;
2241				case 'copy'  : nuovoVal = 169; break;
2242				case 'ordf'  : nuovoVal = 170; break;
2243				case 'laquo'  : nuovoVal = 171; break;
2244				case 'not'  : nuovoVal = 172; break;
2245				case 'shy'  : nuovoVal = 173; break;
2246				case 'reg'  : nuovoVal = 174; break;
2247				case 'macr'  : nuovoVal = 175; break;
2248				case 'deg'  : nuovoVal = 176; break;
2249				case 'plusmn'  : nuovoVal = 177; break;
2250				case 'sup2'  : nuovoVal = 178; break;
2251				case 'sup3'  : nuovoVal = 179; break;
2252				case 'acute'  : nuovoVal = 180; break;
2253				case 'micro'  : nuovoVal = 181; break;
2254				case 'para'  : nuovoVal = 182; break;
2255				case 'middot'  : nuovoVal = 183; break;
2256				case 'cedil'  : nuovoVal = 184; break;
2257				case 'sup1'  : nuovoVal = 185; break;
2258				case 'ordm'  : nuovoVal = 186; break;
2259				case 'raquo'  : nuovoVal = 187; break;
2260				case 'frac14'  : nuovoVal = 188; break;
2261				case 'frac12'  : nuovoVal = 189; break;
2262				case 'frac34'  : nuovoVal = 190; break;
2263				case 'iquest'  : nuovoVal = 191; break;
2264				case 'Agrave'  : nuovoVal = 192; break;
2265				case 'Aacute'  : nuovoVal = 193; break;
2266				case 'Acirc'  : nuovoVal = 194; break;
2267				case 'Atilde'  : nuovoVal = 195; break;
2268				case 'Auml'  : nuovoVal = 196; break;
2269				case 'Aring'  : nuovoVal = 197; break;
2270				case 'AElig'  : nuovoVal = 198; break;
2271				case 'Ccedil'  : nuovoVal = 199; break;
2272				case 'Egrave'  : nuovoVal = 200; break;
2273				case 'Eacute'  : nuovoVal = 201; break;
2274				case 'Ecirc'  : nuovoVal = 202; break;
2275				case 'Euml'  : nuovoVal = 203; break;
2276				case 'Igrave'  : nuovoVal = 204; break;
2277				case 'Iacute'  : nuovoVal = 205; break;
2278				case 'Icirc'  : nuovoVal = 206; break;
2279				case 'Iuml'  : nuovoVal = 207; break;
2280				case 'ETH'  : nuovoVal = 208; break;
2281				case 'Ntilde'  : nuovoVal = 209; break;
2282				case 'Ograve'  : nuovoVal = 210; break;
2283				case 'Oacute'  : nuovoVal = 211; break;
2284				case 'Ocirc'  : nuovoVal = 212; break;
2285				case 'Otilde'  : nuovoVal = 213; break;
2286				case 'Ouml'  : nuovoVal = 214; break;
2287				case 'times'  : nuovoVal = 215; break;
2288				case 'Oslash'  : nuovoVal = 216; break;
2289				case 'Ugrave'  : nuovoVal = 217; break;
2290				case 'Uacute'  : nuovoVal = 218; break;
2291				case 'Ucirc'  : nuovoVal = 219; break;
2292				case 'Uuml'  : nuovoVal = 220; break;
2293				case 'Yacute'  : nuovoVal = 221; break;
2294				case 'THORN'  : nuovoVal = 222; break;
2295				case 'szlig'  : nuovoVal = 223; break;
2296				case 'agrave'  : nuovoVal = 224; break;
2297				case 'aacute'  : nuovoVal = 225; break;
2298				case 'acirc'  : nuovoVal = 226; break;
2299				case 'atilde'  : nuovoVal = 227; break;
2300				case 'auml'  : nuovoVal = 228; break;
2301				case 'aring'  : nuovoVal = 229; break;
2302				case 'aelig'  : nuovoVal = 230; break;
2303				case 'ccedil'  : nuovoVal = 231; break;
2304				case 'egrave'  : nuovoVal = 232; break;
2305				case 'eacute'  : nuovoVal = 233; break;
2306				case 'ecirc'  : nuovoVal = 234; break;
2307				case 'euml'  : nuovoVal = 235; break;
2308				case 'igrave'  : nuovoVal = 236; break;
2309				case 'iacute'  : nuovoVal = 237; break;
2310				case 'icirc'  : nuovoVal = 238; break;
2311				case 'iuml'  : nuovoVal = 239; break;
2312				case 'eth'  : nuovoVal = 240; break;
2313				case 'ntilde'  : nuovoVal = 241; break;
2314				case 'ograve'  : nuovoVal = 242; break;
2315				case 'oacute'  : nuovoVal = 243; break;
2316				case 'ocirc'  : nuovoVal = 244; break;
2317				case 'otilde'  : nuovoVal = 245; break;
2318				case 'ouml'  : nuovoVal = 246; break;
2319				case 'divide'  : nuovoVal = 247; break;
2320				case 'oslash'  : nuovoVal = 248; break;
2321				case 'ugrave'  : nuovoVal = 249; break;
2322				case 'uacute'  : nuovoVal = 250; break;
2323				case 'ucirc'  : nuovoVal = 251; break;
2324				case 'uuml'  : nuovoVal = 252; break;
2325				case 'yacute'  : nuovoVal = 253; break;
2326				case 'thorn'  : nuovoVal = 254; break;
2327				case 'yuml'  : nuovoVal = 255; break;
2328				case 'OElig'  : nuovoVal = 338; break;
2329				case 'oelig'  : nuovoVal = 339; break;
2330				case 'Scaron'  : nuovoVal = 352; break;
2331				case 'scaron'  : nuovoVal = 353; break;
2332				case 'Yuml'  : nuovoVal = 376; break;
2333				case 'fnof'  : nuovoVal = 402; break;
2334				case 'circ'  : nuovoVal = 710; break;
2335				case 'tilde'  : nuovoVal = 732; break;
2336				case 'Alpha'  : nuovoVal = 913; break;
2337				case 'Beta'  : nuovoVal = 914; break;
2338				case 'Gamma'  : nuovoVal = 915; break;
2339				case 'Delta'  : nuovoVal = 916; break;
2340				case 'Epsilon'  : nuovoVal = 917; break;
2341				case 'Zeta'  : nuovoVal = 918; break;
2342				case 'Eta'  : nuovoVal = 919; break;
2343				case 'Theta'  : nuovoVal = 920; break;
2344				case 'Iota'  : nuovoVal = 921; break;
2345				case 'Kappa'  : nuovoVal = 922; break;
2346				case 'Lambda'  : nuovoVal = 923; break;
2347				case 'Mu'  : nuovoVal = 924; break;
2348				case 'Nu'  : nuovoVal = 925; break;
2349				case 'Xi'  : nuovoVal = 926; break;
2350				case 'Omicron'  : nuovoVal = 927; break;
2351				case 'Pi'  : nuovoVal = 928; break;
2352				case 'Rho'  : nuovoVal = 929; break;
2353				case 'Sigma'  : nuovoVal = 931; break;
2354				case 'Tau'  : nuovoVal = 932; break;
2355				case 'Upsilon'  : nuovoVal = 933; break;
2356				case 'Phi'  : nuovoVal = 934; break;
2357				case 'Chi'  : nuovoVal = 935; break;
2358				case 'Psi'  : nuovoVal = 936; break;
2359				case 'Omega'  : nuovoVal = 937; break;
2360				case 'alpha'  : nuovoVal = 945; break;
2361				case 'beta'  : nuovoVal = 946; break;
2362				case 'gamma'  : nuovoVal = 947; break;
2363				case 'delta'  : nuovoVal = 948; break;
2364				case 'epsilon'  : nuovoVal = 949; break;
2365				case 'zeta'  : nuovoVal = 950; break;
2366				case 'eta'  : nuovoVal = 951; break;
2367				case 'theta'  : nuovoVal = 952; break;
2368				case 'iota'  : nuovoVal = 953; break;
2369				case 'kappa'  : nuovoVal = 954; break;
2370				case 'lambda'  : nuovoVal = 955; break;
2371				case 'mu'  : nuovoVal = 956; break;
2372				case 'nu'  : nuovoVal = 957; break;
2373				case 'xi'  : nuovoVal = 958; break;
2374				case 'omicron'  : nuovoVal = 959; break;
2375				case 'pi'  : nuovoVal = 960; break;
2376				case 'rho'  : nuovoVal = 961; break;
2377				case 'sigmaf'  : nuovoVal = 962; break;
2378				case 'sigma'  : nuovoVal = 963; break;
2379				case 'tau'  : nuovoVal = 964; break;
2380				case 'upsilon'  : nuovoVal = 965; break;
2381				case 'phi'  : nuovoVal = 966; break;
2382				case 'chi'  : nuovoVal = 967; break;
2383				case 'psi'  : nuovoVal = 968; break;
2384				case 'omega'  : nuovoVal = 969; break;								
2385				case 'thetasym'  : nuovoVal = 977; break;
2386				case 'upsih'  : nuovoVal = 978; break;
2387				case 'piv'  : nuovoVal = 982; break;
2388				case 'ensp'  : nuovoVal = 8194; break;
2389				case 'emsp'  : nuovoVal = 8195; break;
2390				case 'thinsp'  : nuovoVal = 8201; break;
2391				case 'zwnj'  : nuovoVal = 8204; break;
2392				case 'zwj'  : nuovoVal = 8205; break;
2393				case 'lrm'  : nuovoVal = 8206; break;
2394				case 'rlm'  : nuovoVal = 8207; break;
2395				case 'ndash'  : nuovoVal = 8211; break;
2396				case 'mdash'  : nuovoVal = 8212; break;
2397				case 'lsquo'  : nuovoVal = 8216; break;
2398				case 'rsquo'  : nuovoVal = 8217; break;
2399				case 'sbquo'  : nuovoVal = 8218; break;
2400				case 'ldquo'  : nuovoVal = 8220; break;
2401				case 'rdquo'  : nuovoVal = 8221; break;
2402				case 'bdquo'  : nuovoVal = 8222; break;
2403				case 'dagger'  : nuovoVal = 8224; break;
2404				case 'Dagger'  : nuovoVal = 8225; break;
2405				case 'bull'  : nuovoVal = 8226; break;
2406				case 'hellip'  : nuovoVal = 8230; break;
2407				case 'permil'  : nuovoVal = 8240; break;
2408				case 'prime'  : nuovoVal = 8242; break;
2409				case 'Prime'  : nuovoVal = 8243; break;
2410				case 'lsaquo'  : nuovoVal = 8249; break;
2411				case 'rsaquo'  : nuovoVal = 8250; break;
2412				case 'oline'  : nuovoVal = 8254; break;
2413				case 'frasl'  : nuovoVal = 8260; break;
2414				case 'euro'  : nuovoVal = 8364; break;
2415				case 'image'  : nuovoVal = 8465; break;
2416				case 'weierp'  : nuovoVal = 8472; break;
2417				case 'real'  : nuovoVal = 8476; break;
2418				case 'trade'  : nuovoVal = 8482; break;
2419				case 'alefsym'  : nuovoVal = 8501; break;
2420				case 'larr'  : nuovoVal = 8592; break;
2421				case 'uarr'  : nuovoVal = 8593; break;
2422				case 'rarr'  : nuovoVal = 8594; break;
2423				case 'darr'  : nuovoVal = 8595; break;
2424				case 'harr'  : nuovoVal = 8596; break;
2425				case 'crarr'  : nuovoVal = 8629; break;
2426				case 'lArr'  : nuovoVal = 8656; break;
2427				case 'uArr'  : nuovoVal = 8657; break;
2428				case 'rArr'  : nuovoVal = 8658; break;
2429				case 'dArr'  : nuovoVal = 8659; break;
2430				case 'hArr'  : nuovoVal = 8660; break;
2431				case 'forall'  : nuovoVal = 8704; break;
2432				case 'part'  : nuovoVal = 8706; break;
2433				case 'exist'  : nuovoVal = 8707; break;
2434				case 'empty'  : nuovoVal = 8709; break;
2435				case 'nabla'  : nuovoVal = 8711; break;
2436				case 'isin'  : nuovoVal = 8712; break;
2437				case 'notin'  : nuovoVal = 8713; break;
2438				case 'ni'  : nuovoVal = 8715; break;
2439				case 'prod'  : nuovoVal = 8719; break;
2440				case 'sum'  : nuovoVal = 8721; break;
2441				case 'minus'  : nuovoVal = 8722; break;
2442				case 'lowast'  : nuovoVal = 8727; break;
2443				case 'radic'  : nuovoVal = 8730; break;
2444				case 'prop'  : nuovoVal = 8733; break;
2445				case 'infin'  : nuovoVal = 8734; break;
2446				case 'ang'  : nuovoVal = 8736; break;
2447				case 'and'  : nuovoVal = 8743; break;
2448				case 'or'  : nuovoVal = 8744; break;
2449				case 'cap'  : nuovoVal = 8745; break;
2450				case 'cup'  : nuovoVal = 8746; break;
2451				case 'int'  : nuovoVal = 8747; break;
2452				case 'there4'  : nuovoVal = 8756; break;
2453				case 'sim'  : nuovoVal = 8764; break;
2454				case 'cong'  : nuovoVal = 8773; break;
2455				case 'asymp'  : nuovoVal = 8776; break;
2456				case 'ne'  : nuovoVal = 8800; break;
2457				case 'equiv'  : nuovoVal = 8801; break;
2458				case 'le'  : nuovoVal = 8804; break;
2459				case 'ge'  : nuovoVal = 8805; break;
2460				case 'sub'  : nuovoVal = 8834; break;
2461				case 'sup'  : nuovoVal = 8835; break;
2462				case 'nsub'  : nuovoVal = 8836; break;
2463				case 'sube'  : nuovoVal = 8838; break;
2464				case 'supe'  : nuovoVal = 8839; break;
2465				case 'oplus'  : nuovoVal = 8853; break;
2466				case 'otimes'  : nuovoVal = 8855; break;
2467				case 'perp'  : nuovoVal = 8869; break;
2468				case 'sdot'  : nuovoVal = 8901; break;
2469				case 'lceil'  : nuovoVal = 8968; break;
2470				case 'rceil'  : nuovoVal = 8969; break;
2471				case 'lfloor'  : nuovoVal = 8970; break;
2472				case 'rfloor'  : nuovoVal = 8971; break;
2473				case 'lang'  : nuovoVal = 9001; break;
2474				case 'rang'  : nuovoVal = 9002; break;
2475				case 'loz'  : nuovoVal = 9674; break;
2476				case 'spades'  : nuovoVal = 9824; break;
2477				case 'clubs'  : nuovoVal = 9827; break;
2478				case 'hearts'  : nuovoVal = 9829; break;
2479				case 'diams'  : nuovoVal = 9830; break;
2480				default :	nuovoVal = -1;
2481			}
2482			
2483		}
2484		if (nuovoVal > -1){ 
2485			fReturn += TestoHtml.substr(indice, reMatch.index - indice) + String.fromCharCode(nuovoVal);
2486			indice = reMatch.index + reMatch[0].length;
2487		}
2488		reMatch = re.exec(TestoHtml);
2489	}
2490	fReturn += TestoHtml.substr(indice);
2491	return fReturn
2492}
2493
2494
2495// Serializza il valore passato.
2496function SerializeValue(Valore){
2497	var cont1, cont2, cont3, str1, str2, k, y;
2498	var fReturn;
2499	
2500	switch (ValueType(Valore)){
2501		case 'null':
2502			fReturn = '#NULL';
2503			break;
2504		case 'empty':
2505			fReturn = '#EMPTY';
2506			break;
2507		case 'undefined':
2508			fReturn = '#NOTHING';
2509			break;
2510		case 'Object':
2511			fReturn = '#OBJECT';
2512			break;
2513		case 'Array':
2514			fReturn = '';
2515			str1 = SerializeValue__ArrayColl_getArrayType(Valore);
2516			if (!str1) {
2517				// Controllo se l'array ottenuto si tratta di un Array o di una Dictionary
2518				// in caso si tratti d un array si procede normalmente..
2519				// in caso si trattasse di una dictionary provvederemo a serializzare sia chiave che valore..
2520				cont2 = 0;
2521				str1 = 'Array';
2522				for (cont1 in Valore) {
2523					if (ValueType(Valore[cont1]) != 'Function') {
2524						if (cont1.toString() != cont2.toString()) {
2525							str1 = 'Dictionary';
2526							//alert('SerializeValue :' +  '\n   cont1 = ' + cont1 + '\n   cont2 = ' + cont2 + '\n   typeof= ' + ValueType(Valore[cont1]));
2527							break;
2528						}
2529						cont2 += 1;
2530					}
2531				}
2532			}
2533			switch (str1) {
2534				case 'Array':		// Stiamo serializzando un Array
2535					fReturn = '{';
2536					for (cont1=0; cont1<Valore.length; cont1++) {
2537						if (fReturn != '{') fReturn += ',';
2538						str1 = SerializeValue(Valore[cont1]);
2539						k = str1.length;
2540						fReturn += k + ':' + str1; 
2541					}
2542					fReturn = fReturn + '}';
2543					break;
2544				case 'Dictionary':	// Stiamo Serializzando un Dictionary
2545					fReturn = '[';
2546					for (cont1 in Valore) {
2547						if (typeof(Valore[cont1]) != 'function') {
2548							if (fReturn != '[') fReturn += ',';
2549							str1 = SerializeValue(cont1);
2550							str2 = SerializeValue(Valore[cont1]);
2551							y = str1.length;
2552							k = str2.length;
2553							fReturn += y + ':' + str1 + ',' + k + ':' + str2;
2554						}
2555					}
2556					fReturn = fReturn + ']';
2557					break;
2558			}
2559			break;
2560		case 'number':
2561			fReturn = 'F' + Valore.toString();
2562			break;
2563		case 'Date':
2564			fReturn = 'D' + Valore.getFullYear() + LFill((Valore.getMonth()+1).toString(), '0',2) + LFill(Valore.getDate().toString(), '0',2) + LFill(Valore.getHours().toString(),'0', 2)+ LFill(Valore.getMinutes().toString(),'0', 2) + LFill(Valore.getSeconds().toString(),'0', 2);
2565			break;
2566		case 'boolean':
2567			if ( IsTrue(Valore) == true) {
2568				fReturn = 'B' + '1'; 
2569			} else {
2570				fReturn = 'B' + '0';
2571			}
2572			break;
2573		case 'string':
2574			fReturn = 'S' + HTMLEncode(Valore);
2575			break;
2576		default:
2577			fReturn = '#tipo [' + ValueType(Valore) + '] non supportato.';
2578	}
2579	return fReturn;
2580}
2581//Deserializza il valore passato
2582function DeserializeValue(ValoreSerializzato) {
2583	var cont1, cont2, cont3, str1, str2, lunghezza, tipo, valore, fReturn;
2584	tipo = ValoreSerializzato.charAt(0);
2585	valore = ValoreSerializzato.substr(1);
2586	switch (tipo) {
2587		case '#':
2588			switch (valore) {
2589				case 'NULL':
2590					fReturn = null;
2591					break;
2592				case 'NOTHING':
2593					fReturn = void(0);
2594					break;
2595				case 'OBJECT':
2596					fReturn = null;
2597					break;
2598				case 'EMPTY':
2599					fReturn = '';
2600					break;
2601				default:
2602					fReturn = null;
2603					break;
2604			}
2605			break;
2606		case 'D':
2607			fReturn = new Date();
2608			fReturn.setFullYear(toNumber(valore.substr(0,4)));
2609			fReturn.setMonth(toNumber(valore.substr(4,2))-1);
2610			fReturn.setDate(toNumber(valore.substr(6,2)));
2611			fReturn.setHours(toNumber(valore.substr(8,2)));
2612			fReturn.setMinutes(toNumber(valore.substr(10,2)));
2613			fReturn.setSeconds(toNumber(valore.substr(12,2)));
2614			break;
2615		case 'S':
2616			fReturn = HTMLDecode(valore);
2617			break;
2618		case 'F':
2619		case 'I':
2620			fReturn = toNumber(valore,0, false);
2621			break;
2622		case 'B':
2623			fReturn = IsTrue(valore);
2624			break;
2625		case '{':
2626			fReturn = new Array();
2627			SerializeValue__ArrayColl_addArrayType(fReturn, 'Array');
2628			if (valore != '}') {
2629				cont1 = 0;
2630				cont3 = 0;
2631				do {
2632					cont1 += 1;
2633					cont2 = cont1 + 1 + ValoreSerializzato.substr(cont1 + 1).search(/:/);
2634					lunghezza = toNumber(ValoreSerializzato.substr(cont1, cont2 - cont1));
2635					str1 = ValoreSerializzato.substr(cont2 + 1, lunghezza);
2636					cont1 = cont2 + lunghezza + 1;
2637					//Setto il valore nell'array
2638					fReturn[cont3] = DeserializeValue(str1);
2639					cont3 += 1;
2640				} while (ValoreSerializzato.charAt(cont1) == ',');
2641			}
2642			break;
2643		case '[':
2644			fReturn = new Array();
2645			SerializeValue__ArrayColl_addArrayType(fReturn, 'Dictionary');
2646			if (valore != ']') {
2647				cont1 = 0;
2648				do {
2649					//Determino il nome dell'item
2650					cont1 += 1;
2651					cont2 = cont1 + 1 + ValoreSerializzato.substr(cont1 + 1).search(/:/);
2652					lunghezza = toNumber(ValoreSerializzato.substr(cont1, cont2 - cont1));
2653					str1 = ValoreSerializzato.substr(cont2 + 1, lunghezza);
2654					cont1 = cont2 + lunghezza + 1;
2655					//Determino il valore dell'item
2656					cont1 += 1;
2657					cont2 = cont1 + 1 + ValoreSerializzato.substr(cont1 + 1).search(/:/);
2658					lunghezza = toNumber(ValoreSerializzato.substr(cont1, cont2 - cont1));
2659					str2 = ValoreSerializzato.substr(cont2 + 1, lunghezza);
2660					cont1 = cont2 + lunghezza + 1;
2661					//Setto il valore nel dictionary
2662					fReturn[DeserializeValue(str1)] = DeserializeValue(str2);
2663				} while (ValoreSerializzato.charAt(cont1) == ',');
2664			}
2665			break;
2666		default:
2667			fReturn = null;
2668	}
2669	return fReturn;
2670}
2671//Aggiunge un oggetto Array alla collection di oggetti riconosciuti da [SerializeValue]/[DeserializeValue].
2672function SerializeValue__ArrayColl_addArrayType(ArrayObject, ObjectType) {
2673	if (!window.SerializeValue__ArrayColl) window.SerializeValue__ArrayColl = new Array();
2674	window.SerializeValue__ArrayColl.push(ArrayObject);
2675	window.SerializeValue__ArrayColl.push(ObjectType);
2676}
2677function SerializeValue__ArrayColl_getArrayType(ArrayObject) {
2678	var cont1, fReturn;
2679	if (window.SerializeValue__ArrayColl) {
2680		for (cont1=0; cont1<window.SerializeValue__ArrayColl.length; cont1+=2) {
2681			if (window.SerializeValue__ArrayColl[cont1] === ArrayObject) {
2682				fReturn = window.SerializeValue__ArrayColl[cont1 + 1];
2683				break;
2684			}
2685		}
2686	}
2687	return fReturn;
2688}
2689
2690
2691
2692//####   GetHtmlControlValue   -   SetHtmlControlValue   ####
2693//####   Info-Data - Flavio Spezi - ver. 1.0	(17/11/2005)
2694//Leggono e scrivono il valore degli oggetti INPUT, TEXTAREA e SELECT. Parametri:
2695//		ControlObject:	è il riferimento all'oggetto oppure l'ID dell'oggetto. Se si tratta di INPUT type=radio,
2696//						il parametro può essere il riferimento ad uno degli oggetti INPUT type=radio del gruppo oppure il nome del
2697//						gruppo seguito dal nome del frame (es. FrmPrinc.OptSesso_M, 'OptSesso_F', 'FrmPrinc.OptSesso').
2698function GetHtmlControlValue(ControlObject, Checkbox_TrueFalse) {
2699	var obj, tipoCtrl, objForm;
2700	var tipoRadio_Nome, listaCtrl;
2701	var cont1;
2702	var fReturn = null;
2703	obj = ControlObject;
2704	if (typeof(obj) == 'string') {
2705		if (obj.indexOf('.') > -1) obj = obj.substr(obj.indexOf('.')+1);
2706		obj = findObj(obj);
2707		if (typeof(obj) != 'object' || !obj.tagName) obj = ControlObject;
2708	}
2709	switch (typeof(obj)) {
2710		case 'object':
2711			tipoCtrl = obj.tagName;
2712			if (tipoCtrl == 'INPUT') tipoCtrl += ' ' + obj.type.toLowerCase();
2713			break;
2714		case 'string':
2715			tipoCtrl = 'INPUT radio';
2716			break;
2717	}
2718	if (tipoCtrl != 'INPUT radio' && typeof(obj) != 'object') tipoCtrl = 'non valido';
2719	switch (tipoCtrl) {
2720		case 'INPUT checkbox':
2721			fReturn = ((obj.checked) ? obj.value : null);
2722			break;
2723		case 'INPUT hidden':
2724			fReturn = obj.value;
2725			break;
2726		case 'INPUT password':
2727			fReturn = obj.value;
2728			break;
2729		case 'INPUT radio':
2730			if (typeof(obj) == 'string') {
2731				objForm = findObj(obj.substr(0, obj.indexOf('.')));
2732				tipoRadio_Nome = obj.substr(obj.indexOf('.')+1).toLowerCase();
2733			} else {
2734				objForm = obj.form;
2735				tipoRadio_Nome = obj.name.toLowerCase();
2736			}
2737			listaCtrl = objForm.tags('INPUT');
2738			if (listaCtrl) {
2739				for (cont1 = 0; cont1 < listaCtrl.length; cont1++) {
2740					if (listaCtrl[cont1].type.toLowerCase() == 'radio'
2741							&& listaCtrl[cont1].name.toLowerCase() == tipoRadio_Nome
2742							&& listaCtrl[cont1].checked) {
2743						fReturn = listaCtrl[cont1].value;
2744						break;
2745					}
2746				}
2747			}
2748			break;
2749		case 'INPUT text':
2750			fReturn = obj.value;
2751			break;
2752		case 'SELECT':
2753			fReturn = obj.value;
2754			break;
2755		case 'TEXTAREA':
2756			fReturn = obj.value;
2757			break;
2758	}
2759	return fReturn;
2760}
2761//Stesso principio della procedura [GetHtmlControlValue]. Restituisce TRUE se l'operazione va a buon fine.
2762function SetHtmlControlValue(ControlObject, NewValue) {
2763	var obj, tipoCtrl, objForm;
2764	var tipoRadio_Nome, listaCtrl;
2765	var cont1, cont2;
2766	var fReturn = false;
2767	obj = ControlObject;
2768	if (typeof(obj) == 'string') {
2769		if (obj.indexOf('.') > -1) obj = obj.substr(obj.indexOf('.')+1);
2770		obj = findObj(obj);
2771		if (typeof(obj) != 'object' || !obj.tagName) obj = ControlObject;
2772	}
2773	switch (typeof(obj)) {
2774		case 'object':
2775			tipoCtrl = obj.tagName;
2776			if (tipoCtrl == 'INPUT') tipoCtrl += ' ' + obj.type.toLowerCase();
2777			break;
2778		case 'string':
2779			tipoCtrl = 'INPUT radio';
2780			break;
2781	}
2782	if (tipoCtrl != 'INPUT radio' && typeof(obj) != 'object') tipoCtrl = 'non valido';
2783	switch (tipoCtrl) {
2784		case 'INPUT checkbox':
2785			obj.checked = ((NewValue) ? true : false);
2786			fReturn = true;
2787			break;
2788		case 'INPUT hidden':
2789			obj.value = NewValue;
2790			fReturn = true;
2791			break;
2792		case 'INPUT password':
2793			obj.value = NewValue;
2794			fReturn = true;
2795			break;
2796		case 'INPUT radio':
2797			switch (typeof(obj)) {
2798				case 'string':
2799					objForm = findObj(obj.substr(0, obj.indexOf('.')));
2800					tipoRadio_Nome = obj.substr(obj.indexOf('.')+1).toLowerCase();
2801					break;
2802				case 'object':
2803					objForm = obj.form;
2804					tipoRadio_Nome = obj.name.toLowerCase();
2805					break;
2806			}
2807			listaCtrl = objForm.tags('INPUT');
2808			if (listaCtrl) {
2809				for (cont1 = 0; cont1 < listaCtrl.length; cont1++) {
2810					if (listaCtrl[cont1].type.toLowerCase() == 'radio'
2811							&& listaCtrl[cont1].name.toLowerCase() == tipoRadio_Nome
2812							&& listaCtrl[cont1].value == NewValue) {
2813						listaCtrl[cont1].checked = true;
2814						fReturn = true;
2815						break;
2816					}
2817				}
2818			}
2819			break;
2820		case 'INPUT text':
2821			obj.value = NewValue;
2822			fReturn = true;
2823			break;
2824		case 'SELECT':
2825			if (ValueType(NewValue) == 'Array') {
2826				obj.value = NewValue;
2827				if (obj.value == NewValue) {
2828					fReturn = true;
2829				} else {
2830					fReturn = 0;
2831					for (cont1=0; cont1<obj.options.length; cont1++) {
2832						for (cont2=0; cont2<NewValue.length; cont2++) {
2833							if (obj.options(cont1).value == NewValue[cont2]) {
2834								obj.options(cont1).selected = true;
2835								fReturn ++;
2836							}
2837						}
2838					}
2839					fReturn = (fReturn == NewValue.length);
2840				}
2841			} else {
2842				obj.value = NewValue;
2843				if (obj.value == NewValue) {
2844					fReturn = true;
2845				} else {
2846					fReturn = false;
2847					for (cont1=0; cont1<obj.options.length; cont1++) {
2848						if (obj.options(cont1).text == NewValue[cont2]) {
2849							obj.options(cont1).selected = true;
2850							fReturn = true;
2851							break;
2852						}
2853					}
2854				}
2855			}
2856			break;
2857		case 'TEXTAREA':
2858			obj.value = NewValue;
2859			fReturn = true;
2860			break;
2861		default:
2862			alert('Funzioni.js\n  function SetHtmlControlValue()\n    TipoCtrl non gestito: ' + tipoCtrl + '\n    Parametro ControlObject: ' + ControlObject);
2863	}
2864	return fReturn;
2865}
2866
2867
2868// ####  Funzioni di STANDARDIZZAZIONE BROWSERS  ##########
2869
2870// Associa una funzione all'evento di un oggetto
2871function addEvent(obj, evType, fn) {
2872	if (obj.addEventListener) {
2873		obj.addEventListener(evType, fn, false);
2874		return true;
2875	} else if (obj.attachEvent) {
2876		var r = obj.attachEvent('on' + evType, fn);
2877		return r;
2878	} else {
2879		return false;
2880	}
2881}
2882function removeEvent(obj, evType, fn) {
2883	if (obj.removeEventListener) {
2884		obj.removeEventListener(evType, fn, false);
2885		return true;
2886	} else if (obj.detachEvent) {
2887		var r = obj.detachEvent('on' + evType, fn);
2888		return r;
2889	} else {
2890		return false;
2891	}
2892}
2893function fireEvent(obj, evType) {
2894	var esisteEvento;
2895	if (obj.fireEvent) {
2896		obj.fireEvent('on' + evType);
2897	} else {
2898		eval('esisteEvento = obj.on' + evType + ';');
2899		if (esisteEvento) eval('esisteEvento = obj.on' + evType + '();');
2900	}
2901}
2902function findObj(idObject, optDocument) {
2903	var p, i, x;
2904	if (!optDocument) optDocument = document;
2905	if ((p = idObject.toString().indexOf('?')) > 0 && parent.frames.length) {
2906		optDocument = parent.frames[idObject.substring(p + 1)].document;
2907		idObject = idObject.substring(0, p);
2908	}
2909	if (!(x = optDocument[idObject]) && optDocument.getElementById) x = optDocument.getElementById(idObject);
2910	if (!x && optDocument.parentWindow) x = optDocument.parentWindow[idObject];
2911	if (!x && optDocument.defaultView) x = optDocument.defaultView[idObject];
2912	if (!x && optDocument.all) x = optDocument.all[idObject];
2913	if (!x && optDocument.forms) for (i=0; i < optDocument.forms.length; i++) x = optDocument.forms[i][idObject];
2914	if (!x && optDocument.layers) for (i=0; i < optDocument.layers.length; i++) x = findObj(idObject, optDocument.layers[i].document);
2915	return x;
2916}
2917function findParentObj(HtmlObject, optTagNameFilter, optAttribNameFilter, optAttribValueFilter, optStopObject) {
2918	//Restituisce il padre che risponde alle caratteristiche indicate. Se non trovato restituisce NULL. Argomenti:
2919	//	HtmlObject:				riferimento all'oggetto di cui si deve trovare il padre;
2920	//	optTagNameFilter:		(opzionale)(regExp o stringa) valore "tagName" che deve avere il padre da cercare;
2921	//	optAttribNameFilter:	(opzionale)(stringa) il padre deve avere tale attributo impostato;
2922	//	optAttribValueFilter:	(opzionale)(regExp o stringa) è il valore che deve avere l'attributi indicato con "optAttribNameFilter";
2923	//	optStopObject:			(opzionale)(tagName o HtmlObject) è l'oggetto su cui cessare la ricerca.
2924	var trovato, fncCerca, fineRicerca;
2925	var fReturn = HtmlObject;
2926	trovato = false;
2927	fineRicerca = false;
2928	fncCerca = function(Value, Filter) {
2929		switch (ValueType(Filter)) {
2930			case 'string':	return (Value == Filter ? true : false); break;
2931			case 'RegExp':	return (Value.search(Filter) > -1 ? true : false); break;
2932			default:		return false;
2933		}
2934	}
2935	while (fReturn.tagName && trovato == false && fineRicerca == false) {
2936		trovato = true;
2937		if (trovato && optTagNameFilter) trovato = fncCerca(fReturn.tagName, optTagNameFilter);
2938		if (trovato && optAttribNameFilter) trovato = (fReturn[optAttribNameFilter] ? true : false);
2939		if (trovato && optAttribNameFilter && optAttribValueFilter) trovato = fncCerca(fReturn[optAttribNameFilter], optAttribValueFilter);
2940		if (!trovato) {
2941			fReturn = fReturn.parentNode;
2942			if (optStopObject) {
2943				switch (ValueType(optStopObject)) {
2944					case 'Object':
2945						fineRicerca = (fReturn === optStopObject ? true : false);
2946						break;
2947					case 'String':
2948						fineRicerca = (fReturn.tagName == optStopObject ? true : false);
2949						break;
2950				}
2951			} else if (fReturn.tagName == 'BODY') {
2952				fineRicerca = true;
2953			}
2954		}
2955	}
2956	return (trovato ? fReturn : null);
2957}
2958
2959
2960// ####  [Traduci_Varchar_Read] ,  [Traduci_Varchar_Write] ,  [Traduci_Text_Read] ,  [Traduci_Text_Write]  ####
2961// ####  Info-Data Flavio Spezi (ver. 2.0 - 04/11/2005)  ###
2962// Procedure per la lettura e la scrittura in lingua.
2963// Parametri:
2964// 	MultilanguageSource   :	Può essere il [testo intero] in tutte le lingue oppure l'oggetto da cui prendere il valore:
2965// 							se il parametro è di tipo [Object], verrà prelevato il valore dell'attributo Value;
2966// 							se il parametro è una stringa essa verrà usata come [testo intero];
2967// 							per le funzioni Xxx_Write, nel caso in cui il parametro passato è un [Object], il risultato
2968// 							dell'elaborazione verrà salvato all'interno dell'oggetto; e in ogni caso verrà restituito come
2969// 							stringa dalla funzione.
2970// 	LanguageCode		  : il codice della lingua (es: IT, EN).
2971// 	LanguageIndex		  : l'indice di posizione della lingua (a partire da zero).
2972// 	LanguageSource		  : per le funzioni Xxx_Write, settare questo parametro col valore del testo nella lingua indicata;
2973// 							se il parametro è di tipo [Object], verrà prelevato il valore dell'attributo Value;
2974// 							se il parametro è una stringa essa verrà usata come [testo della lingua].
2975// 	CharsPerLanguage	  : caratteri messi a disposizione per ogni lingua. A differenza del programma analogo lato server,
2976//							qui non posso consentire l'uso del valore -1 (in automatico leggendo lungezza campo nel db) per
2977//							ovvi motivi.
2978function Traduci_Varchar_Read(MultilanguageSource, CharsPerLanguage, LanguageIndex) {
2979	var numCaratteri = toNumber(CharsPerLanguage, null, true);
2980	var indiceLingua = toNumber(LanguageIndex, null, true);
2981	var sorgenteIsObj = typeof(MultilanguageSource) == 'object';
2982	var sorgenteTesto = ((sorgenteIsObj) ? MultilanguageSource.value : MultilanguageSource);
2983	var fReturn = RTrim(sorgenteTesto.substr(numCaratteri * indiceLingua, numCaratteri));
2984	return fReturn;
2985}
2986function Traduci_Varchar_Write(MultilanguageSource, CharsPerLanguage, LanguageIndex, LanguageSource) {
2987	var numCaratteri = toNumber(CharsPerLanguage, null, true);
2988	var indiceLingua = toNumber(LanguageIndex, null, true);
2989	var sorgenteIsObj = typeof(MultilanguageSource) == 'object';
2990	var sorgenteTesto = ((sorgenteIsObj) ? MultilanguageSource.value : MultilanguageSource);
2991	var sorgenteLanIsObj = typeof(LanguageSource) == 'object';
2992	var sorgenteLanTesto = ((sorgenteLanIsObj) ? LanguageSource.value : LanguageSource);
2993	var fReturn;
2994	
2995	while (sorgenteTesto.length < numCaratteri * indiceLingua) sorgenteTesto += ' ';
2996	while (sorgenteLanTesto.length < numCaratteri) sorgenteLanTesto += ' ';
2997	fReturn = sorgenteTesto.substr(0, numCaratteri * indiceLingua) +
2998			sorgenteLanTesto + 
2999			sorgenteTesto.substr(numCaratteri * (indiceLingua + 1));
3000	if (sorgenteIsObj) MultilanguageSource.value = RTrim(fReturn);
3001	return fReturn;
3002}
3003function Traduci_Text_Read(MultilanguageSource, LanguageCode) {
3004	//#	Costanti utili che sono dichiarante in FUNZIONI.ASP : #
3005	//	Traduci_ChrLingua, Traduci_ChrFormatoTesto, Traduci_Lingue_DefaultIndex, Traduci_Lingue_DefaultCode, Traduci_FormatoTestoDefault
3006	var sorgenteIsObj = typeof(MultilanguageSource) == 'object';
3007	var sorgenteTesto = ((sorgenteIsObj) ? MultilanguageSource.value : MultilanguageSource);
3008	var posizIni, posizFine;
3009	var formatoTesto;
3010	var fReturn;
3011	//Leggo e rimuovo la definizione del FormatoTesto dalla stringa.
3012	formatoTesto = Traduci_GetFormatoTesto(sorgenteTesto);
3013	if (!formatoTesto) {
3014		formatoTesto = Traduci_FormatoTestoDefault;
3015	} else {
3016		sorgenteTesto = Traduci_RemoveFormatoTesto(sorgenteTesto);
3017	}
3018	
3019	//Se NON trovo nemmeno un [Traduci_ChrLingua], significa che il testo non ha alcuna formattazione di lingua,
3020	//quindi imposterò tutto il testo alla lingua default [Traduci_Lingue_DefaultCode].                
3021	if (sorgenteTesto.substr(0, Traduci_ChrLingua.length) != Traduci_ChrLingua) sorgenteTesto = Traduci_ChrLingua + Traduci_Lingue_DefaultCode + sorgenteTesto;
3022	
3023    posizIni = sorgenteTesto.indexOf(Traduci_ChrLingua + LanguageCode);
3024    if (posizIni == -1) {
3025		fReturn = '';
3026	} else {
3027		posizIni += Traduci_ChrLingua.length + LanguageCode.length;
3028		posizFine = sorgenteTesto.indexOf(Traduci_ChrLingua, posizIni);
3029		if (posizFine == -1) posizFine = sorgenteTesto.length;
3030		fReturn = sorgenteTesto.substr(posizIni, posizFine - posizIni);
3031	}
3032	return fReturn;
3033}
3034function Traduci_Text_Write(MultilanguageSource, LanguageCode, LanguageSource) {
3035	//#	Costanti utili che sono dichiarante in FUNZIONI.ASP : #
3036	//	Traduci_ChrLingua, Traduci_ChrFormatoTesto, Traduci_Lingue_DefaultIndex, Traduci_Lingue_DefaultCode, Traduci_FormatoTestoDefault
3037	var sorgenteIsObj = typeof(MultilanguageSource) == 'object';
3038	var sorgenteTesto = ((sorgenteIsObj) ? MultilanguageSource.value : MultilanguageSource);
3039	var sorgenteLanIsObj = typeof(LanguageSource) == 'object';
3040	var sorgenteLanTesto = ((sorgenteLanIsObj) ? LanguageSource.value : LanguageSource);
3041	var posizIni, posizFine;
3042	var formatoTesto;
3043	var fReturn;
3044	//Leggo e rimuovo la definizione del FormatoTesto dalla stringa.
3045	formatoTesto = Traduci_GetFormatoTesto(sorgenteTesto);
3046	if (!formatoTesto) {
3047		formatoTesto = Traduci_FormatoTestoDefault;
3048	} else {
3049		sorgenteTesto = Traduci_RemoveFormatoTesto(sorgenteTesto);
3050	}
3051	
3052	//Se NON trovo nemmeno un [Traduci_ChrLingua], significa che il testo non ha alcuna formattazione di lingua,
3053	//quindi imposterò tutto il testo alla lingua default [Traduci_Lingue_DefaultCode].                
3054	if (sorgenteTesto.substr(0, Traduci_ChrLingua.length) != Traduci_ChrLingua) sorgenteTesto = Traduci_ChrLingua + Traduci_Lingue_DefaultCode + sorgenteTesto;
3055	
3056	posizIni = sorgenteTesto.indexOf(Traduci_ChrLingua + LanguageCode);
3057	if (posizIni == -1) {
3058		fReturn = sorgenteTesto + Traduci_ChrLingua + LanguageCode + sorgenteLanTesto;
3059	} else {
3060		posizIni += Traduci_ChrLingua.length + LanguageCode.length;
3061		posizFine = sorgenteTesto.indexOf(Traduci_ChrLingua, posizIni);
3062		if (posizFine == -1) posizFine = sorgenteTesto.length;
3063		fReturn = sorgenteTesto.substr(0, posizIni) +
3064				sorgenteLanTesto +
3065				sorgenteTesto.substr(posizFine);
3066	}
3067	fReturn = Traduci_SetFormatoTesto(fReturn, formatoTesto);
3068	if (sorgenteIsObj) MultilanguageSource.value = fReturn;
3069	return fReturn;
3070}
3071function Traduci_GetFormatoTesto(textString) {
3072	//  Restituisce il FormatoTesto memorizzato nella stringa di testo passata come parametro.
3073	//  Se la stringa di testo non possiede un FormatoTesto definito, la funzione restituisce NULL.
3074	var fReturn = null;
3075    if (textString.substr(textString.length-2, 1) == Traduci_ChrFormatoTesto) {
3076		fReturn = textString.substr(textString.length-1, 1);
3077    }
3078    return fReturn;
3079}
3080function Traduci_SetFormatoTesto(textString, newTextFormat) {
3081	//  Restituisce il Testo con il FormatoTesto modificato.
3082	//  Se la stringa di testo non possiede un FormatoTesto definito, questo verrà aggiunto.
3083	var fReturn;
3084	fReturn = Traduci_RemoveFormatoTesto(textString) + Traduci_ChrFormatoTesto + newTextFormat.toString().substr(0, 1);
3085    return fReturn;
3086}
3087function Traduci_RemoveFormatoTesto(textString, newTextFormat) {
3088	//  Restituisce il Testo senza il FormatoTesto.
3089	//  Se la stringa di testo non possiede un FormatoTesto definito, la funzione restituisce il Testo intero del parametro.
3090	var fReturn;
3091    if (textString.substr(textString.length-2, 1) == Traduci_ChrFormatoTesto) {
3092		fReturn = textString.substr(0, textString.length - 2);
3093    } else {
3094		fReturn = textString;
3095    }
3096    return fReturn;
3097}
3098
3099function Traduci_Lingue_Count(){
3100	return Traduci_Lingue_List.length;
3101}
3102function Traduci_Lingue_Index(Code){
3103	var cont1;
3104	var fReturn;
3105	for (cont1 = 0; cont1 < Traduci_Lingue_Count(); cont1++){
3106		if (Traduci_Lingue_List[cont1] == Code){
3107			fReturn = cont1;
3108			break;
3109		}
3110	}
3111	return fReturn; 
3112}
3113function Traduci_Lingue_Code(Index){
3114	return Traduci_Lingue_List[Index];
3115}
3116function Traduci_Lingue_LCID(IndiceOCodiceLingua){
3117	var str1, fReturn;
3118	str1 = IndiceOCodiceLingua;
3119	switch(typeof(IndiceOCodiceLingua)){
3120		case 'number':
3121			str1 = Traduci_Lingue_Code(IndiceOCodiceLingua)
3122			break;
3123		case 'string':
3124			str1 = IndiceOCodiceLingua
3125			break;
3126	}
3127	if (str1 == ''){
3128		str1 = Lan;
3129	}
3130	switch (str1){
3131		case "IT":
3132			fReturn = 1040;		//1040 stà per la localizzazione italiana (formato data e ora, numerico ecc...)
3133			break;
3134		case "FR":
3135			fReturn = 1036;
3136			break;
3137		case "DE":
3138			fReturn = 1031;
3139			break;
3140		case "ES":	
3141			fReturn = 1034;
3142			break;
3143		case "RU":
3144			fReturn = 1049;
3145			break;
3146		case "GR": 
3147			fReturn = 1032;
3148			break;
3149		case "PR": 
3150			fReturn = 2070;
3151			break;
3152		default: 
3153			fReturn = 1033;
3154	}
3155	return  fReturn;
3156}
3157//######################################################################################
3158//####	Funzioni per la gestione dei DOMINI del sito (come nel file Funzioni.asp)	####
3159//######################################################################################
3160var Domini_Nomi_ArrayCacheValue;
3161function Domini_Nomi_ArrayCacheValue_Fill() {
3162	if (!Domini_Nomi_ArrayCacheValue) Domini_Nomi_ArrayCacheValue = Domini_Nomi_List.split(';');
3163}
3164function Domini_Nomi_Count() {
3165	Domini_Nomi_ArrayCacheValue_Fill();
3166	return Domini_Nomi_ArrayCacheValue.length;
3167}
3168function Domini_Nomi_Index(NomeDominio) {
3169	var str1, cont1;
3170	Domini_Nomi_ArrayCacheValue_Fill();
3171	str1 = NomeDominio.toString().toLowerCase();
3172	for (cont1=0; cont1<Domini_Nomi_ArrayCacheValue.length; cont1++) {
3173		if (str1 == Domini_Nomi_ArrayCacheValue[cont1]) return cont1;
3174	}
3175    return -1;
3176}
3177function Domini_Nomi_Name(IndiceDominio) {
3178	Domini_Nomi_ArrayCacheValue_Fill();
3179	return Domini_Nomi_ArrayCacheValue[IndiceDominio];
3180}
3181function Domini_Nomi_CurrentIndex() {
3182	return Domini_Nomi_Index(Domini_Nomi_CurrentName);
3183}
3184function Domini_Nomi_CurrentName() {
3185	var fReturn = window.location.hostname;
3186	if (window.location.port != DefaultProtocolIpPort(window.location.protocol)) fReturn += ':' + window.location.port;
3187	return fReturn;
3188}
3189function DefaultProtocolIpPort(Protocol) {
3190	switch (Protocol.toLowerCase()) {
3191		case 'http':		return 80;
3192		case 'https':		return 443;
3193		case 'ftp':			return 21;
3194		case 'smtp':		return 25;
3195		case 'pop3':		return 110;
3196		case 'imap':		return 143;
3197		case 'nntp':		return 119;
3198		case 'snmp':		return 161;
3199		case 'irc':			return 194;
3200		case 'sqlserver':	return 1433;
3201		case 'mysql':		return 3306;
3202		case 'pptp':		return 1723;			//Point to Point Tunneling Protocol
3203		case 'telnet':		return 23;
3204		case 'rdp':			return 3389;			//Remote Desktop Protocol
3205		case 'vnc':			return 5900;
3206		default:			return -1;
3207	}
3208}
3209
3210
3211//#################################
3212//####  Funzioni di HTML PLUS  ####
3213//#################################
3214
3215
3216//Procedure per aggiungere funzionalità ad oggetti Html
3217
3218
3219function HtmlPlus_Positionator(ID, Object, RelativeOf, Direction, Properties, DynamicMode, optRelOfBoxSizing) {
3220	/*Riposiziona/Ridimensiona l'oggetto indicato dinamicamente. Argomenti:
3221		ID :			valore ID dell'oggetto.
3222		Object :		l'oggetto da posizionare e/o ridimensionare.
3223		RelativeOf :	l'oggetto su cui basare i calcoli; può essere:  [window] rispetto alla visualizzazione corrente,  [document] rispetto all'intero
3224						documento,  <oggetto HTML> rispetto all'oggetto indicato (es. INPUT),  NULL rispetto al puntatore del mouse.
3225		Direction :		indica dove posizionare l'oggetto; può essere:  'IN' all'interno di [RelativeOf],  'SE' (sta per SOUTH-EAST) si deve posizionare
3226						sotto a [RelativeOf] allineato a sinistra,  'ES' (sta per EAST-SOUTH) si deve posizionare a destra di [RelativeOf] allineato
3227						in alto,  <altre combinazioni di N, S, E, W> ...,   'S' (sta per SOUTH) sotto a [RelativeOf] allineato al centro,
3228						N/E/W ...analogo, stessa cosa.
3229		Properties :	collection di valori per [style], in stile JavaScript. Le definizioni ammesse sono:  left, top, right, bottom, width, minWidth,
3230						maxWidth, height, minHeight, maxHeight, marginLeft, marginTop, marginRight, marginBottom;
3231						le definizioni 'left' e 'top' possono essere settate anche con valori percentuali: così facendo si indica che [Object] dovrà
3232						posizionarsi a tale percentuale rispetto a 'width'/'height' di [RelativeOf];
3233						alle definizioni standard si aggiungono:  position1, position2, margin1, margin2; queste possono essere usate al posto di
3234						left, top, marginXxxx quando si vuole indicare il valore di posizione/margine del primo o secondo punto cardinale; es. indicando
3235						la proprietà "position2=10px" e "Direction='SE'" si indica che [Object] sarà sotto a [RelativeOf], allineato a sinistra, e
3236						spostato di 10px verso destra; se "DynamicMode='visible'" e si determina che [Object] non sarebbe visibile con "Direction='SE'",
3237						allora l'opzione [DynamicMode] prevede che [Direction] diventa 'SW', quindi la posizione sarà sotto, allineato a destra, e
3238						spostato di 10px; i valori indicati in queste definizioni verrà sommato a quello indicato alle definizioni standard.
3239		DynamicMode :	modalità di calcolo dinamico degli attributi; può essere:
3240							NULL funzionalità disattivata, la posizione/dimensione viene determinata in base ai parametri indicati;
3241							'onetime' la posizione/dimensione viene determinata una sola volta, su lancio di [Run], e Direction viene modificato se
3242									l'oggetto non è immediatamente visibile;
3243							'onredraw' la posizione/dimensione viene ricalcolata in conseguenza ad una modifica di posizione o dimensione di [RelativeOf]:
3244							'visible' la posizione/dimensione (come per 'onredraw') viene ricalcolata su modifica di [RelativeOf] e in più se [Object] non
3245									è immediatamente visibile viene modificando l'argomento [Direction] con un valore più appropriato.
3246		optRelOfBoxSizing :		valore attributo [boxSizing] per l'oggetto [RelativeOf], indica il modo con cui viene determinata la posizione e la
3247						dimensione dell'oggetto per determinare la posizione di [Object]; se non indicato verrà considerato 'border-box' se [Direction]
3248						è settato con punti cardinali (es. 'SE', 'NE', 'E'...), e 'content-box' negli altri casi.
3249		*/
3250	this.id = ID;
3251	this.objectType = 'HtmlPlus_Positionator';			// Tipo di oggetto HtmlPlus
3252	this.object = Object;
3253	this.relativeOf = RelativeOf;
3254	this.direction = null;
3255	this.properties = Properties;
3256	this.dynamicMode = null;
3257	this.relativeOfBoxSizing = null;	this._relativeOfBoxSizing = null;		//Il primo contiene il valore di argomento, il secondo quello che verrà usato dalla classe
3258	this._html = null;
3259	this._htmlScroll = null;	//indicherà i valori scrollLeft e scrollTop in relazione a [Object]
3260	this._status = null;
3261
3262	if (!window.HtmlPlus_PositionatorColl) window.HtmlPlus_PositionatorColl = new Array();
3263	window.HtmlPlus_PositionatorColl[this.id] = this;
3264	
3265	this._initialize = function() {
3266		//Caricamento variabili di configurazione
3267		this.direction = 'IN';
3268		if (Direction) {
3269			if (Direction.search(/^(IN|NE|NW|SE|SW|WN|WS|EN|ES|N|E|S|W)$/i) >= 0) this.direction = Direction.toUpperCase();
3270		}
3271		this.dynamicMode = null;
3272		if (DynamicMode) {
3273			if (DynamicMode.search(/^(onredraw|visible)$/i) >= 0) this.dynamicMode = DynamicMode.toLowerCase();
3274		}
3275		this.relativeOfBoxSizing = null;
3276		if (optRelOfBoxSizing) {
3277			if (optRelOfBoxSizing.search(/^(border-box|content-box)$/i) >= 0) this.relativeOfBoxSizing = optRelOfBoxSizing.toLowerCase();
3278		}
3279		this._relativeOfBoxSizing = this.relativeOfBoxSizing;
3280		if (!this._relativeOfBoxSizing) {
3281			this._relativeOfBoxSizing = (this.direction == 'IN' ? 'content-box' : 'border-box');
3282		}
3283		this._status = 'stop';
3284	}
3285	this._initialize_setBody = function() {
3286		//Caricamento variabili di funzionamento
3287		this._html = GetDocInfo(this.object, 'RootElement');
3288		this._htmlScroll = {left:0, top:0};
3289		switch (GetCssStyle(this.object, 'position')) {
3290			case 'absolute':
3291				this._htmlScroll.left = this._html.scrollLeft;
3292				this._htmlScroll.top = this._html.scrollTop;
3293				break;
3294			case 'fixed':
3295				this._htmlScroll.left = 0;
3296				this._htmlScroll.top = 0;
3297				break;
3298		}
3299	}
3300	this._addValue = function(CurrentValue, Operation_Sum_Subtract, NewValue, RelativeOfSize) {
3301		var operazione, valore, fReturn;
3302		fReturn = CurrentValue;
3303		switch (Operation_Sum_Subtract) {
3304			case '+': case 'sum':		operazione = 1; break;
3305			case '-': case 'subtract':	operazione = -1; break;
3306			default:			operazione = 0; break;
3307		}
3308		if (!IsUndefined(NewValue) && NewValue !== null) {
3309			valore = GetValue(NewValue);
3310			if (valore.number > 0 || valore.number < 0) {
3311				if (valore.um == '%') {
3312					fReturn += (RelativeOfSize * valore.number / 100) * operazione;
3313				} else {
3314					fReturn += valore.number * operazione;
3315				}
3316			}
3317		}
3318		return fReturn;
3319	}
3320	this._getObjInfo = function(Object) {
3321		var cont1, cont2, fReturn;
3322		fReturn = {left:null, top:null, width:null, height:null};
3323		fReturn.left = getPos(Object, 'left');
3324		fReturn.top = getPos(Object, 'top');
3325		fReturn.width = Object.offsetWidth;
3326		fReturn.height = Object.offsetHeight;
3327		//FORSE DEVO VERIFICARE IL VALORE DI QUESTO ATTRIBUTO PER RITOCCARE I VALORI OTTENUTI?  -->		switch (Object.style.position) {	}
3328		switch (this._relativeOfBoxSizing) {
3329			case 'border-box':
3330				break;
3331			case 'content-box':
3332				cont1 = 0;
3333				cont2 = 0;
3334				if (Object.style.borderLeftWidth > 0) cont1 += Object.style.borderLeftWidth;
3335				if (Object.style.borderRightWidth > 0) cont2 += Object.style.borderRightWidth;
3336				if (Object.style.paddingLeft > 0) cont1 += Object.style.paddingLeft;
3337				if (Object.style.paddingRight > 0) cont2 += Object.style.paddingRight;
3338				fReturn.left -= cont1;
3339				fReturn.width -= (cont1 + cont2);
3340				cont1 = 0;
3341				cont2 = 0;
3342				if (Object.style.borderTopWidth > 0) cont1 += Object.style.borderTopWidth;
3343				if (Object.style.borderBottomWidth > 0) cont2 += Object.style.borderBottomWidth;
3344				if (Object.style.paddingTop > 0) cont1 += Object.style.paddingTop;
3345				if (Object.style.paddingBottom > 0) cont2 += Object.style.paddingBottom;
3346				fReturn.top -= cont1;
3347				fReturn.height -= (cont1 + cont2);
3348				break;
3349		}
3350		return fReturn;
3351	}
3352	this.Run = function() {
3353		var direzione, numProva, calcolo;
3354		if (this._status == 'stop') {
3355			if (this.object) {
3356				//Calcolo i valori per [Object]
3357				this._initialize_setBody();
3358				direzione = this.direction;
3359				numProva = 0;
3360				do {
3361					calcolo = this.CalculateAttributes(direzione);
3362					if (this.IsVisible(calcolo.left, calcolo.top, calcolo.width, calcolo.height)) break;
3363					switch (numProva) {
3364						case 0:	case 2:
3365							switch (direzione.substr(direzione.length-1, 1)) {
3366								case 'N':	direzione = direzione.substr(direzione.length-2, 1) + 'S'; break;
3367								case 'S':	direzione = direzione.substr(direzione.length-2, 1) + 'N'; break;
3368								case 'E':	direzione = direzione.substr(direzione.length-2, 1) + 'W'; break;
3369								case 'W':	direzione = direzione.substr(direzione.length-2, 1) + 'E'; break;
3370							}
3371							break;
3372						case 1: case 3:
3373							switch (direzione.substr(0, 1)) {
3374								case 'N':	direzione = 'S' + this.direction.substr(1, 1); break;
3375								case 'S':	direzione = 'N' + this.direction.substr(1, 1); break;
3376								case 'E':	direzione = 'W' + this.direction.substr(1, 1); break;
3377								case 'W':	direzione = 'E' + this.direction.substr(1, 1); break;
3378							}
3379							break;
3380					}
3381					numProva += 1;
3382				} while (direzione != 'IN' && numProva < 4 && this.dynamicMode !== null);
3383				//Applico i valori
3384				if (calcolo.left !== null) this.object.style.left = calcolo.left.toString() + 'px';
3385				if (calcolo.top !== null) this.object.style.top = calcolo.top.toString() + 'px';
3386				if (calcolo.width !== null) this.object.style.width = calcolo.width.toString() + 'px';
3387				if (calcolo.height !== null) this.object.style.height = calcolo.height.toString() + 'px';
3388				//Attacco gli eventi
3389				//	DA IMPLEMENTARE
3390				
3391				//Setto lo stato
3392				switch (this.dynamicMode) {
3393					case 'onredraw':
3394					case 'visible':
3395						this._status = 'run';
3396						break;
3397				}
3398			}
3399		}
3400	}
3401	this.Stop = function() {
3402		//Disattivo gli eventi
3403		//	DA IMPLEMENTARE
3404		//Setto lo stato
3405		this.status = 'stop';
3406	}
3407	this.CalculateAttributes = function(Direction) {
3408		//Calcola gli attributi 'left','top','width','height' per [Object] per la [Direction] indicata
3409		var relativeOfInfo = {left:null, top:null, width:null, height:null};
3410		var objectInfo = {width:null, height:null};
3411		var fReturn = {left:null, top:null, width:null, height:null};
3412		var cont1, cont2, dict1;
3413		//Determino i valori di [relativeOfInfo]
3414		if (ValueType(this.relativeOf) == 'Array') {
3415			for (cont1 in this.relativeOf) {
3416				dict1 = this._getObjInfo(this.relativeOf[cont1]);
3417				dict1.right = dict1.width + dict1.left;
3418				dict1.bottom = dict1.height + dict1.top;
3419				if (!relativeOfInfo) {
3420					relativeOfInfo = dict1;
3421				} else {
3422					switch (this._relativeOfBoxSizing) {
3423						case 'border-box':
3424							if (relativeOfInfo.left > dict1.left) relativeOfInfo.left = dict1.left;
3425							if (relativeOfInfo.top > dict1.top) relativeOfInfo.top = dict1.top;
3426							if (relativeOfInfo.right < dict1.right) relativeOfInfo.right = dict1.right;
3427							if (relativeOfInfo.bottom < dict1.bottom) relativeOfInfo.bottom = dict1.bottom;
3428							break;
3429						case 'content-box':
3430							if (relativeOfInfo.left < dict1.left) relativeOfInfo.left = dict1.left;
3431							if (relativeOfInfo.top < dict1.top) relativeOfInfo.top = dict1.top;
3432							if (relativeOfInfo.right > dict1.right) relativeOfInfo.right = dict1.right;
3433							if (relativeOfInfo.bottom > dict1.bottom) relativeOfInfo.bottom = dict1.bottom;
3434							break;
3435					}
3436				}
3437			}
3438			relativeOfInfo.width = relativeOfInfo.right - relativeOfInfo.left;
3439			relativeOfInfo.height = relativeOfInfo.bottom - relativeOfInfo.top;
3440			relativeOfInfo.right = void(0);
3441			relativeOfInfo.bottom = void(0);
3442		} else {
3443			relativeOfInfo = this._getObjInfo(this.relativeOf);
3444		}
3445		/* è già presente in [this._getObjInfo]
3446			//FORSE DEVO VERIFICARE IL VALORE DI QUESTO ATTRIBUTO PER RITOCCARE I VALORI OTTENUTI?  -->		switch (this.relativeOf.style.position) {	}
3447			switch (this._relativeOfBoxSizing) {
3448				case 'border-box':
3449					break;
3450				case 'content-box':
3451					cont1 = 0;
3452					cont2 = 0;
3453					if (this.relativeOf.style.borderLeftWidth > 0) cont1 += this.relativeOf.style.borderLeftWidth;
3454					if (this.relativeOf.style.borderRightWidth > 0) cont2 += this.relativeOf.style.borderRightWidth;
3455					if (this.relativeOf.style.paddingLeft > 0) cont1 += this.relativeOf.style.paddingLeft;
3456					if (this.relativeOf.style.paddingRight > 0) cont2 += this.relativeOf.style.paddingRight;
3457					relativeOfInfo.left -= cont1;
3458					relativeOfInfo.width -= (cont1 + cont2);
3459					cont1 = 0;
3460					cont2 = 0;
3461					if (this.relativeOf.style.borderTopWidth > 0) cont1 += this.relativeOf.style.borderTopWidth;
3462					if (this.relativeOf.style.borderBottomWidth > 0) cont2 += this.relativeOf.style.borderBottomWidth;
3463					if (this.relativeOf.style.paddingTop > 0) cont1 += this.relativeOf.style.paddingTop;
3464					if (this.relativeOf.style.paddingBottom > 0) cont2 += this.relativeOf.style.paddingBottom;
3465					relativeOfInfo.top -= cont1;
3466					relativeOfInfo.height -= (cont1 + cont2);
3467					break;
3468			}
3469		*/
3470		//Determino i valori 'width' e 'height' per [fReturn]
3471		if (!IsUndefined(this.properties['width'])) {
3472			fReturn.width = this._addValue(0, '+', this.properties['width'], relativeOfInfo.width);
3473			if (!IsUndefined(this.properties['minWidth'])) {
3474				cont1 = this._addValue(0, '+', this.properties['minWidth'], relativeOfInfo.width);
3475				if (cont1 > fReturn.width) fReturn.width = cont1;
3476			}
3477			if (!IsUndefined(this.properties['maxWidth'])) {
3478				cont1 = this._addValue(0, '+', this.properties['maxWidth'], relativeOfInfo.width);
3479				if (cont1 < fReturn.width) fReturn.width = cont1;
3480			}
3481		}
3482		if (!IsUndefined(this.properties['height'])) {
3483			fReturn.height = this._addValue(0, '+', this.properties['height'], relativeOfInfo.height);
3484			if (!IsUndefined(this.properties['minHeight'])) {
3485				cont1 = this._addValue(0, '+', this.properties['minHeight'], relativeOfInfo.height);
3486				if (cont1 > fReturn.height) fReturn.height = cont1;
3487			}
3488			if (!IsUndefined(this.properties['maxHeight'])) {
3489				cont1 = this._addValue(0, '+', this.properties['maxHeight'], relativeOfInfo.height);
3490				if (cont1 < fReturn.height) fReturn.height = cont1;
3491			}
3492		}
3493		//Setto le info per [objectInfo]
3494		objectInfo.width = this.object.offsetWidth;
3495		if (fReturn.width > 0) {
3496			objectInfo.width = fReturn.width;
3497			//DA IMPLEMENTARE	-->		sommare bordo e padding
3498		}
3499		objectInfo.height = this.object.offsetHeight;
3500		if (fReturn.height > 0) {
3501			objectInfo.height = fReturn.height;
3502			//DA IMPLEMENTARE	-->		sommare bordo e padding
3503		}
3504		//Leggendo [Direction], determino un primo stadio di valori 'left' e 'top' per [fReturn]
3505		switch (Direction) {
3506			case 'IN':
3507				fReturn.left = relativeOfInfo.left;
3508				fReturn.top = relativeOfInfo.top;
3509				break;
3510			default:
3511				switch (Direction.substr(0, 1)) {
3512					case 'N':	fReturn.top = relativeOfInfo.top - objectInfo.height; break;
3513					case 'E':	fReturn.left = relativeOfInfo.left + relativeOfInfo.width; break;
3514					case 'S':	fReturn.top = relativeOfInfo.top + relativeOfInfo.height; break;
3515					case 'W':	fReturn.left = relativeOfInfo.left - objectInfo.width; break;
3516				}
3517				switch (Direction.substr(1, 1)) {
3518					case 'N':	fReturn.top = relativeOfInfo.top + relativeOfInfo.height - objectInfo.height; break;
3519					case 'E':	fReturn.left = relativeOfInfo.left; break;
3520					case 'S':	fReturn.top = relativeOfInfo.top; break;
3521					case 'W':	fReturn.left = relativeOfInfo.left + relativeOfInfo.width - objectInfo.width; break;
3522					default:
3523						switch (Direction.substr(0, 1)) {
3524							case 'N': case 'S':	fReturn.left = relativeOfInfo.left + (relativeOfInfo.width - objectInfo.width) / 2; break;
3525							case 'E': case 'W':	fReturn.top = relativeOfInfo.top + (relativeOfInfo.height - objectInfo.height) / 2; break;
3526						}
3527				}
3528				//Cerco property 'position1/2' e 'margin1/2' e modifico 'left' e 'top' di [fReturn]
3529				switch (Direction.substr(0, 1)) {
3530					case 'N':	fReturn.top = this._addValue(fReturn.top, '-', this.properties['position1'], relativeOfInfo.height); break;
3531					case 'E':	fReturn.left = this._addValue(fReturn.left, '+', this.properties['position1'], relativeOfInfo.width); break;
3532					case 'S':	fReturn.top = this._addValue(fReturn.top, '+', this.properties['position1'], relativeOfInfo.height); break;
3533					case 'W':	fReturn.left = this._addValue(fReturn.left, '-', this.properties['position1'], relativeOfInfo.width); break;
3534				}
3535				switch (Direction.substr(0, 1)) {
3536					case 'N':	fReturn.top = this._addValue(fReturn.top, '-', this.properties['margin1'], relativeOfInfo.height); break;
3537					case 'E':	fReturn.left = this._addValue(fReturn.left, '+', this.properties['margin1'], relativeOfInfo.width); break;
3538					case 'S':	fReturn.top = this._addValue(fReturn.top, '+', this.properties['margin1'], relativeOfInfo.height); break;
3539					case 'W':	fReturn.left = this._addValue(fReturn.left, '-', this.properties['margin1'], relativeOfInfo.width); break;
3540				}
3541				switch (Direction.substr(1, 1)) {
3542					case 'N':	fReturn.top = this._addValue(fReturn.top, '-', this.properties['position2'], relativeOfInfo.height); break;
3543					case 'E':	fReturn.left = this._addValue(fReturn.left, '+', this.properties['position2'], relativeOfInfo.width); break;
3544					case 'S':	fReturn.top = this._addValue(fReturn.top, '+', this.properties['position2'], relativeOfInfo.height); break;
3545					case 'W':	fReturn.left = this._addValue(fReturn.left, '-', this.properties['position2'], relativeOfInfo.width); break;
3546				}
3547				switch (Direction.substr(1, 1)) {
3548					case 'N':	fReturn.top = this._addValue(fReturn.top, '-', this.properties['margin2'], relativeOfInfo.height); break;
3549					case 'E':	fReturn.left = this._addValue(fReturn.left, '+', this.properties['margin2'], relativeOfInfo.width); break;
3550					case 'S':	fReturn.top = this._addValue(fReturn.top, '+', this.properties['margin2'], relativeOfInfo.height); break;
3551					case 'W':	fReturn.left = this._addValue(fReturn.left, '-', this.properties['margin2'], relativeOfInfo.width); break;
3552				}
3553				//Se "this.object.style.position == 'fixed'" allora...
3554				if (this.object.style.position == 'fixed') {
3555					fReturn.top -= this._html.scrollTop;
3556					fReturn.left -= this._html.scrollLeft;
3557				}
3558		}
3559		//Cerco property e modifico 'left' e 'top' di [fReturn]
3560		fReturn.left = this._addValue(fReturn.left, '+', this.properties['left'], relativeOfInfo.width);
3561		fReturn.left = this._addValue(fReturn.left, '-', this.properties['right'], relativeOfInfo.width);		//Questo attributo và implementato diversamente: se DIRECTION='IN' allora RIGHT=10px significa che si deve posizionare a 10px dal bordo destro.
3562		fReturn.left = this._addValue(fReturn.left, '+', this.properties['marginLeft'], relativeOfInfo.width);
3563		fReturn.left = this._addValue(fReturn.left, '-', this.properties['marginRight'], relativeOfInfo.width);
3564		fReturn.top = this._addValue(fReturn.top, '+', this.properties['top'], relativeOfInfo.height);
3565		fReturn.top = this._addValue(fReturn.top, '-', this.properties['bottom'], relativeOfInfo.height);		//Questo.... (vedi attributo RIGHT qui sopra).
3566		fReturn.top = this._addValue(fReturn.top, '+', this.properties['marginTop'], relativeOfInfo.height);
3567		fReturn.top = this._addValue(fReturn.top, '-', this.properties['marginBottom'], relativeOfInfo.height);
3568		//Fine calcoli
3569		return fReturn;
3570	}
3571	this.IsVisible = function(Left, Top, Width, Height) {
3572		//Restituisce TRUE se [Object], per la posizione e dimensione indicate negli argomenti, sarà visibile sul browser
3573		var valWidth = (Width !== null ? Width : this.object.offsetWidth);
3574		var valHeight = (Height !== null ? Height : this.object.offsetHeight);
3575		var fReturn = true;
3576		if (fReturn) if (this._htmlScroll.top > Top) fReturn = false;
3577		if (fReturn) if (this._htmlScroll.left > Left) fReturn = false;
3578		if (fReturn) if (this._htmlScroll.top + this._html.clientHeight < Top + valHeight) fReturn = false;
3579		if (fReturn) if (this._htmlScroll.left + this._html.clientWidth < Left + valWidth) fReturn = false;
3580		return fReturn;
3581	}
3582	this.Status = function() {
3583		return this._status;
3584	}
3585	
3586	this._initialize();
3587	return this;
3588}
3589
3590
3591
3592
3593
3594function HtmlPlus_SlideShow(IdObject, BackGroundColor, ObjContainer, ImagesPath, ZoomType, PermanenceTime, TransactionTime, TransactionStyle, TransactionType, Fps){
3595	// Questa funzione serve per meccanizzare gli SlideShow in modo da non dover ogni volta ricominciare daccapo.
3596	// Gestisce 3 tipi di transazioni : trasparenza, transazione verticale, trasazione orizzontale. Sar possibile aggiungerne altre.
3597	// Ci sono per dei bug da risolvere che riguardano l'utilizzo non standard dei browser riguardo ad alcuni attributi di stile
3598	//	degli oggetti html come left, top, zIndex che sono da verificare bene.
3599	this.id = IdObject;								// Id dell'oggetto HtmlPlus
3600	this.objectType = 'HtmlPlus_SlideShow';			// Tipo di oggetto
3601	this.objectContainer = ObjContainer;			// Oggetto che contiene le immagini da visualizzare in slideshow
3602	this.imagesCollection = null;					// Array di path di immagini da visualizzare
3603	this.zoomType = ZoomType;						// Pu essere 'Fixed', 'Min' 'Max'
3604	this.permanenceTime = PermanenceTime;			// Durata della visualizzazione dell'immagine (in secondi); comprende anche il tempo di scambio.
3605	this.transactionTime = TransactionTime;			// Durata dello scambio (in secondi)
3606	this.transactionStyle = TransactionStyle;		// Style di transazione['opacity', 'left-right', 'right-left', 'top-bottom', 'bottom-top']
3607	this.transactionType = TransactionType;			// Tipo di transazione['sin', 'cos', 'square', 'triangle']
3608	this.transactionStyleFF = 'auto';				// Style di transazione per passare da una immagine successiva ad una precedente.
3609	this.preloadTimeout = 5;						// Tempo massimo per il preload di una immagine (in secondi)
3610	this.fps = Fps;									// Fotogrammi per secondo della transazione.
3611	this.repeat = true;								// se [False] alla fine del ciclo si ferma. se [True] ricomincia da capo
3612	this.startMethod = 'image';						// Puo essere ['image', 'transaction', '<url-img>']
3613	this.transactionMaker = null;					// Oggetto transazione per passare da una immagine ad un'altra.
3614	this.transactionMakerFF = null;					// (opzionale) Oggetto transazione per passare da una immagine successiva ad una precedente.
3615	this.backgroundColor = BackGroundColor;
3616	
3617	if (!window.HtmlPlus_SlideShowColl) window.HtmlPlus_SlideShowColl = new Array();
3618	window.HtmlPlus_SlideShowColl[this.id] = this;
3619	
3620	this._initialize = function() {
3621		var cont1;
3622		
3623		switch (this.zoomType.toLowerCase()) {
3624			case 'fixed':
3625			case 'min':
3626			case 'max':
3627				this.zoomType = this.zoomType.toLowerCase();
3628				break;
3629			default:
3630				this.zoomType = 'fixed';
3631				break;
3632		}
3633		
3634		if (this.permanenceTime < this.transactionTime) this.permanenceTime = this.transactionTime;
3635		
3636		switch (this.transactionStyle.toLowerCase()) {
3637			case 'opacity':
3638			case 'right-left':
3639			case 'left-right':
3640			case 'top-bottom':
3641			case 'bottom-top':
3642			case 'test':
3643				this.transactionStyle = this.transactionStyle.toLowerCase();
3644				break;
3645			default:
3646				this.transactionStyle = 'opacity';
3647				break;
3648		}
3649		if (ValueType(ImagesPath) == 'Array') {
3650			switch (ValueType(ImagesPath[0])) {
3651				case 'Object':
3652					// Gli elementi [Oggetto] devono avere gli attributi "alt", "src" e "onClick".
3653					this.imagesCollection = ImagesPath;
3654					break;
3655				case 'string':
3656					this.imagesCollection = new Array();
3657					for (cont1=0; cont1 < ImagesPath.length; cont1++) {
3658						this.imagesCollection.push( {src:ImagesPath[cont1], width:null, height:null, alt:'', onClick:''} );
3659					}
3660					break;
3661			}
3662		}
3663		if (ValueType(ImagesPath) != 'Array') this.imagesCollection = new Array();
3664		
3665		if (!this.fps) this.fps = GetBrowserInfo('RecommendedFps');
3666		
3667		if (typeof(this.objectContainer) == 'string') this.objectContainer = findObj(this.objectContainer);
3668		this.objectContainer.style.overflow = 'hidden';
3669		
3670		this.objectContainer_width = toNumber(GetProperty(this.objectContainer, 'clientWidth')) / (this.transactionStyle == 'test' ? 10 : 1);
3671		this.objectContainer_height = toNumber(GetProperty(this.objectContainer, 'clientHeight')) / (this.transactionStyle == 'test' ? 10 : 1);
3672		
3673		this._div1 = null;
3674		this._div2 = null;
3675		this._img_srcNone = '/images/shim.gif';
3676		this._img1 = null;
3677		this._img2 = null;
3678		this._imgLoad = null;
3679		this._currentPosition = 0;
3680		this._status = 'stop';
3681		this._tmr = null;
3682	}
3683	
3684	this._buildObjects = function(){
3685		var str1;
3686		
3687		// Se il comando era già stato eseguito allora esco dalla funzione.
3688		if (this._div1) return false;
3689		
3690		// Creo gli oggetti
3691		this._div1 = document.createElement('div');
3692		this._div2Base = document.createElement('div');
3693		this._div2 = document.createElement('div');
3694		this._img1 = document.createElement('img');
3695		this._img2 = document.createElement('img');
3696		this._div1.appendChild(this._img1);
3697		this._div2.appendChild(this._img2);
3698		this._div2Base.appendChild(this._div2);
3699		this.objectContainer.appendChild(this._div1);
3700		this.objectContainer.appendChild(this._div2Base);
3701		
3702		// Creo ed inizializzo l'immagine che mi serve per ridimensionare le immagini da mostrare
3703		this._imgLoad = document.createElement('img');
3704		this._imgLoad._HtmlPlus_SlideShowObj = this;
3705		this._imgLoad.style.visibility = 'hidden';
3706		addEvent(this._imgLoad, 'load', this._imgLoad_onLoad);
3707		
3708		this._div3 = document.createElement('div');
3709		this.objectContainer.appendChild(this._div3);
3710		this._div3.appendChild(this._imgLoad);
3711		
3712		// Inizializzo i div assegnandogli le giuste proprietà.
3713		//Il DIV1:  contenitore dell'immagine corrente, e durante la transazione contiene l'immagine che se ne va.
3714		this._div1.style.position = 'relative';
3715		this._div1.style.width = this.objectContainer_width.toString() + 'px';
3716		this._div1.style.height = this.objectContainer_height.toString() + 'px';
3717		this._div1.style.padding = '0 0 0 0';
3718		this._div1.style.overflow = 'hidden';
3719		this._div1.style.visibility = 'hidden';
3720		this._div1.style.zIndex = 1;
3721		this._div1.style.backgroundColor = this.backgroundColor;
3722		//Il DIV2: contenitore dell'immagine nuova, per il periodo della transazione. Dopodichè questo DIV verrà nascosto, e l'immagine contenuta passerà a DIV1.
3723		this._div2.style.position = 'relative';
3724		this._div2.style.width = this.objectContainer_width.toString() + 'px';
3725		this._div2.style.height = this.objectContainer_height.toString() + 'px';
3726		this._div2.style.padding = '0 0 0 0';
3727		this._div2.style.overflow = 'hidden';
3728		this._div2.style.visibility = 'visible';
3729		this._div2.style.zIndex = 3;
3730		this._div2.style.backgroundColor = this.backgroundColor;
3731		//Il DIV2BASE: padre di DIV2. Serve per risolvere problemi di posizionamento di DIV2.
3732		this._div2Base.style.position = 'relative';
3733		this._div2Base.style.width = this.objectContainer_width.toString() + 'px';
3734		this._div2Base.style.height = this.objectContainer_height.toString() + 'px';
3735		this._div2Base.style.padding = '0 0 0 0';
3736		this._div2Base.style.overflow = 'hidden';
3737		this._div2Base.style.left = '0px';
3738		this._div2Base.style.top = - toNumber(this.objectContainer_height) + 'px';
3739		this._div2Base.style.display = 'none';
3740		this._div2Base.style.zIndex = 2;
3741		this._div2Base.style.backgroundColor = 'transparent';
3742		
3743		this._img1.style.position = 'relative';
3744		this._img1.alt = '';
3745		this._img2.style.position = 'relative';
3746		this._img2.alt = '';
3747		
3748		if (this.zoomType == 'fixed') {
3749			this._img1.style.width = this.objectContainer_width.toString() + 'px';
3750			this._img1.style.height = this.objectContainer_height.toString() + 'px';
3751			this._img1.style.left = '0px';
3752			this._img1.style.top = '0px';
3753			this._img2.style.width = this.objectContainer_width.toString() + 'px';
3754			this._img2.style.height = this.objectContainer_height.toString() + 'px';
3755			this._img2.style.left = '0px';
3756			this._img2.style.top = '0px';
3757		}
3758		
3759		// Creazione funzione per la generazione delle transazioni
3760		var generaClipMaker = function (myThis, IDTransazione, Stile) {
3761			var fReturn;
3762			switch (Stile) {
3763				case '':
3764					break;
3765				case 'opacity':
3766					fReturn = new HtmlPlus_ClipMaker(CStrJS(IDTransazione), myThis.transactionTime, myThis.fps);
3767					fReturn.AppendMotion(myThis._div1, 'opacity', '', 0, 100, 100, 0, myThis.transactionType);
3768					fReturn.AppendMotion(myThis._div2, 'opacity', '', 0, 100, 0, 100, myThis.transactionType);
3769					break;
3770				case 'right-left':
3771					fReturn = new HtmlPlus_ClipMaker(CStrJS(IDTransazione), myThis.transactionTime, myThis.fps);
3772					fReturn.AppendMotion(myThis._div1, 'left', 'px', 0, 100, 0, -myThis.objectContainer_width, myThis.transactionType);
3773					fReturn.AppendMotion(myThis._div2, 'left', 'px', 0, 100, myThis.objectContainer_width, 0, myThis.transactionType);
3774					break;
3775				case 'left-right':
3776					fReturn = new HtmlPlus_ClipMaker(CStrJS(IDTransazione), myThis.transactionTime, myThis.fps);
3777					fReturn.AppendMotion(myThis._div1, 'left', 'px', 0, 100, 0, myThis.objectContainer_width, myThis.transactionType);
3778					fReturn.AppendMotion(myThis._div2, 'left', 'px', 0, 100, -myThis.objectContainer_width, 0, myThis.transactionType);	
3779					break;
3780				case 'top-bottom':
3781					fReturn = new HtmlPlus_ClipMaker(CStrJS(IDTransazione), myThis.transactionTime, myThis.fps);
3782					fReturn.AppendMotion(myThis._div1, 'top', 'px', 0, 100, 0, myThis.objectContainer_height, myThis.transactionType);
3783					fReturn.AppendMotion(myThis._div2, 'top', 'px', 0, 100, -myThis.objectContainer_height, 0, myThis.transactionType);
3784					break;
3785				case 'bottom-top':
3786					fReturn = new HtmlPlus_ClipMaker(CStrJS(IDTransazione), myThis.transactionTime, myThis.fps);
3787					fReturn.AppendMotion(myThis._div1, 'top', 'px', 0, 100, 0, -myThis.objectContainer_height, myThis.transactionType);
3788					fReturn.AppendMotion(myThis._div2, 'top', 'px', 0, 100, myThis.objectContainer_height, 0, myThis.transactionType);
3789					break;
3790				case 'test':
3791					fReturn = new HtmlPlus_ClipMaker(CStrJS(IDTransazione), myThis.transactionTime, myThis.fps);
3792					fReturn.AppendMotion(myThis._div1, 'left', 'px', 0, 100, 100, 100 - myThis.objectContainer_height, myThis.transactionType);
3793					fReturn.AppendMotion(myThis._div2, 'top', 'px', 0, 100, 100 + myThis.objectContainer_height, 100, myThis.transactionType);
3794					break;
3795				default:
3796					fReturn = Stile;
3797			}
3798			if (fReturn) fReturn.AppendEvent(100, 'HtmlPlus_SlideShowColl[\'' + CStrJS(myThis.id) +  '\']._transactionMaker_OnEnd();');
3799			return fReturn;
3800		}
3801		
3802		//Creazione oggetti ClipMaker per [transactionMaker]
3803		this.transactionMaker = generaClipMaker(this, this.id + '_transaction', this.transactionStyle);
3804		
3805		//Creazione oggetti ClipMaker per [transactionMakerFF]
3806		this.transactionMakerFF = null;
3807		if (this.transactionStyleFF == 'auto') {
3808			switch (this.transactionStyle) {
3809				case 'opacity':		str1 = ''; break;
3810				case 'right-left':	str1 = 'left-right'; break;
3811				case 'left-right':	str1 = 'right-left'; break;
3812				case 'top-bottom':	str1 = 'bottom-top'; break;
3813				case 'bottom-top':	str1 = 'top-bottom'; break;
3814				case 'test':		str1 = 'test'; break;
3815				default:			str1 = ''; break;
3816			}
3817		} else {
3818			str1 = this.transactionStyleFF;
3819		}
3820		this.transactionMakerFF = generaClipMaker(this, this.id + '_transactionFF', str1);
3821		
3822		return true;
3823	} 
3824	this._processoPlay_args = {tmr:null};
3825	this._processoPlay = function(Stato) {
3826		//Si occupa di gestire le transazioni e le permanenze delle immagini.
3827		var nextPos1, nextPos2, strFunc;
3828		if (this._status == 'play') {
3829			if (this._div1.style.visibility == 'hidden') this._div1.style.visibility = 'visible';
3830			switch (Stato) {
3831				case 'transaction':
3832					nextPos1 = this._getPosition(1);
3833					nextPos2 = this._getPosition(2);
3834					if (!IsNull(nextPos1)) {
3835						strFunc = 'HtmlPlus_SlideShowColl[\'' + CStrJS(this.id) +  '\']._processoPlay(\'permanence\');';
3836						this._processoTransac(true, nextPos1, nextPos2, strFunc);
3837					}
3838					break;
3839				case 'permanence':
3840					clearTimeout(this._processoPlay_args['tmr']);
3841					this._processoPlay_args['tmr'] = setTimeout('HtmlPlus_SlideShowColl[\'' + CStrJS(this.id) +  '\']._processoPlay(\'transaction\');',  (this.permanenceTime - this.transactionTime) * 1000);
3842					break;
3843				case 'pause':
3844					clearTimeout(this._processoPlay_args['tmr']);
3845					break;
3846			}
3847		}
3848	}
3849	this._processoTransac_args = {stato:'check', newItem:null, nextItem:null, onEndFunction:null, objTransac:null};
3850	this._processoTransac = function(IsStatoCheck, optNewItem, optNextItem, optOnEndFunction) {
3851		//Si occupa di controllare il processo di passaggio da un'immagine all'altra.
3852		//In un ciclo Step si lavora su 3 immagini: old (a video, da sostituire), new (sostituirà old), next (la prossima).
3853		//Descrizione degli stati:
3854		//  1) check :   Verifica per inizio transazione: si verifica che new sia stata caricata.
3855		//  2) start :   Inizio transazione: old verrà sostituita da new, e nel frattempo verrà iniziato il caricamento di next.
3856		//  3) end :     Inizio tempo visione di new: la transazione è finita, si attende la fine del tempo permanenceTime.
3857		var cont1, str1;
3858		if (IsStatoCheck) {
3859			this._processoTransac_args['stato'] = 'check';
3860			if (optNewItem >= 0) {
3861				this._processoTransac_args['newItem'] = this.imagesCollection[optNewItem];
3862				this._processoTransac_args['newItem'].index = optNewItem;
3863			} else {
3864				this._processoTransac_args['newItem'] = {src:optNewItem, width:null, height:null, alt:'', onClick:''};
3865				this._processoTransac_args['newItem'].index = -1;
3866			}
3867			if (IsNull(optNextItem)) {
3868				this._processoTransac_args['nextItem'] = null;
3869			} else {
3870				if (optNextItem >= 0) {
3871					this._processoTransac_args['nextItem'] = this.imagesCollection[optNextItem];
3872					this._processoTransac_args['nextItem'].index = optNextItem;
3873				} else {
3874					this._processoTransac_args['nextItem'] = {src:optNextItem, alt:'', onClick:''};
3875					this._processoTransac_args['nextItem'].index = -1;
3876				}
3877			}
3878			this._processoTransac_args['onEndFunction'] = optOnEndFunction;
3879			this._processoTransac_args['objTransac'] = null;
3880		}
3881		switch (this._processoTransac_args['stato']) {
3882			case 'check':
3883				if (this.OnCurrentPrositionChanging(this, this._currentPosition, this._processoTransac_args['newItem'].index)) {
3884					//Determino lo stato successivo
3885					if (this.startMethod == 'image') {
3886						str1 = (this._img1.src.indexOf(this._img_srcNone) == -1 ? 'start' : 'end');
3887					} else {
3888						str1 = 'start';
3889					}
3890					//Carico l'immagine per il preload
3891					this._imgLoad_preloadImg(this._processoTransac_args['newItem']);
3892					if (this._imgLoadInfo['isLoaded']) {	//l'immagine new è stata caricata, proseguo.
3893						this._processoTransac_args['stato'] = str1;
3894						this._processoTransac();
3895					} else {
3896						cont1 = this._imgLoadInfo['timeout'] - (new Date());	//Tempo passato dal preload, in msec.
3897						if (cont1 < 0) {	// scaduto il tempo di preload, proseguo.
3898							// annullo il timer di preload
3899							clearTimeout(this._imgLoadInfo['onPreloadEndTmr']);
3900							this._imgLoadInfo['onPreloadEndFunction'] = null;
3901							// eseguo lo step successivo
3902							this._processoTransac_args['stato'] = str1;
3903							this._processoTransac();
3904						} else {			//devo aspettare lo scadere del tempo di preload.
3905							this._imgLoadInfo['onPreloadEndFunction'] = 'HtmlPlus_SlideShowColl[\'' + CStrJS(this.id) +  '\']._processoTransac();';
3906							this._imgLoadInfo['onPreloadEndTmr'] = setTimeout(this._imgLoadInfo['onPreloadEndFunction'], cont1);
3907						}
3908					}
3909				} else {
3910					if (this.Status() == 'play') this._changeStatus('pause');
3911				}
3912				break;
3913			case 'start':
3914				if (this._div1.style.visibility == 'hidden') this._div1.style.visibility = 'visible';
3915				this._img1.alt = '';
3916				this._img1.onClick = '';
3917				if (this._currentPosition >= 0 && this._currentPosition > this._processoTransac_args['newItem'].index) {
3918					//La nuova posizione  posteriore alla corrente, quindi eseguo la transazione all'indietro.
3919					this._processoTransac_args.objTransac = (this.transactionMakerFF ? this.transactionMakerFF : this.transactionMaker);
3920				} else {
3921					//Eseguo la transazione all'avanti.
3922					this._processoTransac_args.objTransac = this.transactionMaker;
3923				}
3924				this._img2.src = this._processoTransac_args['newItem'].src;
3925				this._imgRedim(this._processoTransac_args['newItem'], this._img2);
3926				this._div2Base.style.display = 'block';
3927				this.OnTransactionBegin(this, this._currentPosition, this._processoTransac_args['newItem'].index);
3928				this._processoTransac_args.objTransac.Play();
3929				this._processoTransac_args['stato'] = 'end';
3930				if (this._processoTransac_args['nextItem']) this._imgLoad_preloadImg(this._processoTransac_args['nextItem']);
3931				break;
3932			case 'end':
3933				this._img1.src = this._processoTransac_args['newItem'].src;
3934				this._img1.alt = this._processoTransac_args['newItem'].alt;
3935				this._img1.onClick = this._processoTransac_args['newItem'].onClick;
3936				switch (this.zoomType){
3937					case 'fixed':
3938						break;
3939					default:
3940						this._imgRedim(this._processoTransac_args['newItem'], this._img1);
3941				}
3942				
3943				//ripristino il div1 e div2 e nascondo il div2
3944				this._div2Base.style.display = 'none';
3945				if (this._processoTransac_args.objTransac) this._processoTransac_args.objTransac.Stop();
3946				//Fine esecuzione
3947				this._processoTransac_args['stato'] = '';
3948				this._currentPosition = this._processoTransac_args['newItem'].index;
3949				this.OnCurrentPrositionChanged(this, this._currentPosition);
3950				if (this._processoTransac_args['onEndFunction']) eval(this._processoTransac_args['onEndFunction']);
3951				break;
3952		}
3953	}
3954	this._imgLoadInfo = {isLoaded:false, startTime:null, endTime:null, timeout:null, imgColl:[], onPreloadEndFunction:null, onPreloadEndTmr:null};
3955	this._imgLoad_preloadImg = function(ImageSource) {
3956		var objImg, src, caricare;
3957		if (ValueType(ImageSource) == 'Object') {
3958			objImg = ImageSource;
3959			src = objImg.src;
3960		} else {
3961			objImg = null;
3962			src = ImageSource;
3963		}
3964		caricare = true;
3965		if (caricare && this._imgLoad.src == src) caricare = false;
3966		if (caricare && objImg) caricare = true; (objImg.isLoaded ? false : true);
3967		if (caricare) {
3968			this._imgLoadInfo['imageSource'] = ImageSource;
3969			this._imgLoadInfo['image'] = objImg;
3970			this._imgLoadInfo['isLoaded'] = false;
3971			this._imgLoadInfo['startTime'] = new Date();
3972			this._imgLoadInfo['endTime'] = null;
3973			this._imgLoadInfo['timeout'] = this._imgLoadInfo['startTime'].DateAdd('s', this.preloadTimeout);
3974			this._imgLoad.src = src;
3975			this.OnPreloadBegin(this, this._imgLoadInfo['imageSource']);
3976		}
3977	}
3978	this._imgLoad_onLoad = function(ev) {
3979		var eventObj = new STDEvent(ev);
3980		var objSlide = eventObj.srcElement._HtmlPlus_SlideShowObj;
3981		var str1, objImg, obj1;
3982		if (objSlide) {
3983			objSlide._imgLoadInfo['isLoaded'] = true;
3984			objSlide._imgLoadInfo['endTime'] = new Date();
3985			objImg = objSlide._imgLoadInfo['image'];
3986			if (objImg) {
3987				objImg.isLoaded = true;
3988				if (!objImg.width) objImg.width = toNumber(GetProperty(objSlide._imgLoad, 'width', true));
3989				if (!objImg.height) objImg.height = toNumber(GetProperty(objSlide._imgLoad, 'height', true));
3990			}
3991			//Metto in cache un nuovo oggett IMAGE
3992			obj1 = document.createElement('IMG');
3993			obj1.src = eventObj.srcElement.src;
3994			objSlide._imgLoadInfo['imgColl'].push(obj1);
3995			//Lanco l'evento OnPreloadEnd
3996			objSlide.OnPreloadEnd(objSlide, objSlide._imgLoadInfo['imageSource']);
3997			if (objSlide._imgLoadInfo['onPreloadEndFunction']) {
3998				clearTimeout(objSlide._imgLoadInfo['onPreloadEndTmr']);
3999				str1 = objSlide._imgLoadInfo['onPreloadEndFunction'];
4000				objSlide._imgLoadInfo['onPreloadEndFunction'] = null;
4001				eval(str1);
4002			}
4003		}
4004	}
4005	this._imgRedim = function(ImageItem, Img) {
4006		var divW, divH, imgW, imgH;
4007		
4008		divW = this.objectContainer_width;
4009		divH = this.objectContainer_height;
4010		imgW = IfNull(ImageItem.width, divW);
4011		imgH = IfNull(ImageItem.height, divH);
4012		
4013		switch (this.zoomType){
4014			case 'fixed':
4015				break;
4016			case 'min':
4017				if ((divW / divH) > (imgW / imgH)) {
4018					// Calcolo le dimensioni
4019					Img.style.width = divW + 'px';
4020					Img.style.height = (imgH * divW / imgW) + 'px';
4021					// Centro l'immagine
4022					Img.style.top = Math.round(-(parseInt(Img.style.height, 0) - divH) / 2) + 'px';
4023					Img.style.left = '0px';
4024				} else {
4025					// Calcolo le dimensioni
4026					Img.style.height = divH + 'px';
4027					Img.style.width = (imgW * divH / imgH) + 'px';
4028					// Centro l'immagine
4029					Img.style.top = '0px';
4030					Img.style.left = Math.round(-(parseInt(Img.style.width, 0) - divW) / 2) + 'px';
4031				}
4032				break;
4033			case 'max':
4034				if ((divW / divH) < (imgW / imgH)) {
4035					// Calcolo le dimensioni dell'immagine
4036					Img.style.width = divW + 'px';
4037					Img.style.height = (imgH * divW / imgW) + 'px' ;
4038					// Centro l'immagine
4039					Img.style.left = '0px';
4040					Img.style.top = Math.round((divH - (parseInt(Img.style.height, 0))) / 2) + 'px';
4041				} else {
4042					// Calcolo le dimensioni dell'immagine
4043					Img.style.height = divH + 'px';
4044					Img.style.width = (imgW * divH / imgH) + 'px' ;
4045					// Centro l'immagine	
4046					Img.style.left = Math.round((divW -(parseInt(Img.style.width, 0))) / 2) + 'px';
4047					Img.style.top = '0px';
4048				}
4049				break;
4050		}
4051	}
4052	this._transactionMaker_OnEnd = function(){
4053		this.OnTransactionEnd(this, cont1,  this.GetCurrentPosition());
4054		this._processoTransac();
4055	}
4056	
4057	this._changeStatus = function (nuovoValore) {
4058		if (this._status != nuovoValore) {
4059			var str1 = this._status;
4060			this._status = nuovoValore;
4061			this.OnStatusChanged(this, str1, nuovoValore);
4062		}
4063	}
4064	this._getPosition = function(MoveForItems) {
4065		this._buildObjects();
4066		var posiz = this._currentPosition;
4067		if (this.imagesCollection.length < 1) {
4068			posiz = null;
4069		} else {
4070			posiz += MoveForItems;
4071			if (posiz < 0) {
4072				if (this.repeat) {
4073					while (posiz < 0) {
4074						posiz += this.imagesCollection.length;
4075					}
4076				} else {
4077					posiz = null;
4078				}
4079			} else if (posiz >= this.imagesCollection.length) {
4080				if (this.repeat) {
4081					while (posiz >= this.imagesCollection.length) {
4082						posiz -= this.imagesCollection.length;
4083					}
4084				} else {
4085					posiz = null;
4086				}
4087			}
4088		}
4089		return posiz;
4090	}
4091	this.GetPreviousPosition = function(){
4092		return this._getPosition(-1);
4093	}
4094	this.GetNextPosition = function(){
4095		return this._getPosition(1);
4096	}
4097	
4098	this.Play = function() {
4099		var str1;
4100		this._buildObjects();
4101		switch (this._status){
4102			case 'play':
4103				break;
4104			case 'pause':
4105				this._changeStatus('play');
4106				this._processoPlay('transaction');
4107				break;
4108			case 'stop':
4109				if (this.imagesCollection.length < 2) this.repeat = false;
4110				switch (this.startMethod){
4111					case 'image':
4112						this._img1.src = this._img_srcNone;
4113						this._img1.alt = '';
4114						this._img1.onClick = '';
4115						str1 = 'var objSlide = HtmlPlus_SlideShowColl[\'' + CStrJS(this.id) +  '\'];';
4116						str1 += 'objSlide._changeStatus(\'play\');';
4117						str1 += 'objSlide._processoPlay(\'permanence\');';
4118						this._processoTransac(true, 0, null, str1);
4119						break;
4120					case 'transaction': 
4121						this._changeStatus('play');
4122						this._currentPosition = -1;
4123						this._img1.src = this._img_srcNone;
4124						this._img1.alt = '';
4125						this._img1.onClick = '';
4126						this._processoPlay('transaction');
4127						break;
4128					default:
4129						this._changeStatus('play');
4130						this._currentPosition = -1;
4131						this._img1.src = this.startMethod;
4132						this._img1.alt = '';
4133						this._img1.onClick = '';
4134						this._processoPlay('transaction');
4135						break;
4136				}
4137				break;
4138		}
4139	}
4140	this.Pause = function(){
4141		this._buildObjects();
4142		switch (this._status){
4143			case 'play':
4144				this._processoPlay('pause');
4145				this._changeStatus('pause');
4146				break;
4147			case 'pause':
4148				break;
4149			case 'stop':
4150				break;
4151		}
4152	}
4153	this.Stop = function(){
4154		this._buildObjects();
4155		switch (this._status){
4156			case 'play':
4157				this._processoPlay('pause');
4158				this._changeStatus('stop');
4159				this.SetCurrentPosition(0);
4160				break;
4161			case 'pause':
4162				this._processoPlay('pause');
4163				this._changeStatus('stop');
4164				this.SetCurrentPosition(0);
4165				break;	
4166			case 'stop':
4167				break;
4168		}
4169	}
4170	
4171	this.GetCurrentPosition = function(){
4172		this._buildObjects();
4173		return this._currentPosition;
4174	}
4175	this.SetCurrentPosition = function(value){
4176		this._buildObjects();
4177		switch(this._status){
4178			case 'play':
4179				this.Pause();
4180				break;
4181			case 'pause':
4182				break;
4183			case 'stop':
4184				this.Pause();
4185				break;
4186		}
4187		this._processoTransac(true, value, null);
4188	}
4189	
4190	this.Status = function(){
4191		this._buildObjects();
4192		return this._status;
4193	}
4194	
4195	this.OnStatusChanged = function (SlideShow, OldStatusValue, NewStatusValue) {return void(0);};
4196	this.OnPreloadBegin = function (SlideShow, Src) {return void(0);};
4197	this.OnPreloadEnd = function (SlideShow, Src) {return void(0);};
4198	this.OnTransactionBegin = function (SlideShow, OldImageIndex, NewImageIndex) {return void(0);};
4199	this.OnTransactionEnd = function (SlideShow, OldImageIndex, NewImageIndex) {return void(0);};
4200	this.OnCurrentPrositionChanging = function (SlideShow, OldImageIndex, NewImageIndex) {return true;};
4201	this.OnCurrentPrositionChanged = function (SlideShow, NewImageIndex) {return void(0);};
4202	
4203	this._initialize();
4204	return this;
4205}
4206
4207
4208function HtmlPlus_VerticalFill(HtmlObject, DynamicMode, optOffset) {
4209	return HtmlPlus_DimensionFill(HtmlObject, 'height', DynamicMode, optOffset);
4210}
4211function HtmlPlus_OrizzontalFill(HtmlObject, DynamicMode, optOffset) {
4212	return HtmlPlus_DimensionFill(HtmlObject, 'width', DynamicMode, optOffset);
4213}
4214function HtmlPlus_DimensionFill(HtmlObject, WidthHeight, DynamicMode, optOffset) {
4215	//Dimensiona l'oggetto passato al fine di riempire lo spazio a disposizione senza far comparire le barre di scorrimento.
4216	//Mettendo NoDynamic a TRUE, il ridimensionamento viene impostato al valore secondo la dimensione attuale del browser, e su
4217	//ridimensionamento l'oggetto non viene ridimensionato.
4218	//ATTENZIONE: l'oggetto è consigliabile che sia posizionato in alto a sinistra rispetto al suo contenitore.
4219	var objHtml, objBody, argDynMode;
4220	var dimWH, clientWH, scrollWH, offsetWH;
4221	var nuovaDim, valOffset, str1;
4222	
4223	//Carico le variabili
4224	objHtml = (typeof(HtmlObject) == 'string' ? findObj(HtmlObject) : HtmlObject);
4225	objBody = objHtml.ownerDocument.body;
4226	objBody = GetDocInfo(objHtml, 'RootElement');
4227	switch (DynamicMode) {
4228		case 'NoDynamic':
4229		case 'NoDynamic+Offset':
4230		case 'DynamicRecalc':
4231		case 'Dynamic':
4232			argDynMode = DynamicMode;
4233			break;
4234		case true:		//serve per compatibilità all'indietro, dove il secondo argomento si chiamava "NoDynamic"
4235			argDynMode = 'NoDynamic';
4236			break;
4237		case false:		//serve per compatibilità all'indietro, dove il secondo argomento si chiamava "NoDynamic"
4238		default:
4239			argDynMode = 'Dynamic';
4240			break;
4241	}
4242	switch (WidthHeight) {
4243		case 'width':	dimWH = 'width'; break;
4244		default:		dimWH = 'height'; break;
4245	}
4246	switch (dimWH) {
4247		case 'width':	clientWH = 'clientWidth'; scrollWH = 'scrollWidth'; offsetWH = 'offsetWidth'; break;
4248		case 'height':	clientWH = 'clientHeight'; scrollWH = 'scrollHeight'; offsetWH = 'offsetHeight'; break;
4249	}
4250	
4251	if (window._HtmlPlus_DimensionFill_running) {
4252		str1 = 'HtmlPlus_DimensionFill(';
4253		str1 += 'findObj(\'' + CStrJS(GetProperty(objHtml, 'uniqueID')) + '\')';
4254		str1 += ', \'' + CStrJS(dimWH) + '\'';
4255		str1 += ', \'' + CStrJS(argDynMode) + '\'';
4256		if (optOffset) str1 += ', ' + optOffset.toString();
4257		str1 += ');';
4258		//setTimeout(str1, 200);
4259	} else {
4260		//Mi memorizzo sull'oggetto che è in corso una esecuzione di questa procedura, perchè c'è rischio che si crei una esecuzione a catena
4261		//dato che ci sono degli eventi associati.
4262		//window._HtmlPlus_VerticalFill_running = true;		DISATTIVATO, perchè non funziona. Vedi commento piu sotto su "addEvent".
4263		
4264		//Determino la nuova dimensione ed effettuo la modifica
4265		if (argDynMode == 'NoDynamic+Offset') {
4266			SetProperty(objHtml, dimWH, (toNumber(objBody[clientWH]) - optOffset) + 'px');
4267		} else {
4268			var scrVal1, scrVal2, scrVal3;
4269			var cacheDisp = GetCssStyle(objHtml, 'display');
4270			SetProperty(HtmlObject, dimWH, toNumber(objBody[clientWH]).toString() + 'px');
4271			objHtml.style.display = 'none';
4272			scrVal1 = toNumber(objBody[scrollWH]);
4273			objHtml.style.display = cacheDisp;
4274			scrVal2 = toNumber(objBody[scrollWH]);
4275			if (scrVal1 > toNumber(objBody[clientWH])) {	//Se la scrollbar ci sta anche senza objHtml allora...
4276				SetProperty(objHtml, dimWH, (1000 + toNumber(objBody[clientWH])) + 'px');	//50000
4277				scrVal3 = toNumber(objBody[scrollWH]);
4278				nuovaDim = toNumber(GetCssStyle(objHtml, dimWH)) - (scrVal3 - scrVal2);
4279			} else {
4280				nuovaDim = toNumber(GetCssStyle(objHtml, dimWH)) - (scrVal2 - toNumber(objBody[clientWH]));
4281			}
4282			if (nuovaDim > 0) SetProperty(objHtml, dimWH, nuovaDim + 'px');
4283			valOffset = toNumber(objBody[clientWH]) - nuovaDim;
4284		}
4285		//Verifico se devo creare eventi per la gestione dinamica della dimensione su ridimensionamento del Document
4286		switch (argDynMode) {
4287			case 'NoDynamic':
4288			case 'NoDynamic+Offset':
4289				break;
4290			case 'DynamicRecalc':
4291				//addEvent(window, 'resize', function() {HtmlPlus_VerticalFill(objHtml, 'NoDynamic');});
4292				//	'--- disattivato perchè il ridimensionamento verso 5000 per determinare di quanto si eccede non funziona: l'oggetto viene
4293				//		ridimensionato ma la pagina sembra che non venga ricalcolata. Di conseguenza non ho un valore valido per "scrollHeight".
4294				//		La soluzione sarebbe di spezzare la procedura in più parti, dando tempo al browser di rappresentare ciò che deve, oppure
4295				//		scoprire un comando che sappia eseguire un REFRESH. Al momento ripristino il vecchio meccanismo.
4296				if (objHtml.setExpression) objHtml.setExpression(dimWH, 'window.document.body.' + clientWH + ' - (' + valOffset + ')');
4297				break;
4298			case 'Dynamic':
4299				//objHtml.setExpression('height', 'Math.min(window.document.body.clientHeight, window.document.body.scrollHeight) - ' + offsetY);
4300				//objHtml.setExpression('height', 'window.document.body.clientHeight - ' + offsetY);
4301				//addEvent(window, 'resize', function() {HtmlPlus_VerticalFill(objHtml, 'NoDynamic+Offset', valOffset);});
4302				//  ^--- disattivato per lo stesso motivo indicato per argDynMode=DynamicRecalc
4303				if (objHtml.setExpression) objHtml.setExpression(dimWH, 'window.document.body.' + clientWH + ' - (' + valOffset + ')');
4304				break;
4305		}
4306		
4307		//Indico la fine dell'esecuzione della procedura
4308		window._HtmlPlus_DimensionFill_running = false;
4309	}
4310}
4311
4312function HtmlPlus_AutoScroll_AddPlusToObject(HtmlObject, ObjectHeight, PixelPerSec, NoAutoStart) {
4313	new HtmlPlus_AutoScroll('AutoScroll_' + HtmlObject.id, HtmlObject, ObjectHeight, PixelPerSec, NoAutoStart, null);
4314}
4315function HtmlPlus_AutoScroll(IdObject, ScrollerHtmlObject, ClientHeight, PixelPerSecond, NoAutoStart, HtmlPageSeparator, IsOrizzontal) {
4316	this.id = IdObject;
4317	this.objectType = 'HtmlPlus_AutoScroll';
4318	this.scrollerHtmlObject = ScrollerHtmlObject;	//Riferimento all'oggetto che effettuerà lo scrolling del suo contenuto;
4319	this.clientHeight = ClientHeight;				//Valore in Pixel o rif. a oggetto Html da cui determinare l'altezza di ScrollerHtmlObject;
4320	this.pixelPerSec = PixelPerSecond;				//Velocità di scorrimento;
4321	this.htmlPageSeparator = HtmlPageSeparator;		//Codice HTML che verrà usato come separatore fra pagine; se non definito il separatore sarà una
4322													//pagina bianca alta quanto [scrollerHtmlObject.clientHeight];
4323	this.isOrizzontal = IsOrizzontal;				//Se nullo o true la pagina simuove verticalmente altrimenti orizzontalmente
4324	this.autoStart = false;							//Se TRUE, lo scroll partirà quando verrà eseguito l'evento WINDOW.ONLOAD;
4325	this.fps = 0;									//Fotogrammi per secondo (qualità animazione);
4326	this.enabled = false;							//Tipicamente TRUE o FALSE, indica se l'animazione è attivata o disattivata;
4327	this._isPlay = false;							//Se TRUE, significa che l'animazione è accesa;
4328	this._tmp = null;								//Riferimento all'istanza "setInterval" che esegue l'animazione;
4329
4330	if (!window.HtmlPlus_AutoScrollColl) {
4331		window.HtmlPlus_AutoScrollColl = new Array();
4332		addEvent(window, 'load', function() {
4333						var obj;
4334						for (obj in window.HtmlPlus_AutoScrollColl) {
4335							window.HtmlPlus_AutoScrollColl[obj].WINDOW_OnLoadHandler();
4336							break;
4337						}
4338					}
4339				 );
4340	}
4341	window.HtmlPlus_AutoScrollColl[this.id] = this;
4342	
4343	this._initialize = function() {
4344		var defaultPixelPerSec = 20;
4345		var defaultFps = GetBrowserInfo('RecommendedFps');
4346		
4347		this.scrollerHtmlObject.AutoScrollObject = this;
4348		if (!this.pixelPerSec) this.pixelPerSec = defaultPixelPerSec;
4349		this.autoStart = ((NoAutoStart) ? false : true);
4350		this.fps = defaultFps;
4351		this.enabled = 'toInitialize';
4352
4353		if ( ! this.isOrizzontal ) {
4354			switch (typeof(this.clientHeight)) {
4355				case 'object':
4356					this.scrollerHtmlObject.style.height = toNumber(GetProperty(this.clientHeight, 'clientHeight')).toString() + 'px';
4357					break;
4358				case 'string':
4359					if (this.clientHeight.length > 10) {
4360						this.scrollerHtmlObject.style.height = toNumber(this.clientHeight, 0).toString() + 'px';
4361						break;
4362					}
4363				default:
4364					this.scrollerHtmlObject.style.height = toNumber(this.clientHeight, 0).toString() + 'px';
4365			}
4366		} else {
4367			switch (typeof(this.clientHeight)) {
4368				case 'object':
4369					this.scrollerHtmlObject.style.width = toNumber(GetProperty(this.clientHeight, 'clientWidth')).toString() + 'px';
4370					break;
4371				case 'string':
4372					if (this.clientHeight.length > 10) {
4373						this.scrollerHtmlObject.style.width = toNumber(this.clientHeight, 0).toString() + 'px';
4374						break;
4375					}
4376				default:
4377					this.scrollerHtmlObject.style.width = toNumber(this.clientHeight, 0).toString() + 'px';
4378			}
4379		}
4380
4381		addEvent(this.scrollerHtmlObject, 'mouseover', function(ev) {
4382						var eventObj = new STDEvent(ev);
4383						var obj = eventObj.srcElement;
4384						while (obj.tagName != 'BODY') {
4385							if (obj.AutoScrollObject) {
4386								obj.AutoScrollObject.OnMouseOverHandler();
4387								break;
4388							} else {
4389								obj = obj.parentNode;
4390							}
4391						}
4392					}
4393				);
4394		addEvent(this.scrollerHtmlObject, 'mouseout', function(ev){
4395						var eventObj = new STDEvent(ev);
4396						var obj = eventObj.srcElement;
4397						while (obj.tagName != 'BODY') {
4398							if (obj.AutoScrollObject) {
4399								obj.AutoScrollObject.OnMouseOutHandler();
4400								break;
4401							} else {
4402								obj = obj.parentNode;
4403							}
4404						}
4405					}
4406				);
4407	}
4408	
4409	this.WINDOW_OnLoadHandler = function() {
4410		var obj;
4411		for (obj in window.HtmlPlus_AutoScrollColl) {
4412			if (window.HtmlPlus_AutoScrollColl[obj].autoStart) window.HtmlPlus_AutoScrollColl[obj].Start();
4413		}
4414	}
4415	this.OnMouseOverHandler = function() {
4416		this.Stop();
4417	}
4418	this.OnMouseOutHandler = function() {
4419		this.Start();
4420	}
4421	
4422	this.Start = function() {
4423		if (this.enabled == 'toInitialize') {
4424				//Inizializzo l'oggetto
4425			if (! this.isOrizzontal){
4426				if (this.scrollerHtmlObject.scrollHeight > this.scrollerHtmlObject.clientHeight) {
4427					if (this.htmlPageSeparator) {
4428						// Inserisco il SeparatoreDiPagina all'inizio del contenuto dello Scroller, poi duplico tutto il contenuto.
4429						var str1 = this.htmlPageSeparator + this.scrollerHtmlObject.innerHTML;
4430						this.scrollerHtmlObject.innerHTML = str1 + str1;
4431						this.scrollerHtmlObject.style.paddingTop = '0px';
4432						this.scrollerHtmlObject.style.paddingBottom = '0px';
4433					} else {
4434						// Aggiungo dello spazio vuoto in testa ed in coda al contenuto
4435						this.scrollerHtmlObject.style.paddingTop = this.scrollerHtmlObject.clientHeight + 'px';
4436						this.scrollerHtmlObject.style.paddingBottom = this.scrollerHtmlObject.clientHeight + 'px';
4437					}
4438					this.enabled = true;
4439				}
4440				this._tmr = '';
4441			} else {
4442				if (this.scrollerHtmlObject.scrollWidth > this.scrollerHtmlObject.clientWidth) {
4443					if (this.htmlPageSeparator) {
4444						// Inserisco il SeparatoreDiPagina all'inizio del contenuto dello Scroller, poi duplico tutto il contenuto.
4445						var str1 = '<table cellpadding="0" height="100%" cellspacing="0" border="0"><tr>';
4446						str1 = str1 + '<td align="left" valign="middle">' + this.htmlPageSeparator + '</td>' ;
4447						str1 = str1 + '<td>' + this.scrollerHtmlObject.innerHTML + '</td>';
4448						str1 = str1 + '<td align="left" valign="middle">' + this.htmlPageSeparator + '</td>';
4449						str1 = str1 + '<td>' + this.scrollerHtmlObject.innerHTML + '</td>';
4450						str1 = str1 + '</tr></table>';
4451						this.scrollerHtmlObject.innerHTML = str1;
4452						this.scrollerHtmlObject.style.paddingLeft = '0px';
4453						this.scrollerHtmlObject.style.paddingRight = '0px';
4454					} else {
4455						// Aggiungo dello spazio vuoto in testa ed in coda al contenuto
4456						this.scrollerHtmlObject.style.paddingLeft = this.scrollerHtmlObject.clientWidth + 'px';
4457						this.scrollerHtmlObject.style.paddingRight = this.scrollerHtmlObject.clientWidth + 'px';
4458					}
4459					this.enabled = true;
4460				}
4461				this._tmr = '';
4462			}
4463		}
4464		if (!this.isPlay && this.enabled) {
4465			this._tmr = setInterval('var obj = window.HtmlPlus_AutoScrollColl["' + this.id + '"]; obj._runStep();', 1000 / this.fps);
4466			this.isPlay = true;
4467		}
4468	}
4469
4470
4471	this.Stop = function() {
4472		if (this.isPlay) {
4473			this.isPlay = false;
4474			window.clearInterval(this._tmr);
4475			this._tmr = '';
4476		}
4477	}
4478		
4479	this._runStep = function() {
4480		var i;
4481		if (this.isPlay) {
4482			if ( ! this.isOrizzontal) {
4483				if (this.scrollerHtmlObject.scrollHeight <= this.scrollerHtmlObject.clientHeight) {
4484					this.Stop();
4485				} else {
4486					i = this.scrollerHtmlObject.scrollTop + Math.ceil(this.pixelPerSec / this.fps);
4487					if (this.htmlPageSeparator) {
4488						if ((i >= this.scrollerHtmlObject.scrollHeight / 2) || (i < 0)) {
4489							if (this.pixelPerSec > 0) {
4490								i = 0;
4491							} else {
4492								i = this.scrollerHtmlObject.scrollHeight / 2;
4493							}
4494						}
4495					} else {
4496						if ((i > this.scrollerHtmlObject.scrollHeight - this.scrollerHtmlObject.clientHeight) || (i < 0)) {
4497							if (this.pixelPerSec > 0) {
4498								i = 0;
4499							} else {
4500								i = this.scrollerHtmlObject.scrollHeight;
4501							}
4502						}
4503					}
4504					this.scrollerHtmlObject.scrollTop = i;
4505				}
4506			}else{
4507				if (this.scrollerHtmlObject.scrollWidth <= this.scrollerHtmlObject.clientWidth) {
4508					this.Stop();
4509				} else {
4510					i = this.scrollerHtmlObject.scrollLeft + Math.ceil(this.pixelPerSec / this.fps);
4511					if (this.htmlPageSeparator) {
4512						if ((i >= this.scrollerHtmlObject.scrollWidth / 2) || (i < 0)) {
4513							if (this.pixelPerSec > 0) {
4514								i = 0;
4515							} else {
4516								i = this.scrollerHtmlObject.scrollWidth / 2;
4517							}
4518						}
4519					} else {
4520						if ((i > this.scrollerHtmlObject.scrollWidth - this.scrollerHtmlObject.clientWidth) || (i < 0)) {
4521							if (this.pixelPerSec > 0) {
4522								i = 0;
4523							} else {
4524								i = this.scrollerHtmlObject.scrollWidth;
4525							}
4526						}
4527					}
4528					this.scrollerHtmlObject.scrollLeft = i;
4529				}
4530			}
4531		}
4532	}
4533	
4534	this._initialize();
4535	return this;
4536}
4537
4538
4539
4540function HtmlPlus_ClipMaker(IdObject, TransactionTime, fps) {
4541	this.id = IdObject;
4542	this.objectType = 'HtmlPlus_ClipMaker';
4543	this.transactionTime = TransactionTime;		//Durata della transazione (in secondi).
4544	this.fps = fps;								//Fotogrammi per secondo della transazione.
4545	
4546		
4547	if (!window.HtmlPlus_ClipMakerColl) window.HtmlPlus_ClipMakerColl = new Array();
4548	window.HtmlPlus_ClipMakerColl[this.id] = this;
4549	
4550	this._initialize = function () {
4551		this._time = 0;
4552		this._speed = 1;
4553		this._status = 'stop';
4554		this._tmr = null;
4555		this._startTime = null;
4556		this._showFrame_running = false;
4557		this._showFrame_callPool = new Array();
4558		if (!this.fps) this.fps = GetBrowserInfo('RecommendedFps');
4559	}
4560	this.Motions = function () {
4561		return this._motions;
4562	}
4563	this.AppendMotion = function (AnimatedHtmlObject, AttributeName, AttributeUM_Format, StartTime, StopTime, StartValue, StopValue, TransactionType) {
4564		/*
4565		Aggiunge un oggetto Movimento all'array [Motions]. Parametri:
4566			AnimatedHtmlObject		Qggetto da animare.
4567			AttributeName			Attributo da modificare.
4568			AttributeUM_Format		L'unità di misura del valore che verrà impostato all'attributo; se la stringa contiene il carattere "#" allora
4569									la stringa verrà usata in modalità Format, sostituendo il carattere segnaposto "#" col valore numerico da settare;
4570									Es.:    AttributeUM_Format = 'alpha(opacity=#)'    l'attributo verra settato con:   'alpha(opacity=12)'.
4571			StartTime				Tempo in cui deve iniziare l'animazione (da 0 a 100, corrispondenti all'inizio e alla fine del clip).
4572			StopTime				Tempo in cui deve finire l'animazione (come per StartTime).
4573			StartValue				Valore di partenza dell'attributo.
4574			StopValue				Valore finale dell'attributo.
4575			TransactionType			Il tipo di transazione; può essere: 'square', 'triangle', 'sin', 'cos'.
4576		*/
4577		var obj1 = new Object();
4578		obj1.htmlObject = AnimatedHtmlObject;
4579		obj1.attributeName = AttributeName;
4580		obj1.attributeFormat = AttributeUM_Format;
4581		obj1.startTime = StartTime;
4582		obj1.stopTime = StopTime;
4583		obj1.startValue = StartValue;
4584		obj1.stopValue = StopValue;
4585		obj1.transactionType = TransactionType;
4586		obj1.enabled = true;
4587		
4588		if (typeof(obj1.htmlObject) != 'object') obj1.htmlObject = findObj(obj1.htmlObject);
4589		if (obj1.attributeFormat.indexOf('#') == -1) obj1.attributeFormat = '#' + obj1.attributeFormat;
4590		switch (obj1.transactionType) {
4591			case 'square': case 'triangle': case 'sin': case 'cos': break;
4592			default: obj1.transactionType = 'triangle';
4593		}
4594		
4595		if (!this._motions) this._motions = new Array();
4596		this._motions.push(obj1);
4597	}
4598	this.Events = function () {
4599		return this._events;
4600	}
4601	this.AppendEvent = function (Time, Action) {
4602		/*
4603		Aggiunge un oggetto Evento all'array [Events]. Parametri:
4604			Time					Il momento in cui deve eseguirsi l'evento (da 0 a 100, corrispondenti all'inizio e alla fine del clip).
4605			Action					L'azione che deve essere eseguita; può essere una stringa JavaScript oppure un puntatore a funzione.
4606		*/
4607		var obj1 = new Object();
4608		obj1.time = Time;
4609		obj1.action = Action;
4610		
4611		if (!this._events) this._events = new Array();
4612		this._events.push(obj1);
4613	}
4614	this.RecalcTransactionTime = function () {
4615		//Ricalcolo i tempi per spalmare i tempi da valori in secondo a valori in percentuale:
4616		//itera fra gli oggetti [motions] e [events], interpreta gli attributi Time come se fossero espressi in secondi, e li converte in percentuale;
4617		//il valore più alto che viene trovato verrà usato per risettare l'attributo [transactionTime].
4618		var valMax = -1;
4619		var cont1;
4620		if (this._motions) {
4621			for (cont1 = 0; cont1 < this._motions.length; cont1++) {
4622				if (valMax < this._motions[cont1].stopTime) valMax = this._motions[cont1].stopTime;
4623			}
4624		}
4625		if (this._events) {
4626			for (cont1 = 0; cont1 < this._events.length; cont1++) {
4627				if (valMax < this._events[cont1].time) valMax = this._events[cont1].time;
4628			}
4629		}
4630		this.transactionTime = valMax;
4631		if (this._motions) {
4632			for (cont1 = 0; cont1 < this._motions.length; cont1++) {
4633				this._motions[cont1].startTime = this._motions[cont1].startTime / valMax * 100;
4634				this._motions[cont1].stopTime = this._motions[cont1].stopTime / valMax * 100;
4635			}
4636		}
4637		if (this._events) {
4638			for (cont1 = 0; cont1 < this._events.length; cont1++) {
4639				this._events[cont1].time = this._events[cont1].time / valMax * 100;
4640			}
4641		}
4642		return true;
4643	}
4644	this.Play = function () {
4645		if (this._status != 'play') {
4646			var ora = new Date().getTime();
4647			if (this._tmr) window.clearInterval(this._tmr);
4648			if (this._status == 'stop') {
4649				this._time = ((this._speed > 0) ? -1 : 101);
4650			}
4651			this._startTime = ora - (this.transactionTime / this._speed) * 1000 * this._time / 100;
4652			this._status = 'play';
4653			this._showFrame();
4654			this._tmr = setInterval('var obj = window.HtmlPlus_ClipMakerColl[\'' + CStrJS(this.id) + '\']; obj._showFrame();', 1000 / this.fps);
4655			return true;
4656		} else {
4657			return false;
4658		}
4659	}
4660	this.Pause = function () {
4661		if (this._status == 'play') {
4662			if (this._tmr) window.clearInterval(this._tmr);
4663			this._status = 'pause';
4664			this._forceShowFrame(this._calculateCurrTime(), true);
4665			return true;
4666		} else {
4667			return false;
4668		}
4669	}
4670	this.Stop = function () {
4671		if (this._tmr) window.clearInterval(this._tmr);
4672		this._startTime = null;
4673		this._status = 'stop';
4674		this._forceShowFrame((this._speed > 0)? 0 : 100, true);
4675		return true;
4676	}
4677	this.GetTime = function () {
4678		//Percentuale di esecuzione. 0: inizio del clip; 100: fine del clip.
4679		//Se Speed è negativo, 100 corrisponderà sempre alla fine del filmato, che però, se il clip è in Play, decrementerà fino a 0.
4680		return this._time;
4681	}
4682	this.SetTime = function (TimeValue) {
4683		//Sposta il punto di esecuzione. Valore da 0 a 100.
4684		if (TimeValue >= 0 && TimeValue <= 100) {
4685			if (this._status == 'play') {
4686				this.Pause();
4687				this._forceShowFrame(TimeValue, true);
4688				this.Play();
4689			} else {
4690				this._forceShowFrame(TimeValue, true);
4691			}
4692		}
4693	}
4694	this.GetSpeed = function () {
4695		//Velocità di esecuzione. 1: velocità normale; 0.5: velocità dimezzata; 2: velocità doppia; -1: reverse; ecc..
4696		return this._speed;
4697	}
4698	this.SetSpeed = function (SpeedValue) {
4699		//Velocità di esecuzione. Valore minore o maggiore da 0.
4700		if (SpeedValue > 0 || SpeedValue < 0) this._speed = SpeedValue;
4701	}
4702	this.Status = function () {
4703		//Può essere: 'play', 'pause', 'stop'.
4704		return this._status;
4705	}
4706	
4707	this._calculateCurrTime = function () {
4708		//Calcolo il TIME corrente in base a quanto tempo è trascorso dall'inizio dell'animazione
4709		var fReturn;
4710		fReturn = (new Date().getTime() - this._startTime) / 1000 / (this.transactionTime / this._speed) * 100;
4711		if (fReturn < 0) {
4712			fReturn = 0;
4713		} else if (fReturn > 100) {
4714			fReturn = 100;
4715		}
4716		return fReturn;
4717	}
4718	this._forceShowFrame = function (newTime, optAbortSameTime) {
4719		var eseguire, risp;
4720		if (!optAbortSameTime) {
4721			eseguire = true;
4722		} else {
4723			eseguire = (newTime != this._time);
4724		}
4725		if (eseguire) {
4726			risp = this._showFrame(newTime, true);
4727			if (!risp) this._showFrame_callPool.push('window.HtmlPlus_ClipMakerColl[\'' + CStrJS(this.id) + '\']._showFrame(' + CNumJS(newTime) + ', true);');
4728		}
4729		//	setTimeout('window.HtmlPlus_ClipMakerColl[\'' + CStrJS(this.id) + '\']._forceShowFrame(' + newTime + ');', 50);
4730	}
4731	this._showFrame = function (newTime, optForceShow) {
4732		//Elabora un fotogramma. Il parametro [newTime] (opzionale) serve per indicare il TIME che si deve elaborare. Dopo l'elaborazione
4733		//la funzione setterà il valore TIME alla classe.
4734		var listaMotions = new Array();
4735		var listaMotions_oggetti = new Array();
4736		var listaEvents = new Array();
4737		var precTime, currTime;
4738		var cont1, cont2, str1, obj1, obj2;
4739		
4740		if (!this._showFrame_running) {
4741			this._showFrame_running = true;
4742			
4743			//Determino i TIME
4744			precTime = this._time;
4745			if (newTime >= 0 || newTime < 0) {
4746				currTime = newTime;
4747				if (currTime < 0) {
4748					currTime = 0;
4749				} else if (currTime > 100) {
4750					currTime = 100;
4751				}
4752			} else {
4753				currTime = this._calculateCurrTime();
4754			}
4755			
4756			if (currTime != precTime || optForceShow) {
4757				//Determino gli oggetti-attributi da modificare
4758				if (this._motions) {
4759					for (cont1 = 0; cont1 < this._motions.length; cont1++) {
4760						//Ottengo l'oggetto MOTION, prendendolo dalla testa o dalla coda a seconda della posizione del fotogramma corrente nella timeline.
4761						obj1 = this._motions[(precTime <= currTime ? cont1 : this._motions.length - cont1 - 1)];
4762						//Verifico se l'oggetto Motion esegue un movimento all'interno dell'intervallo  [precTime - currTime]
4763						if (precTime <= currTime && (obj1.startTime < currTime && obj1.stopTime > precTime || obj1.startTime == currTime)
4764								|| precTime > currTime && (obj1.startTime < precTime && obj1.stopTime > currTime || obj1.stopTime == currTime)) {
4765							//L'oggetto Motion è da prendere in considerazione.
4766							//Verifico se l'oggetto è già presente in [listaMotions_oggetti];
4767							cont2 = InArray(listaMotions_oggetti, obj1.htmlObject);
4768							if (cont2 === null) {
4769								cont2 = listaMotions_oggetti.length;
4770								listaMotions_oggetti.push(obj1.htmlObject);
4771							}
4772							//Verifico se l'oggetto-attributo è già presente in [listaMotions]:
4773							str1 = cont2.toString() + '.' + obj1.attributeName;
4774							if (listaMotions[str1]) {
4775								//è presente, quindi valuto se l'oggetto Motion presente nell'array ha un valore [expire] maggiore di quello corrente;
4776								//se così fosse allora sostituisco il Motion dell'array con quello corrente.
4777								obj2 = listaMotions[str1];
4778								cont2 = this._showFrame_calcolaExpire(currTime, precTime, obj1);
4779								if (cont2 < obj2.expire) {
4780									//Il valore [expire] del Motion corrente è minore; sostituisco il Motion dell'array con quello corrente.
4781									obj2.motion = obj1;
4782									obj2.expire = cont2;
4783								}
4784							} else {
4785								//non è presente, quindi creo un nuovo item.
4786								obj2 = new Object();
4787								obj2.motion = obj1;
4788								obj2.value = null;
4789								//setto [expire]: indica il tempo da cui è scaduto il movimento
4790								obj2.expire = this._showFrame_calcolaExpire(currTime, precTime, obj1);
4791							}
4792							listaMotions[str1] = obj2;
4793						}
4794					}
4795				}
4796				//Determino gli eventi da invocare
4797				if (this._events) {
4798					for (cont1 = 0; cont1 < this._events.length; cont1++) {
4799						//Ottengo l'oggetto EVENT, prendendolo dalla testa o dalla coda a seconda della posizione del fotogramma corrente nella timeline.
4800						obj1 = this._events[(precTime <= currTime ? cont1 : this._events.length - cont1 - 1)];
4801						//Verifico se l'oggetto Evento si verifica all'interno dell'intervallo  [precTime - currTime]
4802						if (precTime <= currTime && (precTime < obj1.time && currTime > obj1.time || currTime == obj1.time)
4803								|| precTime > currTime && (currTime < obj1.time && precTime > obj1.time || currTime == obj1.time)) {
4804							//L'oggetto Evento si verifica all'interno di questo intervallo temporale.
4805							listaEvents.push(obj1);
4806						}
4807					}
4808				}
4809				//Calcolo i valori per ogni animazione
4810				for (cont1 in listaMotions) {
4811					obj1 = listaMotions[cont1];
4812					if (currTime >= precTime && obj1.motion.stopTime <= currTime) {
4813						str1 = obj1.motion.stopValue;
4814					} else if (currTime < precTime && obj1.motion.startTime >= currTime) {
4815						str1 = obj1.motion.startValue;
4816					} else {
4817						//Calcolo il "fattore percentuale" della Motion corrente. Il valore che si ottiene và da 0 a 1.
4818						cont2 = (currTime - obj1.motion.startTime) / (obj1.motion.stopTime - obj1.motion.startTime);
4819						switch (obj1.motion.transactionType) {
4820							case 'square':		//si sposta con un unico fotogramma, che è quello centrale rispetto al tempo di transizione indicato.
4821								str1 = obj1.motion.startValue + ((obj1.motion.stopValue - obj1.motion.startValue) * Math.round(cont2));
4822								break;
4823							case 'sin':			//da riposo a MouseOver: parte veloce e si ferma lentamente
4824								str1 = obj1.motion.startValue + ((obj1.motion.stopValue - obj1.motion.startValue) * Math.sin(cont2 * Math.PI / 2));
4825								break;
4826							case 'cos':			//da riposo a MouseOver: parte lento e si ferma di scatto
4827								str1 = obj1.motion.stopValue - ((obj1.motion.stopValue - obj1.motion.startValue) * Math.cos(cont2 * Math.PI / 2));
4828								break;
4829							case 'triangle':	//movimento a velocità costante
4830							default:
4831								str1 = obj1.motion.startValue + ((obj1.motion.stopValue - obj1.motion.startValue) * cont2);
4832						}
4833					}
4834					obj1.value = obj1.motion.attributeFormat.replace('#', str1);
4835				}
4836				//Eseguo le animazioni
4837				for (cont1 in listaMotions) {
4838					obj1 = listaMotions[cont1];
4839					SetProperty(obj1.motion.htmlObject, obj1.motion.attributeName, obj1.value);
4840				}
4841				//Controllo [currTime] e valuto se sono arrivato alla fine del clip
4842				if (this._status == 'play') {
4843					if (this._speed > 0 && currTime == 100 || this._speed < 0 && currTime == 0) {
4844						this.Pause();
4845					}
4846				}
4847				this._time = currTime;
4848				//Eseguo gli eventi
4849				for (cont1 in listaEvents) {
4850					obj1 = listaEvents[cont1];
4851					switch (typeof(obj1.action)) {
4852						case 'function':
4853							this._showFrame_callPool.push([obj1.action, this, currTime]);
4854							//obj1.action(this, currTime);
4855							break;
4856						case 'string':
4857							str1 = obj1.action;
4858							str1 = str1.replace(/\[THIS.ID]/g, this.id);
4859							str1 = str1.replace(/\[THIS]/g, 'window.HtmlPlus_ClipMakerColl[\'' + CStrJS(this.id) + '\']');
4860							str1 = str1.replace(/\[CURRENT_TIME]/g, currTime);
4861							str1 = str1.replace(/\[CURRENT_STATUS]/g, this._status);
4862							//eval(str1);
4863							this._showFrame_callPool.push(str1);
4864							break;
4865					}
4866				}
4867			}
4868			//window.status = 'Status = ' + this.Status() + '   Speed = ' + this.GetSpeed() + '    Time = ' + this.GetTime();
4869			this._showFrame_running = false;
4870			this._showFrame_runCallPool();
4871			return true;
4872		} else {
4873			return false;
4874		}
4875	}
4876	this._showFrame_calcolaExpire = function (CurrTime, PrecTime, ObjMotion) {
4877		if (PrecTime <= CurrTime) {
4878			return ((ObjMotion.stopTime >= CurrTime) ? ObjMotion.stopTime - CurrTime : 0);
4879		} else {
4880			return ((ObjMotion.startTime <= CurrTime) ? CurrTime - ObjMotion.startTime : 0);
4881		}
4882	}
4883	this._showFrame_runCallPool = function () {
4884		var vett1 = this._showFrame_callPool.slice(0);
4885		var vett2;
4886		this._showFrame_callPool = new Array();
4887		for (cont1=0; cont1<vett1.length; cont1++) {
4888			vett2 = vett1[cont1];
4889			switch (ValueType(vett2)) {
4890				case 'Array':
4891					switch (vett2.length) {
4892						case 1: vett2[0](); break;
4893						case 2: vett2[0](vett2[1]); break;
4894						case 3: vett2[0](vett2[1], vett2[2]); break;
4895						case 4: vett2[0](vett2[1], vett2[2], vett2[3]); break;
4896						case 5: vett2[0](vett2[1], vett2[2], vett2[3], vett2[4]); break;
4897					}
4898					break;
4899				case 'string':
4900					eval(vett2);
4901					break;
4902			}
4903		}
4904	}
4905	
4906	this._initialize();
4907	return this;
4908}
4909
4910
4911function HtmlPlus_AnimationOnMouseEvents(IdObject, ControllerHtmlObject, AnimatedHtmlObject, AttributeName, AttributeUM_Format, ValueInMouseOut, ValueInMouseOver, TransactionType, TransactionTime, fps) {
4912	//Ogni oggetto [HtmlPlus_AnimationOnMouseEvents] può gestire una sola animazione, ma la classe è pensata per far si che si possano
4913	//agganciare più animazioni sugli stessi oggetti, animando attributi diversi, col medesimo oggetto ControllerHtmlObject.
4914	this.id = IdObject;
4915	this.objectType = 'HtmlPlus_AnimationOnMouseEvents';
4916	this.controllerHtmlObjectColl = ControllerHtmlObject;	//Riferimento all'oggetto che capterà gli eventi OnMouseOver e OnMouseOut (può essere un array di oggetti).
4917	this.animatedHtmlObject = AnimatedHtmlObject;			//Riferimento all'oggetto che deve essere animato.
4918	this.attributeName = AttributeName;			//Il nome dell'attributo che sarà modificato (es. 'left', 'top', 'width', 'height').
4919	this.attributeFormat = AttributeUM_Format;	//L'unità di misura del valore che verrà impostato all'attributo; se la stringa contiene il carattere "#" allora
4920												//la stringa verrà usata in modalità Format, sostituendo il carattere segnaposto "#" col valore numerico da settare;
4921												//Es.:    AttributeUM_Format = 'alpha(opacity=#)'    l'attributo verra settato con:   'alpha(opacity=12)'.
4922	this.valueInMouseOut = ValueInMouseOut;		//Il valore che deve avere l'attributo in posizione di riposo.
4923	this.valueInMouseOver = ValueInMouseOver;	//Il valore che deve avere l'attributo quando si verifica OnMouseOver su HtmlObject.
4924	this.transactionType = TransactionType;		//Il tipo di transazione; può essere: 'square', 'triangle', 'sin', 'cos'.
4925	this.transactionTime = TransactionTime;		//Durata della transazione (in secondi).
4926	this.fps = fps;								//Fotogrammi per secondo della transazione.
4927	this.enabled = true;						//Se impostato a FALSE, gli eventi OnMouseOver e OnMouseOut non produrranno alcun effetto.
4928	// -- eventi --
4929	this.OnAnimationEnd = null;					//Puntatore a funzione o comando JS da eseguire quando l'animazione è finita (vedere [_animateHtmlObject])
4930	
4931	
4932	if (!window.HtmlPlus_AnimationOnMouseEventsColl) window.HtmlPlus_AnimationOnMouseEventsColl = new Array();
4933	window.HtmlPlus_AnimationOnMouseEventsColl[this.id] = this;
4934	
4935	this._initialize = function () {
4936		var i;
4937		this._direzione = 0;
4938		this._currAction = '';
4939		this._tmr = null;
4940		this._startTime = null;
4941		this._perc = 0;
4942		if (!this.fps) this.fps = GetBrowserInfo('RecommendedFps');
4943		switch (ValueType(this.controllerHtmlObjectColl)) {
4944			case 'Object':
4945				i = this.controllerHtmlObjectColl;
4946				this.controllerHtmlObjectColl = [i];
4947				break;
4948			case 'Array':
4949				for (i in this.controllerHtmlObjectColl) {
4950					if (typeof(this.controllerHtmlObjectColl[i]) == 'string') this.controllerHtmlObjectColl[i] = findObj(this.controllerHtmlObjectColl[i]);
4951				}
4952				break;
4953			case 'string':
4954				this.controllerHtmlObjectColl = [findObj(this.controllerHtmlObjectColl)];
4955				break;
4956			default:
4957				this.controllerHtmlObjectColl = null;
4958		}
4959		if (typeof(this.animatedHtmlObject) != 'object') this.animatedHtmlObject = findObj(this.animatedHtmlObject);
4960		if (this.controllerHtmlObjectColl) {
4961			for (i in this.controllerHtmlObjectColl) {
4962				this._initializeControllerHtmlObject(this.controllerHtmlObjectColl[i]);
4963			}
4964		}
4965		if (this.attributeFormat.indexOf('#') == -1) this.attributeFormat = '#' + this.attributeFormat;
4966	}
4967	
4968	this._initializeControllerHtmlObject = function (ControllerHtmlObject) {
4969		var i;
4970		if (!ControllerHtmlObject.HtmlPlus_AnimationOnMouseEventsColl) {
4971			ControllerHtmlObject.HtmlPlus_AnimationOnMouseEventsColl = new Array();
4972			addEvent(ControllerHtmlObject, 'mouseover', function (ev) {
4973						var eventObj = new STDEvent(ev);
4974						for (i in eventObj.srcElement.HtmlPlus_AnimationOnMouseEventsColl) {
4975							eventObj.srcElement.HtmlPlus_AnimationOnMouseEventsColl[i].OnMouseOverHandler();
4976							break;
4977						}
4978					}
4979				);
4980			addEvent(ControllerHtmlObject, 'mouseout', function (ev) {
4981						var eventObj = new STDEvent(ev);
4982						for (i in eventObj.srcElement.HtmlPlus_AnimationOnMouseEventsColl) {
4983							eventObj.srcElement.HtmlPlus_AnimationOnMouseEventsColl[i].OnMouseOutHandler();
4984							break;
4985						}
4986					}
4987				);
4988		}
4989		if (!ControllerHtmlObject.HtmlPlus_AnimationOnMouseEventsColl[this.id]) {
4990			ControllerHtmlObject.HtmlPlus_AnimationOnMouseEventsColl[this.id] = this;
4991			if (ControllerHtmlObject.all) {
4992				for (i=0; i<ControllerHtmlObject.all.length; i++) this._initializeControllerHtmlObject(ControllerHtmlObject.all[i]);
4993			} else if (ControllerHtmlObject.childNodes) {
4994				for (i=0; i<ControllerHtmlObject.childNodes.length; i++) this._initializeControllerHtmlObject(ControllerHtmlObject.childNodes[i]);
4995			}
4996		}
4997	}
4998	this._setStatusVariables = function (NewAction, NewTransactionTime) {
4999		var ora = new Date().getTime();
5000		if (this._tmr) window.clearInterval(this._tmr);
5001		switch (this._currAction) {
5002			case '':
5003				this._startTime = ora;
5004				break;
5005			case 'ini':
5006				this._startTime = ora;
5007				break;
5008			case 'moved':
5009				if (NewAction == 'stop') {
5010					this._perc = 100 - (ora - this._startTime) / 1000 / NewTransactionTime * 100;
5011					this._startTime = ora - NewTransactionTime * 1000 * this._perc / 100;
5012				}
5013				break;
5014			case 'stop':
5015				if (NewAction == 'moved') {
5016					this._perc = 100 - (ora - this._startTime) / 1000 / NewTransactionTime * 100;
5017					this._startTime = ora - NewTransactionTime * 1000 * this._perc / 100;
5018				}
5019				break;
5020		}
5021		this._currAction = NewAction;
5022	}
5023	
5024	this.InitializeWithAnimation = function (InitializeValue, TransactionTime) {
5025		this._direzione = 1;
5026		SetProperty(this.animatedHtmlObject, this.attributeName, this.attributeFormat.replace('#',InitializeValue));
5027		this._setStatusVariables('ini', TransactionTime);
5028		this._tmr = setInterval('var obj = window.HtmlPlus_AnimationOnMouseEventsColl["' + this.id + '"]; obj._animateHtmlObject(' + InitializeValue + ', obj.valueInMouseOut, ' + TransactionTime + ');', 1000 / this.fps);
5029	}
5030	this.OnMouseOverHandler = function () {
5031		this.OnFiredEvent(true);
5032	}
5033	this.OnMouseOutHandler = function () {
5034		this.OnFiredEvent(false);
5035	}
5036	this.OnFiredEvent = function (IsBeginAnimation) {
5037		var i, j, obj, anim;
5038		for (i in this.controllerHtmlObjectColl) {
5039			obj = this.controllerHtmlObjectColl[i];
5040			for (j in obj.HtmlPlus_AnimationOnMouseEventsColl) {
5041				anim = obj.HtmlPlus_AnimationOnMouseEventsColl[j];
5042				if (anim._currAction != 'ini' && anim.enabled) {
5043					anim._direzione = ((IsBeginAnimation) ? 1 : -1);
5044					anim._setStatusVariables(((IsBeginAnimation) ? 'moved' : 'stop'), anim.transactionTime);
5045					anim._tmr = setInterval('var obj = window.HtmlPlus_AnimationOnMouseEventsColl["' + j + '"]; obj._animateHtmlObject(obj.valueInMouseOut, obj.valueInMouseOver, obj.transactionTime);', 1000 / this.fps);
5046				}
5047			}
5048		}
5049	}
5050	this._animateHtmlObject = function (StartValue, EndValue, TranslationTime) {
5051		var nuovoVal;
5052		var str1;
5053		var precAction;
5054		if (this._currAction != '') {
5055			//Incremento il valore [_PERC] di un tot per ogni esecuzione di questa funzione
5056			//this._perc = this._perc + 100 / (this.fps * TranslationTime);
5057			
5058			//Imposto il valore [_PERC] in base a quanto tempo è trascorso dall'inizio dell'animazione
5059			this._perc = (new Date().getTime() - this._startTime) / 1000 / TranslationTime * 100;
5060			if (this._direzione == -1) this._perc = 100 - this._perc;
5061			
5062			if (this._perc < 0) {
5063				this._perc = 0;
5064			} else if (this._perc > 100) {
5065				this._perc = 100;
5066			}
5067			switch (this._perc) {
5068				case 0:
5069					nuovoVal = StartValue;
5070					break;
5071				case 100:
5072					nuovoVal = EndValue;
5073					break;
5074				default:
5075					switch (this.transactionType) {
5076						case 'square':		//si sposta con un unico fotogramma, che è quello centrale rispetto al tempo di transizione indicato.
5077							nuovoVal = StartValue + ((EndValue - StartValue) * Math.round(this._perc / 100));
5078							break;
5079						case 'sin':			//da riposo a MouseOver: parte veloce e si ferma lentamente
5080							nuovoVal = StartValue + ((EndValue - StartValue) * Math.sin(this._perc * Math.PI / 200));
5081							break;
5082						case 'cos':			//da riposo a MouseOver: parte lento e si ferma di scatto
5083							nuovoVal = EndValue - ((EndValue - StartValue) * Math.cos(this._perc * Math.PI / 200));
5084							break;
5085						case 'triangle':	//movimento a velocità costante
5086						default:
5087							nuovoVal = StartValue + ((EndValue - StartValue) * (this._perc / 100));
5088					}
5089
5090					break;
5091			}
5092			str1 = this.attributeFormat.replace('#', nuovoVal);
5093			SetProperty(this.animatedHtmlObject, this.attributeName, str1);
5094			if (this._perc==0 && this._currAction=='stop' || this._perc==100 && this._currAction!='stop') {
5095				//Fine animazione.
5096				
5097				//Reset delle variabili per la gestione dell'animazione
5098				precAction = this._currAction;
5099				if (this._currAction == 'ini') this._perc = 0;
5100				this._currAction = '';
5101				window.clearInterval(this._tmr);
5102				
5103				//Invoco l'evento [OnAnimationEnd], se gestito.
5104				if (this.OnAnimationEnd) {
5105					switch (typeof(this.OnAnimationEnd)) {
5106						case 'function':
5107							this.OnAnimationEnd(this, precAction);
5108							break;
5109						case 'string':
5110							str1 = this.OnAnimationEnd;
5111							str1 = str1.replace(/\[THIS.ID]/g, this.id);
5112							str1 = str1.replace(/\[THIS]/g, 'window.HtmlPlus_AnimationOnMouseEventsColl[\'' + this.id + '\']');
5113							str1 = str1.replace(/\[CURRENT_ACTION]/g, precAction);
5114							eval(str1);
5115							break;
5116					}
5117				}
5118			}
5119		}
5120	}
5121	
5122	this._initialize();
5123	return this;
5124}
5125
5126
5127function HtmlPlus_PageScroller(idObject, AnimatedHtmlObject, IsVerticalScroll, PageWidth, CurrentPage, TransactionType, TransactionTime, fps) {
5128	this.id = idObject;
5129	this.objectType = 'HtmlPlus_PageScroller';
5130	this.animatedHtmlObject = AnimatedHtmlObject;		//Riferimento all'oggetto che deve essere animato. Attenzione: deve avere un solo figlio.
5131	this.isVerticalScroll = IsVerticalScroll;	//Se TRUE, indica che lo scroll deve avvenire verticalmente, altrimenti sarà orizzontalmente.
5132	this.pageWidth = PageWidth;					//Dimensione della pagina (larghezza o altezza in base all'orientamento dello scroll)
5133	this.currentPage = CurrentPage;				//La pagina corrente, a base ZERO.
5134	this.transactionType = TransactionType;		//Il tipo di transazione; può essere: 'square', 'triangle', 'sin', 'cos'
5135	this.transactionTime = TransactionTime;		//Durata della transazione fra una pagnia ed un'altra adiacente (in secondi)
5136	this.fps = fps;								//Fotogrammi per secondo della transazione
5137	this.enabled = true;						//Se impostato a FALSE, i metodi GoTo####Page non produrranno alcun effetto
5138
5139	if (!window.HtmlPlus_PageScrollerColl) window.HtmlPlus_PageScrollerColl = new Array();
5140	window.HtmlPlus_PageScrollerColl[this.id] = this;
5141	
5142	this._initialize = function () {
5143		var dimCorpo, obj1;
5144		//Preparo l'oggetto [animatedHtmlObject]
5145		this.animatedHtmlObject.style.overflow = 'hidden';
5146		//Creo e setto variabili pubbliche
5147		this.bodyWidth = (this.isVerticalScroll ? this.animatedHtmlObject.childNodes[0].offsetHeight : this.animatedHtmlObject.childNodes[0].offsetWidth);
5148		this.visibleWidth = GetValue(GetCssStyle(this.animatedHtmlObject, (this.isVerticalScroll ? 'height' : 'width'))).number;
5149		if (this.bodyWidth <= this.visibleWidth) {
5150			this.pages = 1;
5151		} else {
5152			this.pages = Math.ceil(this.bodyWidth / this.pageWidth) - (Math.floor(this.visibleWidth / this.pageWidth) - 1);
5153			//Se l'ultima pagina non è completamente piena, allora aggiungo un DIV per riempirla con spazio vuoto.
5154			dimCorpo = this.pageWidth * (this.pages - 1) + this.visibleWidth;
5155			if (dimCorpo != this.bodyWidth) {
5156				obj1 = this.animatedHtmlObject.childNodes[0];
5157				SetProperty(obj1, ((this.isVerticalScroll) ? 'height' : 'width'), dimCorpo.toString() + 'px');
5158			}
5159		}
5160		if (!this.fps) this.fps = GetBrowserInfo('RecommendedFps');
5161		//Creo e setto variabili private
5162		this._attributeName = ((this.isVerticalScroll) ? 'scrollTop' : 'scrollLeft');
5163		this._currAction = '';
5164		this._tmr = null;
5165		this._startTime = null;
5166		this._perc = 0;
5167		//Mi posiziono nella PAGINA CORRENTE indicata nella creazione dell'oggetto
5168		SetProperty(this.animatedHtmlObject, this._attributeName, this.pageWidth * this.currentPage);
5169	}
5170	this._setStatusVariables = function (NewAction, NewTransactionTime) {
5171		var ora = new Date().getTime();
5172		if (this._tmr) window.clearInterval(this._tmr);
5173		switch (this._currAction) {
5174			case '':		//Nessuna azione in corso.
5175				this._perc = 0;
5176				this._startTime = ora;
5177				break;
5178			case 'ini':		//Azione in corso, inizializzazione.
5179				this._perc = 0;
5180				this._startTime = ora;
5181				this.currentPage = this._getTemporaryCurrentPage();
5182				break;
5183			case 'move':	//Azione in corso, spostamento in nuova pagina.
5184				this._perc = 0;
5185				this._startTime = ora;
5186				this.currentPage = this._getTemporaryCurrentPage();
5187				break;
5188		}
5189		this._currAction = NewAction;
5190	}
5191	this._getTemporaryCurrentPage = function () {
5192		var currPx;
5193		currPx = toNumber(GetProperty(this.animatedHtmlObject, this._attributeName), 0);
5194		return currPx / this.pageWidth;
5195	}
5196	this._getTransactionTotalTime = function (Pixels, TransactionTime) {
5197		var pagine = Pixels / this.pageWidth;
5198		switch (this.transactionType) {
5199			case 'square':		//si sposta con un unico fotogramma, che è quello centrale rispetto al tempo di transizione indicato.
5200				return TransactionTime;
5201				break;
5202			case 'sin':			//parte veloce e si ferma lentamente, l'ultima pagina è a velocità variabile
5203				if (pagine <= 1) {
5204					return TransactionTime * pagine;
5205				} else {
5206					return TransactionTime + (pagine - 1) * TransactionTime * Math.sin(100 / (TransactionTime * this.fps) * Math.PI / 200);
5207				}
5208				break;
5209			case 'cos':			//parte lento e si ferma di scatto, la prima pagina è a velocità variabile
5210				if (pagine <= 1) {
5211					return TransactionTime * pagine;
5212				} else {
5213					return TransactionTime + (pagine - 1) * TransactionTime * Math.cos(100 / (TransactionTime * this.fps) * Math.PI / 200);
5214				}
5215				break;
5216			case 'triangle':	//movimento a velocità costante
5217			default:
5218				return TransactionTime * pagine;
5219		}
5220	}
5221	this._scrollPage = function (StartPixel, EndPixel, TransactionTime) {
5222		var nuovoVal, tempoTot, tempoTrascorso, cont1;
5223		if (this._currAction != '') {
5224			//Imposto il valore [_PERC] in base a quanto tempo è trascorso dall'inizio dell'animazione
5225			tempoTot = this._getTransactionTotalTime(Math.abs(StartPixel - EndPixel), TransactionTime);
5226			tempoTrascorso = (new Date().getTime() - this._startTime) / 1000;
5227			this._perc = tempoTrascorso / tempoTot * 100;
5228			if(this._perc<0) this._perc=0; else if(this._perc>100) this._perc=100;
5229			
5230			switch (this._perc) {
5231				case 0:
5232					nuovoVal = StartPixel;
5233					break;
5234				case 100:
5235					nuovoVal = EndPixel;
5236					break;
5237				default:
5238					switch (this.transactionType) {
5239						case 'square':		//si sposta con un unico fotogramma, che è quello centrale rispetto al tempo di transizione indicato.
5240							nuovoVal = StartPixel + ((EndPixel - StartPixel) * Math.round(this._perc / 100));
5241							break;
5242						case 'sin':			//parte veloce e si ferma lentamente, l'ultima pagina è a velocità variabile
5243											//...in realtà non son riuscito a farlo, mi ci voleva troppo.
5244							nuovoVal = StartPixel + ((EndPixel - StartPixel) * Math.sin(this._perc * Math.PI / 200));
5245							break;
5246						case 'cos':			//parte lento e si ferma di scatto, la prima pagina è a velocità variabile
5247							nuovoVal = EndPixel - ((EndPixel - StartPixel) * Math.cos(this._perc * Math.PI / 200));
5248							break;
5249						case 'triangle':	//movimento a velocità costante
5250						default:
5251							nuovoVal = StartPixel + ((EndPixel - StartPixel) * (this._perc / 100));
5252					}
5253					nuovoVal = Math.round(nuovoVal);
5254					break;
5255			}
5256			
5257			SetProperty(this.animatedHtmlObject, this._attributeName, nuovoVal);
5258			if (this._perc == 100) {
5259				window.clearInterval(this._tmr);
5260				this._currAction = '';
5261				cont1 = this.currentPage;
5262				this.currentPage = nuovoVal / this.pageWidth;
5263				this.OnAfterPageChanged(this, cont1, this.currentPage);
5264			}
5265		}
5266	}
5267	
5268	this.GoToPage = function (PageNumber, optIsRelative) {
5269		//Sposta la pagina corrente. Argomenti:
5270		//	PageNumber:		la nuova pagina in cui si viene spostati;
5271		//	optIsRelative:	se TRUE, l'argomento [PageNumber] è da intendersi come incremento/decremento rispetto alla pagina corrente.
5272		var nuovaPag, startPx, endPx;
5273		if (optIsRelative) {
5274			nuovaPag = this.currentPage + PageNumber;
5275		} else {
5276			nuovaPag = PageNumber;
5277		}
5278		if (nuovaPag < 0) nuovaPag = 0;
5279		if (nuovaPag >= this.pages) nuovaPag = this.pages - 1;
5280		if (this.enabled && (this._currentAction=='' && nuovaPag!=this.currentPage || this._currentAction!='' && nuovaPag!=this._getTemporaryCurrentPage())) {
5281			this.OnBeforePageChanging(this, this.currentPage, nuovaPag);
5282			this._setStatusVariables('move', this.transactionTime);
5283			startPx = toNumber(GetProperty(this.animatedHtmlObject, this._attributeName), 0);
5284			endPx = this.pageWidth * nuovaPag;
5285			this._tmr = setInterval('var obj = window.HtmlPlus_PageScrollerColl["' + this.id + '"]; obj._scrollPage(' + startPx.toString() + ', ' + endPx.toString() + ', obj.transactionTime);', 1000 / this.fps);
5286		}
5287	}
5288	this.GoToFirstPage = function () { this.GoToPage(0); }
5289	this.GoToPreviousPage = function () { this.GoToPage(-1, true); }
5290	this.GoToNextPage = function () { this.GoToPage(+1, true); }
5291	this.GoToLastPage = function () { this.GoToPage(this.pages - 1); }
5292	
5293	/* Definizione eventi */
5294	this.OnAfterPageChanged = function (PageScroller, OldPage, CurrentPage) {return void(0);}
5295	this.OnBeforePageChanging = function (PageScroller, CurrentPage, NewPage) {return void(0);}
5296	
5297	this._initialize();
5298	return this;
5299}
5300
5301
5302function HtmlPlus_TextboxWithLabelInside(IdObject, TextboxObject, ValueObject, LabelString, NullValue, TextboxModeCssStyle, LabelModeCssStyle) {
5303	this.id = IdObject;
5304	this.objectType = 'HtmlPlus_TextboxWithLabelInside';
5305	this.textboxObject = TextboxObject;		//L'oggetto TextBox che mostra la LABEL e dove vengono immessi i dati
5306	this.valueObject = ValueObject;			//L'oggetto "<input type=hidden" su cui viene memorizzato il valore vero
5307	this.label = LabelString;				//Il testo da mostrare quando il valore non è indicato
5308	this.nullValue = NullValue;				//Il valore da salvare quando non vi è un valore inserito
5309	this.textboxModeCssStyle = TextboxModeCssStyle;		//Lo stile del Textbox quando la modalità è 'textbox' (contiene un valore o ha focus)
5310	this.labelModeCssStyle = LabelModeCssStyle;			//Lo stile del Textbox quando la modalità è 'label' (non contiene un valore e non ha focus)
5311	this.currentMode = '';					//Può essere 'label' o 'textbox'. Indica cosa viene mostrato nel textbox e con quale stile.
5312	this.enabled = true;
5313	
5314	if (!window.HtmlPlus_TextboxWithLabelInsideColl) window.HtmlPlus_TextboxWithLabelInsideColl = new Array();
5315	window.HtmlPlus_TextboxWithLabelInsideColl[this.id] = this;
5316	
5317	this._initialize = function () {
5318		if (!this.textboxObject.TextboxWithLabelInsideObject) {
5319			this.textboxObject.TextboxWithLabelInsideObject = this;
5320			addEvent(this.textboxObject, 'focus', function (ev) {
5321						var eventObj = new STDEvent(ev);
5322						eventObj.srcElement.TextboxWithLabelInsideObject.OnFocusInHandler();
5323					}
5324				);
5325			addEvent(this.textboxObject, 'blur', function (ev) {
5326						var eventObj = new STDEvent(ev);
5327						eventObj.srcElement.TextboxWithLabelInsideObject.OnFocusOutHandler();
5328					}
5329				);
5330			addEvent(this.textboxObject, 'keydown', function (ev) {
5331						var eventObj = new STDEvent(ev);
5332						eventObj.srcElement.TextboxWithLabelInsideObject.OnKeyDownHandler(eventObj);
5333					}
5334				);
5335			this.currentMode = '';
5336			this.SetValue(this.GetValue());
5337		}
5338	}
5339	this.OnFocusInHandler = function () {
5340		var str1 = this.GetValue();
5341		if (str1 == '') {
5342			this.currentMode = 'textbox';
5343			SetCssStyle(this.textboxObject, this.textboxModeCssStyle);
5344		}
5345		this.SetValue(str1);
5346	}
5347	this.OnFocusOutHandler = function () {
5348		var str1 = this.GetValue(true);
5349		if (str1 == '') {
5350			this.currentMode = 'label';
5351			SetCssStyle(this.textboxObject, this.labelModeCssStyle);
5352		}
5353		this.SetValue(str1);
5354	}
5355	this.OnKeyDownHandler = function (eventObject) {
5356		if (eventObject.keyCode == 13) {
5357			this.SetValue(this.GetValue(true));
5358		}
5359	}
5360	this.GetValue = function (GetTextboxValue) {
5361		//La funzione restituisce il valore REALE del TextBox. Se il valore non è definito, restituisce <stringa-vuota>.
5362		var str1;
5363		if (GetTextboxValue) {
5364			str1 = this.textboxObject.value;
5365			str1 = ((str1 == this.label || str1 == this.nullValue) ? '' : str1);
5366		} else {
5367			str1 = this.valueObject.value;
5368			str1 = ((str1 == this.nullValue) ? '' : str1);
5369		}
5370		return str1;
5371	}
5372	this.SetValue = function (NewValue) {
5373		var str1 = NewValue.toString();
5374		if (str1 == '') {
5375			switch (this.currentMode) {
5376				case 'label':
5377					this.textboxObject.value = this.label;
5378					break;
5379				case 'textbox':
5380					this.textboxObject.value = '';
5381					break;
5382				default:
5383					this.textboxObject.value = this.label;
5384					SetCssStyle(this.textboxObject, this.labelModeCssStyle);
5385					this.currentMode = 'label';
5386			}
5387		} else {
5388			if (this.textboxObject.value != str1) this.textboxObject.value = str1;
5389			switch (this.currentMode) {
5390				case 'textbox':
5391					break;
5392				default:
5393					SetCssStyle(this.textboxObject, this.textboxModeCssStyle);
5394					this.currentMode = 'textbox';
5395			}
5396		}
5397		this.valueObject.value = ((str1 == '') ? this.nullValue : str1);
5398	}
5399	
5400	this._initialize();
5401	return this;
5402}
5403
5404function HtmlPlus_BarcodeReader(IdObject, KeyChars, Action, MinLen, MaxLen, BarcodeConf_PreChar, BarcodeConf_PostChar) {
5405	this.id = IdObject;
5406	this.objectType = 'HtmlPlus_BarcodeReader';
5407	this.keyChars = KeyChars;				//Stringa CHIAVE. Il barcode letto verrà preso in esame solo se inizia con questa
5408											//stringa (può essere NULL).
5409	this.action = Action;					//Azione da eseguire quando viene letto un codice a barre; può essere String o Function.
5410	this.minLen = MinLen;					//(opz) Lunghezza minima del barcode.
5411	this.maxLen = MaxLen;					//(opz) Lunghezza massima del barcode.
5412	this.bcCfg_Pre = null;					//(opz) Carattere di preambolo. Verrà ritenuto "barcode" solo le battiture a tastiera
5413											//che iniziano con questo carattere.
5414	this.bcCfg_Post = null;					//(opz) Carattere di postambolo. Verrà ritenuto "barcode" solo le battiture a tastiera
5415											//che finiscono con questo carattere.
5416											//ATTENZIONE: i caratteri preambolo e postambolo devono essere gli stessi per tutti gli
5417											//oggetti [HtmlPlus_BarcodeReader].
5418	this.timeout = 500;						//Tempo massimo (in millisec) fra ogni pressione di tasto affinchè si possa ritenere
5419											//che si sta leggendo un "barcode" valido; dopodichè la lettura viene annullata.
5420	this.runOneAction = true;				//Se TRUE, quando si è letto un Barcode, verrà eseguita l'Azione appartenente al primo
5421											//oggetto [HtmlPlus_BarcodeReader] compatibile col Barcode letto, in ordine di lunghezza
5422											//di KeyChars, dal più lungo al più corto. Se FALSE verranno eseguite tutte le Azioni.
5423	
5424	this._initialize = function () {
5425		var primoBarcode = false;
5426		if (!window.HtmlPlus_BarcodeReaderColl) {
5427			window.HtmlPlus_BarcodeReaderColl = new Array();
5428			window.HtmlPlus_BarcodeReader__runtime_curKeybStrm = '';
5429			window.HtmlPlus_BarcodeReader__runtime_tmr = 0;
5430			primoBarcode = true;
5431		}
5432		window.HtmlPlus_BarcodeReaderColl[this.id] = this;
5433		if (primoBarcode) {
5434			addEvent(window.document, 'keypress', function(ev) {
5435						var i, objMaster;
5436						for (i in window.HtmlPlus_BarcodeReaderColl) {
5437							objMaster = window.HtmlPlus_BarcodeReaderColl[i];
5438							break;
5439						}
5440						objMaster.DOCUMENT_OnKeyPressHandler(ev);
5441					}
5442				);
5443			if (window.DevelopingMode) DevelopingModeMenu_AddItem('BarcodeReader - Test', 'window.HtmlPlus_BarcodeReaderColl[\'' + CStrJS(this.id) + '\'].DOCUMENT_RunBarcode(window.prompt("[HtmlPlus_BarcodeReader - Test] :  inserisci il codice barcode di cui simulare la lettura:", ""));');
5444		}
5445		if (!this.keyChars) this.keyChars = '';
5446		if (!this.minLen) this.minLen = 1;
5447		
5448		this._initialize_ObjMaster();
5449	}
5450	this._initialize_ObjMaster = function() {
5451		var objMaster = this._getObjMaster();
5452		objMaster.bcCfg_Pre = BarcodeConf_PreChar;
5453		objMaster.bcCfg_Post = BarcodeConf_PostChar;
5454		if (!objMaster.bcCfg_Pre) objMaster.bcCfg_Pre =		['\x02','\x02'];
5455		if (!objMaster.bcCfg_Post) objMaster.bcCfg_Post =	['\x03','\x04'];
5456		if (ValueType(objMaster.bcCfg_Pre) != 'Array') objMaster.bcCfg_Pre = new Array(objMaster.bcCfg_Pre);
5457		if (ValueType(objMaster.bcCfg_Post) != 'Array') objMaster.bcCfg_Post = new Array(objMaster.bcCfg_Post);
5458		objMaster._resetListener(false);
5459	}
5460	
5461	this.DOCUMENT_OnKeyPressHandler = function (ev) {
5462		var eventObj = new STDEvent(ev);
5463		var i, vett1, obj, chrLetto, barcodeLetto;
5464		var inLettura = false;
5465		chrLetto = String.fromCharCode(eventObj.keyCode);
5466		switch (this._readingInfo.state) {
5467			case 0:		//Non sono in stato LETTURA.
5468				if (InArray(this.bcCfg_Pre, chrLetto) !== null) {
5469					//Inizio LETTURA.
5470					this._resetListener(true);
5471					this._readingInfo.state = 1;
5472					this._readingInfo.preChar = chrLetto;
5473					this._readingInfo.postCharList = new Array();
5474					for (i = 0; i < this.bcCfg_Pre.length; i++) {
5475						if (this.bcCfg_Pre[i] == chrLetto) this._readingInfo.postCharList.push(this.bcCfg_Post[i]);
5476					}
5477					inLettura = true;
5478				}
5479				break;
5480			case 1:		//Ho letto il preambolo
5481			case 2:		//Sono in corso di lettura del barcode
5482				//...aspetto il carattere di POSTAMBOLO.
5483				inLettura = true;
5484				if (InArray(this._readingInfo.postCharList, chrLetto) === null) {
5485					this._readingInfo.keybStream += chrLetto;
5486					this._resetTimer(true);
5487				} else {
5488					//Sono alla fine della lettura.
5489					this.DOCUMENT_RunBarcode(this._readingInfo.keybStream);
5490					this._resetListener(false);
5491				}
5492				break;
5493		}
5494		if (inLettura) {
5495			eventObj.cancelBubble(true);
5496			eventObj.returnValue(null);
5497		}
5498	}
5499	this.DOCUMENT_OnTimeoutHandler = function () {
5500		this._resetListener(false);
5501	}
5502	this.DOCUMENT_RunBarcode = function (BarcodeString) {
5503		var i, obj;
5504		if (this.runOneAction) {
5505			//Cerco l'oggetto [HtmlPlus_BarcodeReader] che ha il parametro KeyChars più lungo
5506			var maxLenKeyChars = 0;
5507			var ok;
5508			for (i in window.HtmlPlus_BarcodeReaderColl) {
5509				obj = window.HtmlPlus_BarcodeReaderColl[i];
5510				if (obj.keyChars) {
5511					if (maxLenKeyChars < obj.keyChars.length) maxLenKeyChars = obj.keyChars.length;
5512				}
5513			}
5514			//Ora sfoglio tutti gli oggetti [HtmlPlus_BarcodeReader] in ordine di lunghezza KeyChars, dal più lungo al più corto
5515			ok = false;
5516			for (maxLenKeyChars=maxLenKeyChars; maxLenKeyChars >= 0; maxLenKeyChars--) {
5517				for (i in window.HtmlPlus_BarcodeReaderColl) {
5518					obj = window.HtmlPlus_BarcodeReaderColl[i];
5519					if (maxLenKeyChars == obj.keyChars.length) {
5520						ok = obj.RunAction(BarcodeString);
5521						if (ok) break;
5522					}
5523				}
5524				if (ok) break;
5525			}
5526		} else {
5527			for (i in window.HtmlPlus_BarcodeReaderColl) {
5528				obj = window.HtmlPlus_BarcodeReaderColl[i];
5529				obj.RunAction(BarcodeString);
5530			}
5531		}
5532	}
5533	
5534	this.CheckBarcodeCompatibility = function (BarcodeString) {
5535		var fReturn = true;
5536		fReturn = true;
5537		if (fReturn && this.keyChars) fReturn = ((BarcodeString.substr(0, this.keyChars.length) == this.keyChars) ? true : false);
5538		if (fReturn && this.minLen) fReturn = ((BarcodeString.length >= this.minLen) ? true : false);
5539		if (fReturn && this.maxLen) fReturn = ((BarcodeString.length <= this.maxLen) ? true : false);
5540		return fReturn;
5541	}
5542	this.RunAction = function (BarcodeString, optCheckBarcodeCompatibility) {
5543		//Attenzione: se il parametro [optCheckBarcodeCompatibility] è omesso, si intenderà TRUE.
5544		//Restituisce True se l'azione è stata eseguita.
5545		var ok, str1;
5546		if (IsFalse(optCheckBarcodeCompatibility)) {
5547			ok = true;
5548		} else {
5549			ok = this.CheckBarcodeCompatibility(BarcodeString);
5550		}
5551		if (ok) {
5552			switch (typeof(this.action)) {
5553				case 'string':
5554					str1 = this.action;
5555					str1 = str1.replace(/\[BARCODE]/g, BarcodeString);
5556					str1 = str1.replace(/\[KEYCHARS]/g, this.keyChars);
5557					eval(str1);
5558					break;
5559				case 'function':
5560					this.action(BarcodeString, this);
5561					break;
5562				default:
5563					alert('ERRORE in HtmlPlus_BarcodeReader: il parametro ACTION deve essere una function o una string contenente un comando JavaScript.');
5564					ok = false;
5565			}
5566		}
5567		return ok;
5568	}
5569	
5570	this._getObjMaster = function () {
5571		var objMaster, i;
5572		for (i in window.HtmlPlus_BarcodeReaderColl) {
5573			objMaster = window.HtmlPlus_BarcodeReaderColl[i];
5574			break;
5575		}
5576		return objMaster;
5577	}
5578	this._resetListener = function(StartTimer) {
5579		var objMaster = this._getObjMaster();
5580		this._resetTimer(false);
5581		objMaster._readingInfo = {tmr:null, state:0, keybStream:'', preChar:null, postCharList:null};
5582		if (StartTimer) objMaster._resetTimer(true);
5583	}
5584	this._resetTimer = function(StartTimer) {
5585		var objMaster = this._getObjMaster();
5586		if (objMaster._readingInfo) {
5587			if (objMaster._readingInfo.tmr) window.clearTimeout(objMaster._readingInfo.tmr);
5588		}
5589		if (StartTimer) {
5590			objMaster._readingInfo.tmr = setTimeout('var i, objMaster;' +
5591					'for (i in window.HtmlPlus_BarcodeReaderColl) {' +
5592						'objMaster = window.HtmlPlus_BarcodeReaderColl[i];' +
5593						'break;' +
5594					'}' +
5595					'objMaster.DOCUMENT_OnTimeoutHandler();', objMaster.timeout);
5596		}
5597	}
5598	
5599	this._initialize();
5600	return this;
5601}
5602
5603
5604
5605
5606function HtmlPlus_ServerEval(IdObject, Server, Code) {
5607	this.id = IdObject;
5608	this.objectType = 'HtmlPlus_ServerEval';
5609	this.server = Server;				// Può essere ASP oppure ASPX per indicare che deve invocare le pagine standard, oppure un percorso intero per indicare che deve invocare una pagina precisa.
5610	this.code = Code;					// Il codice da eseguire
5611	
5612	if (!window.HtmlPlus_ServerEvalColl) window.HtmlPlus_ServerEvalColl = new Array();
5613	window.HtmlPlus_ServerEvalColl[this.id] = this;
5614	
5615	this._initialize = function(){
5616		switch (this.server.toLowerCase()) {
5617			case 'asp':
5618				this.server = 'asp';
5619				break;
5620			case 'aspx':
5621				this.server = 'aspx';
5622				break;
5623			default:
5624				if (this.server.substr(0, 4) != 'http') this.server = R + this.server;
5625		}
5626		
5627		this._container = null;
5628		this._container_iFrame = null;
5629		
5630		this._parameters = null;
5631		this._isResponseAvailable = false;
5632		this._isResponseAbort = null;
5633		this._returnValue = null;
5634		this._isRun = false;
5635		this._generaFrame_onLoad_Eseguito = false;
5636		
5637	}
5638	
5639	this._generaFrame = function(srParameters, optDebugMode) {
5640		var cont1, str1, strJS;
5641		
5642		// Inizializzazione del DIV contenitore
5643		this._container = document.createElement('DIV');
5644		this._container.id = this.id;
5645		this._container.style.position = 'absolute';
5646		this._container.style.overflow = 'auto';
5647		this._container.style.zIndex = 10020;
5648		this._container.style.width = '330px';	this._container.style.height = '150px';
5649		this._container.style.left = '-600px';	this._container.style.top = '0px';
5650		if (optDebugMode) {
5651			cont1 = -1;
5652			for (str1 in HtmlPlus_ServerEvalColl) {
5653				cont1++; if (str1 == this.id) break;
5654			}
5655			this._container.style.left = (GetValue(this._container.style.width).number * cont1).toString() + 'px';
5656		}
5657		this._container.ObjServerEval = this;
5658		this._container.style.display = (optDebugMode?'block':'none');
5659		document.body.appendChild(this._container);
5660		
5661		// Creazione [contenuto] del DIV
5662		this._container_iFrame = document.createElement('IFRAME');
5663		this._container.appendChild(this._container_iFrame);
5664		switch (this.server) {
5665			case 'asp':
5666				this._container_iFrame.src = R + '_Include/AspResponder.asp?cli=Brw';
5667				break;
5668			case 'aspx':
5669				this._container_iFrame.src = R + '_Include/AspxResponder.aspx?cli=Brw';
5670				break;
5671			default:
5672				this._container_iFrame.src = this.server;
5673		}
5674		
5675		this._generaFrame_onLoad_Eseguito = false;
5676		strJS = 'addEvent(this._container_iFrame, \'load\', function(ev) {' + 
5677						'var eventObj = new STDEvent(ev);' +
5678						'eval(\'' + CStrJS('window.HtmlPlus_ServerEvalColl[\'' + CStrJS(this.id) + '\']._generaFrame_onLoad(\'' + CStrJS(srParameters) + '\');') + '\');' + 
5679					'}
5679' +
5680				');';
5681		eval(strJS);
5682	}
5683	
5684	this._generaFrame_onLoad = function(srParameters) {
5685		var strJS;
5686		strJS = '';
5687		strJS += 'window.HtmlPlus_ServerEvalColl[\'' + CStrJS(this.id) + '\']._container_iFrame.contentWindow.Interface_HtmlPlus_ServerEval_OnSubmit = function (ReturnSerializedValue, IsAbort) {' +
5688					'window.HtmlPlus_ServerEvalColl[\'' + CStrJS(this.id) + '\'].End(DeserializeValue(ReturnSerializedValue), IsAbort);' +
5689				'};';
5690		strJS += 'window.HtmlPlus_ServerEvalColl[\'' + CStrJS(this.id) + '\']._container_iFrame.contentWindow.Interface_HtmlPlus_ServerEval_IsReady = function () {' +
5691					'return true;' +
5692				'};';
5693		eval(strJS);
5694		if (!this._generaFrame_onLoad_Eseguito) {
5695			this._container_iFrame.contentWindow.Interface_HtmlPlus_ServerEval_OnLoad(this.code, srParameters);
5696			this._generaFrame_onLoad_Eseguito = true;
5697		}
5698		this.OnRun(this);
5699	}
5700	
5701	this.Run = function(Parameters, optDebugMode) {
5702		//Lancia il comando server. Argomenti:
5703		//	Parameters :		array in stile "Dictionary" con la lista degli parametri da passare al server.
5704		if (this.IsRun()) {
5705			return false;
5706		} else {
5707			this._parameters = Parameters;
5708			this._isResponseAvailable = false;
5709			this._isResponseAbort = null;
5710			this._returnValue = null;
5711			this._isRun = true;
5712			
5713			//Generazione oggetti HTML e passaggio argomento [Parameters]
5714			if (!this._container) {
5715				this._generaFrame(SerializeValue(Parameters), optDebugMode);
5716			} else {
5717				this._container_iFrame.contentWindow.Interface_HtmlPlus_ServerEval_OnLoad(this.code, SerializeValue(Parameters));
5718				this.OnRun(this);
5719			}
5720			
5721			return true;
5722		}
5723	}
5724	this.Break = function() {
5725		//Termina il comando server e setta l'esito in ABORT.
5726		if (this.IsRun()) {
5727			this._isRun = false;
5728			this._isResponseAvailable = true;
5729			this._isResponseAbort = true;
5730			this._returnValue = null;
5731			
5732			this.OnEnd(this, this._returnValue, this._isResponseAbort);
5733			return true;
5734		} else {
5735			return false;
5736		}
5737	}
5738	this.End = function(ReturnValue, IsAbort) {
5739		//Chiude il comando server, ed imposta sia il [Valore] da restituire sia lo stato [IsAbort].
5740		if (this.IsRun()) {
5741			this._isRun = false;
5742			this._isResponseAvailable = true;
5743			this._isResponseAbort = ((IsAbort) ? true : false);
5744			this._returnValue = ReturnValue;
5745			
5746			this.OnEnd(this, this._returnValue, this._isResponseAbort);
5747			return true;
5748		} else {
5749			return false;
5750		}
5751	}
5752	this.Parameters = function() {
5753		return this._parameters;
5754	}
5755
5756	this.IsRun = function() {
5757		return this._isRun;
5758	}
5759	this.IsResponseAvailable = function() {
5760		return this._isResponseAvailable;
5761	}
5762	this.IsResponseAbort = function() {
5763		return ((this._isResponseAvailable) ? this._isResponseAbort : null);
5764	}
5765	this.ReturnValue = function() {
5766		return ((this._isResponseAvailable) ? this._returnValue : null);
5767	}
5768	
5769	/* Definizione eventi */
5770	this.OnRun = function (ServerEval) {return void(0);}							//Invocata quando il metodo Run viene lanciato
5771	this.OnEnd = function (ServerEval, ReturnValue, IsAbort) {return void(0);}		//Invocata quando il Popup viene chiuso
5772	
5773	this._initialize();
5774	return this;
5775}
5776
5777
5778
5779function HtmlPlus_Popup(IdObject, Title, Src, PopupWidth, PopupHeight, ContentWidth, ContentHeight, CssPrefix) {
5780	this.id = IdObject;
5781	this.objectType = 'HtmlPlus_Popup';
5782	this.cssPrefix = CssPrefix;			// Prefisso che serve per l'utilizzazione delle classi Css da utilizzare
5783	this.lblTitle = Title;				// E' il titolo della finestra
5784	this.lblClose = 'X';				// E' il testo del pulsante di chiusura
5785	this.src = Src;						// Può essere un percorso, o un testo HTML
5786	this.showInTopFrame = true;			// Se TRUE il popup verrà disegnato nel frame principale
5787	this.popupWidth = PopupWidth;		// Larghezza del contenitore
5788	this.popupHeight = PopupHeight;		// Larghezza del contenitore
5789	this.contentWidth = ContentWidth;	// Larghezza del contenitore
5790	this.contentHeight = ContentHeight;	// Altezza del contenitore
5791	this.container = null;				// contenitore Popup
5792	this.container_content = null;		// contenuto del Popup
5793	this.isModal = false;				// sarà TRUE se il Popup viene aperto in modalità Modale
5794	this.abortOnClickOut = true;		// se impostato su TRUE allora cliccando fuori dal Popup questo si chiuderà
5795	this.popupShadowWidth = 8;			// dimensione dell'ombra (sfasamento rispetto alla posizione del Popup)
5796	this.popupShadowValue = 25;			// opacità  del Div che disegna l'ombra
5797	
5798	/*	####    DETTAGLI SULL'ARGOMENTO [Src] :    ####
5799		L'argomento può essere un percorso URL o un testo HTML. La classe [HtmlPlus_Popup] interpreta l'argomento come HTML se vi trova il
5800		carattere "<", altrimenti sarà interpretato come percorso URL.
5801		Se viene interpetato come percorso URL la classe genererà un IFRAME nel popup, con l'argomento SRC dell'IFRAME settato con l'Src indicato.
5802		La pagina che viene aperta può ospitare 3 variabili JavaScript:
5803			window.Interface_HtmlPlus_Popup_OnLoad :
5804				(function) viene invocata dalla classe [HtmlPlus_Popup] alla fine del caricamento e generazione del popup. Gli argomenti sono:
5805					SendSerializedArgument :	è l'argomento SendArgument passato alla funzione HtmlPlus_Popup.Open, serializzato.
5806			window.Interface_HtmlPlus_Popup_OnSubmit
5807				(function) dev'essere invicata dalla pagina dell'IFRAME per chiudere il Popup. Gli argomenti sono:
5808					ReturnSerializedValue :		dev'essere riempito con l'argomento che si vuole restituire, serializzato;
5809					IsAbort :					dev'esssere settato a TRUE se è stato invocato un "Annulla", altrimenti FALSE.
5810			window.Interface_HtmlPlus_Popup_This
5811				(object) punta all'istanza HtmlPlus_Popup corrente. E' utile per invocare metodi come [SetTitle], per cambiare il titolo del popup,
5812				ma è anche utilizzabile per invocare il metodo [Close] al posto di [Interface_HtmlPlus_Popup_OnSubmit].
5813	*/
5814	
5815	/*	ATTENZIONE:
5816		- 18/02/2010 -  è stata fatta una modifica alla classe che aggiunge una potenzialità: disegnare il popup nel frame TOP. Questa modifica
5817		ha un baco sul pulsante ABORT:
5818		Abbiamo il frame TOP che contiene un IFRAME chiamato CHILD. Abbiamo già generato e chiuso un Popup da Top con ID "MioPopup". Creiamo un altro
5819		Popup da Child con lo stesso valore ID. A questo punto cliccando su Abort verrà scatenato l'evento Close del Popup in Top, invece del Popup
5820		che si trova in Child. Questo perchè viene usata la funzione [FindArrayItem] che cerca prima nel frame Top, poi in Frames.
5821		Per risolvere questo problema si dovrebbe appoggiare il riferimento a THIS in una qualche variabile, e l'eventi ONCLICK di ABORT dovrebbe
5822		utilizzare quel riferimento per referenziarvi.
5823		- 02/03/2010 -  il problema dovrebbe essere stato risolto.
5824	*/
5825	
5826	if (!window.HtmlPlus_PopupColl) window.HtmlPlus_PopupColl = new Array();
5827	window.HtmlPlus_PopupColl[this.id] = this;
5828	
5829	this._initialize = function(){
5830		this._uid = null;
5831		this._container2 = null;
5832		this._divContenuto2 = null;
5833		this._divOmbra = null;
5834		this._divModal = null;
5835		this._modal_resizeTmr = null;
5836		this._popupTmr = null;
5837		this._clipAppearance = null;
5838		
5839		this._isResponseAvailable = false;
5840		this._isResponseAbort = null;
5841		this._returnValue = null;
5842		this._isOpen = false;
5843		this._generaPopup_iFrame_onLoad_EseguitoPrimo = false;
5844		this._generaPopup_iFrame_onLoad_EseguitoInOpen = false;
5845		
5846		this.popupWidth = toNumber(this.popupWidth, null, false);
5847		this.popupHeight = toNumber(this.popupHeight, null, false);
5848		this.contentWidth = toNumber(this.contentWidth, null, false);
5849		this.contentHeight = toNumber(this.contentHeight, null, false);
5850	}
5851	
5852	this._generaPopup = function(SendArgument) {
5853		var strJS;
5854		
5855		//Determino il valore ID UNIVOCO dell'oggetto, verrà usato come prefisso per gli ID degli oggetti HTML.
5856		this._uid = this.id + '__' + GetUID();
5857		
5858		// Inizializzazione del DIV contenitore del Popup
5859		this.container = document.createElement('DIV');
5860		this.container.id = this._uid;
5861		this.container.className = 'Def_Popup_Container' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_Container' : '');
5862		this.container.style.zIndex = 10010;
5863		//if (this.popupWidth) this.container.style.width = this.popupWidth.toString() + 'px';
5864		//if (this.popupHeight) this.container.style.height = this.popupHeight.toString() + 'px';
5865		this.container.style.display = 'none';
5866		this._generaPopup_getDocument().body.appendChild(this.container);
5867		this.container.ObjPopup = this;
5868		
5869		this._divOmbra = document.createElement('DIV');
5870		//if (this.popupWidth) this._divOmbra.style.width = this.popupWidth.toString() + 'px';
5871		//if (this.popupHeight) this._divOmbra.style.height = this.popupHeight.toString() + 'px';
5872		this._divOmbra.className = 'Def_Popup_Container_Shadow' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_Container_Shadow' : '');
5873		this.container.appendChild(this._divOmbra);
5874		//SetProperty(this._divOmbra, 'opacity', this.popupShadowValue);
5875		
5876		this._container2 = document.createElement('DIV');
5877		if (this.popupWidth) this._container2.style.width = this.popupWidth.toString() + 'px';
5878		if (this.popupHeight) this._container2.style.height = this.popupHeight.toString() + 'px';
5879		this._container2.className = 'Def_Popup_Container2' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_Container2' : '');
5880		//this.container.appendChild(this._container2);
5881		this._divOmbra.appendChild(this._container2);
5882		
5883		this._divModal = document.createElement('DIV');
5884		this._divModal.style.position = 'absolute';
5885		this._divModal.style.left = '0px';
5886		this._divModal.style.top = '0px';
5887		this._divModal.style.zIndex = 10000;
5888		//alert(window.document.body.offsetWidth);
5889		//this._divModal.style.height = window.dialogHeight;
5890		this._divModal.className = 'Def_Popup_Container_BgModal' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_Container_BgModal' : '');
5891		this._divModal.style.display = 'none';
5892		this._generaPopup_getDocument().body.appendChild(this._divModal);
5893		SetProperty(this._divModal, 'opacity', 25);
5894		strJS = 'addEvent(window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\']._generaPopup_getDocument(), \'resize\', function(ev) {' + 
5895						'var eventObj = new STDEvent(ev); var obj1;' +
5896						'eval(\'' + CStrJS('obj1 = FindArrayItem(\'HtmlPlus_PopupColl\', \'' + CStrXML(CStrJS(this.id)) + '\');') + '\');' + 
5897						'obj1._generaPopup_divModal_window_onResize();' +
5898					'}' +
5899				');';
5900		if (this.abortOnClickOut) {
5901			strJS += 'addEvent(window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\']._divModal, \'click\', function(ev) {' + 
5902							'var eventObj = new STDEvent(ev); var obj1;' +
5903							'eval(\'' + CStrJS('obj1 = FindArrayItem(\'HtmlPlus_PopupColl\', \'' + CStrXML(CStrJS(this.id)) + '\');') + '\');' + 
5904							'obj1.Close(null, true);' +
5905						'}' +
5906					');';
5907			strJS += 'addEvent(window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\']._generaPopup_getDocument(), \'keypress\', function(ev) {' + 
5908							'var eventObj = new STDEvent(ev); var obj1;' +
5909							'if (eventObj.keyCode == 27 && eventObj.altKey == false && eventObj.ctrlKey == false && eventObj.shiftKey == false) {' +
5910								'eval(\'' + CStrJS('obj1 = FindArrayItem(\'HtmlPlus_PopupColl\', \'' + CStrXML(CStrJS(this.id)) + '\');') + '\');' + 
5911								'obj1.Close(null, true);' +
5912							'}' +
5913						'}' +
5914					');';
5915		}
5916		eval(strJS);
5917		
5918		this._container2.innerHTML = '' +
5919				'<div class="Def_Popup_Container3' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_Container3' : '') + '">' +
5920					'<div class="Def_Popup_TitleBar' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_TitleBar' : '') + '">' +
5921						'<table class="Def_Popup_TitleBar_Table' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_TitleBar_Table' : '') + '" cellpadding="0" cellspacing="0" border="0" width="100%">' +
5922							'<tr>' +
5923								'<td class="Def_Popup_TitleBar_Title' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_TitleBar_Title' : '') + '" id="' + CStrXML(this.container.id) + '_TdTitle">' + CStrHTML(this.lblTitle) + '</td>' +
5924								'<td class="Def_Popup_TitleBar_CmdAbort' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_TitleBar_CmdAbort' : '') + '">' +
5925									'<a href="javascript:void(0);" onclick="findParentObj(this, /DIV/i, \'className\', /^Def_Popup_Container( .+)?$/).ObjPopup.Close(null, true);" title="Close">' +
5926										CStrHTML(this.lblClose) +
5927									'</a>' +
5928								'</td>' +
5929							'</tr>' +
5930						'</table>' +
5931					'</div>' +
5932					'<div class="Def_Popup_Content' + (this.cssPrefix ? ' ' + this.cssPrefix + '_Popup_Content' : '') + '" id="' + HTMLEncode(this._uid) + '_Popup_Content"></div>' +
5933				'</div>';
5934		
5935		this.container_content = document.createElement((this.src.substr(0, 1) == '<') ? 'DIV' : 'IFRAME');
5936		this._divContenuto2 = findObj(this._uid + '_Popup_Content', this._generaPopup_getDocument());
5937		this._divContenuto2.appendChild(this.container_content);
5938		// Creazione [contenuto] del popup
5939		switch (this.container_content.tagName) {
5940			case 'DIV':
5941				this.container_content.innerHTML = this.src;
5942				this._generaPopup_iFrame_onLoad(SerializeValue(SendArgument));
5943				break;
5944			case 'IFRAME':
5945				this.container_content.src = this.src;
5946				SetProperty(this.container_content, 'frameborder', '0');
5947				SetProperty(this.container_content, 'marginwidth', '0');
5948				SetProperty(this.container_content, 'marginheight', '0');
5949				SetProperty(this.container_content, 'scrolling', 'no');
5950				
5951				this._generaPopup_iFrame_onLoad_EseguitoPrimo = false;
5952				strJS = 'addEvent(this.container_content, \'load\', function(ev) {' + 
5953								'var eventObj = new STDEvent(ev);' +
5954								'eval(\'' +
5955										CStrJS('window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\']._generaPopup_iFrame_onLoad(\'' + CStrJS(SerializeValue(SendArgument)) + '\');') +
5956									'\');' + 
5957							'}' +
5958						');';
5959				eval(strJS);
5960				break;
5961		}
5962		if (this.contentWidth) this.container_content.style.width = this.contentWidth.toString() + 'px';
5963		if (this.contentHeight) this.container_content.style.height = this.contentHeight.toString() + 'px';
5964		this.container_content.style.overflow = 'hidden';
5965	}
5966	this._generaPopup_getDocument = function() {
5967		var fReturn = window;
5968		if (this.showInTopFrame == true) {
5969			while (GetDocInfo(fReturn.document, 'IsTopFrame') == false) {
5970				fReturn = fReturn.parent.window;
5971			}
5972		}
5973		return fReturn.document;
5974	}
5975	this._posizionaPopup = function(Left, Top) {
5976		this.container.style.left = Left.toString() + 'px';
5977		this.container.style.top = Top.toString() + 'px';
5978		//this._divOmbra.style.left = (Left + this.popupShadowWidth).toString() + 'px';
5979		//this._divOmbra.style.top = (Top + this.popupShadowWidth).toString() + 'px';
5980	}
5981	
5982	this._generaPopup_iFrame_onLoad = function(SendSerializedArgument) {
5983		if (this.container_content.tagName == 'IFRAME') {
5984			this.container_content.contentWindow.Interface_HtmlPlus_Popup_This = this;
5985			eval('window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\'].container_content.contentWindow.Interface_HtmlPlus_Popup_OnSubmit = function (ReturnSerializedValue, IsAbort) {' +
5986						'window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\'].Close(DeserializeValue(ReturnSerializedValue), IsAbort);' +
5987					'}');
5988			if (!this._generaPopup_iFrame_onLoad_EseguitoInOpen) this.OnLoad(this);
5989			if (!this._generaPopup_iFrame_onLoad_EseguitoPrimo) {
5990				this.container_content.contentWindow.Interface_HtmlPlus_Popup_OnLoad(SendSerializedArgument);
5991				this._generaPopup_iFrame_onLoad_EseguitoPrimo = true;
5992			}
5993		} else {
5994			if (!this._generaPopup_iFrame_onLoad_EseguitoInOpen) this.OnLoad(this);
5995		}
5996		if (!this._generaPopup_iFrame_onLoad_EseguitoInOpen) this.OnOpen(this);
5997		this._generaPopup_iFrame_onLoad_EseguitoInOpen = true;
5998	}
5999	this._generaPopup_divModal_ridimensiona = function() {
6000		this._divModal.style.width = Math.max(this._generaPopup_getDocument().body.scrollWidth, this._generaPopup_getDocument().body.clientWidth).toString() + 'px';
6001		this._divModal.style.height = Math.max(this._generaPopup_getDocument().body.scrollHeight, this._generaPopup_getDocument().body.clientHeight).toString() + 'px';
6002	}
6003	this._generaPopup_divModal_window_onResize = function(ev) {
6004		if (this.isModal && this.IsOpen()) {
6005			if (this._divModal.style.display != 'none') this._divModal.style.display = 'none';
6006			if (this._modal_resizeTmr) clearTimeout(this._modal_resizeTmr);
6007			this._modal_resizeTmr = setTimeout('window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\']._generaPopup_divModal_window_onResize_timer();', 300);
6008		}
6009	}
6010	this._generaPopup_divModal_window_onResize_timer = function() {
6011		if (this.isModal && this._divModal.style.display == 'none') {
6012			this._generaPopup_divModal_ridimensiona();
6013			this._divModal.style.display = 'block';
6014		}
6015	}
6016	
6017	
6018	/* ####  PROCEDURE PUBLIC  #### */
6019	this.Open = function(SendArgument, Left, Top, IsModal, Timer, AppearanceType, AppearanceTime) {
6020		//Argomenti:
6021		//	SendArgument :		l'argomento che si vuole passare all'IFRAME del popup, attraverso la procedura "Interface_HtmlPlus_Popup_OnLoad".
6022		//	Left, Top :			la posizione del Popup.
6023		//	IsModal :			se True, la finestra sarà bloccata finchè non si chiude il Popup.
6024		//	Timer :				se indicato, numero di secondi dopo i quali il popup si chiuderà automaticamente, invocando il metodo Close con IsAbort=true.
6025		//	AppearanceType :	modalità con cui il popup apparirà; può essere: 0=none(default); 1=zoom; 2=fromLeft; 3=fromTop; <objClip>=verrà usato tale oggetto per gestire l'apparizione del Popup.
6026		//	AppearanceTime :	durata, in secondi, di apparizione del popup (se modalità è diverso da 0); default = 0.6 sec.
6027		var appearanceType, appearanceTime;
6028		var posX, posY;
6029		if (this.IsOpen()) {
6030			return false;
6031		} else {
6032			//Setting valori
6033			this._isResponseAvailable = false;
6034			this._isResponseAbort = null;
6035			this._returnValue = null;
6036			this._isOpen = true;
6037			this.isModal = ((IsModal) ? true : false);
6038			this._lastSendArgument = SendArgument;
6039			if (this._popupTmr) clearTimeout(this._popupTmr);
6040			//Determino [posX] e [posY]
6041			posX = Left;
6042			switch (ValueType(posX)) {
6043				case 'string':
6044					//Il valore [posX] è espresso in PERCENTUALE. Ciò significa che posizionerò il popup in base alla dimensione della finestra.
6045					if (posX.charAt(posX.length - 1) != '%') posX = '50%';
6046					posX = (Math.min(this._generaPopup_getDocument().body.scrollWidth, this._generaPopup_getDocument().body.clientWidth) - this.popupWidth) * posX.substr(0, posX.length - 1) / 100 + this._generaPopup_getDocument().body.scrollLeft;
6047					break;
6048				case 'number':
6049					if (posX > 0) {		//Posizionamento da sinistra
6050						posX = posX + this._generaPopup_getDocument().body.scrollLeft;
6051					} else {			//Posizionamento da destra
6052						posX = Math.min(this._generaPopup_getDocument().body.scrollWidth, this._generaPopup_getDocument().body.clientWidth) - this.popupWidth + posX + this._generaPopup_getDocument().body.scrollLeft;
6053					}
6054					break;
6055				default:
6056					posX = 10;
6057			}
6058			if (posX < 10) posX = 10;
6059			posY = Top;
6060			switch (ValueType(posY)) {
6061				case 'string':
6062					//Il valore [posY] è espresso in PERCENTUALE. Ciò significa che posizionerò il popup in base alla dimensione della finestra.
6063					if (posY.charAt(posY.length - 1) != '%') posY = '50%';
6064					posY = (Math.min(this._generaPopup_getDocument().body.scrollHeight, this._generaPopup_getDocument().body.clientHeight) - this.popupHeight) * posY.substr(0, posY.length - 1) / 100 + this._generaPopup_getDocument().body.scrollTop;
6065					break;
6066				case 'number':
6067					if (posY > 0) {		//Posizionamento dall'alto
6068						posY = posY + this._generaPopup_getDocument().body.scrollTop;
6069					} else {			//Posizionamento dal basso
6070						posY = Math.min(this._generaPopup_getDocument().body.scrollHeight, this._generaPopup_getDocument().body.clientHeight) - this.popupHeight + posY + this._generaPopup_getDocument().body.scrollTop;
6071					}
6072					break;
6073				default:
6074					posY = 10;
6075			}
6076			if (posY < 10) posY = 10;
6077			
6078			//Generazione oggetti HTML e passaggio argomento [SendArgument]
6079			this._generaPopup_iFrame_onLoad_EseguitoInOpen = false;
6080			if (!this.container) {
6081				this._generaPopup(SendArgument);
6082				this._posizionaPopup(posX, posY);
6083			} else {
6084				if (!IsUndefined(SendArgument) && this.container_content.tagName == 'IFRAME') {
6085					this.container_content.contentWindow.Interface_HtmlPlus_Popup_OnLoad(SerializeValue(SendArgument));
6086				}
6087				this._posizionaPopup(posX, posY);
6088				this.OnOpen(this);
6089			}
6090			if (this.isModal) {
6091				this._generaPopup_divModal_ridimensiona();
6092				this._divModal.style.display = 'block';
6093			}
6094			
6095			//Gestione della modalità di APPARENZA del POPUP.
6096			if (AppearanceType.objectType == 'HtmlPlus_ClipMaker') {
6097				this._clipAppearance = AppearanceType;
6098			} else {
6099				appearanceTime = ((AppearanceTime) ? AppearanceTime : 0.6);
6100				switch (AppearanceType) {
6101					case 1: case 2: case 3:
6102						this._clipAppearance = new HtmlPlus_ClipMaker('Popup_' + this._uid + '_appearance', appearanceTime);
6103						appearanceType = AppearanceType;
6104						break;
6105					default:
6106						this._clipAppearance = null;
6107						appearanceType = 0;
6108				}
6109				switch (appearanceType) {
6110					case 0:
6111						break;
6112					case 1:
6113						this._clipAppearance.AppendMotion(this.container, 'opacity', '', 0, 100, 0, 100, 'sin');
6114						/*
6115						this._clipAppearance.AppendMotion(this._divOmbra, 'opacity', '', 0, 100, 0, this.popupShadowValue, 'sin');
6116						this._clipAppearance.AppendMotion(this._divOmbra, 'zoom', '', 0, 100, 0.6, 1, 'sin');
6117						*/
6118						break;
6119					case 2:
6120						this._clipAppearance.AppendMotion(this.container, 'left', 'px', 0, 100, -this.popupWidth - this.popupShadowWidth, posX, 'sin');
6121						//this._clipAppearance.AppendMotion(this._divOmbra, 'left', 'px', 0, 100, -this.popupWidth, posX + this.popupS
6121hadowWidth, 'sin');
6122						break;
6123					case 3:
6124						this._clipAppearance.AppendMotion(this.container, 'top', 'px', 0, 100, -this.popupHeight - this.popupShadowWidth, posY, 'sin');
6125						//this._clipAppearance.AppendMotion(this._divOmbra, 'top', 'px', 0, 100, -this.popupHeight, posY + this.popupShadowWidth, 'sin');
6126						break;
6127					default:
6128				}
6129			}
6130			if (this._clipAppearance) {
6131				this._clipAppearance.AppendEvent(1, '' +
6132						'var obj1 = window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\'];' +
6133						'obj1.container.style.display = \'block\';' +
6134						'/*obj1._divOmbra.style.display = \'block\';*/' +
6135						'');
6136				if (Timer > 0) this._clipAppearance.AppendEvent(100, 'window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\']._popupTmr = setTimeout(\'' + CStrJS('window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\'].Close(null, true);') + '\', ' + (Timer * 1000) + ');');
6137				this._clipAppearance.Play();
6138			} else {
6139				this.container.style.display = 'block';
6140				//this._divOmbra.style.display = 'block';
6141				if (Timer > 0) this._popupTmr = setTimeout('window.HtmlPlus_PopupColl[\'' + CStrJS(this.id) + '\'].Close(null, true);', Timer * 1000);
6142			}
6143			return true;
6144		}
6145	}	
6146	this.Close = function(ReturnValue, IsAbort) {
6147		//Chiude il Popup, ed imposta sia il [Valore] da restituire sia lo stato [IsAbort].
6148		if (this.IsOpen()) {
6149			this.container.style.display = 'none';
6150			//this._divOmbra.style.display = 'none';
6151			this._divModal.style.display = 'none';
6152			if (this._popupTmr) clearTimeout(this._popupTmr);
6153			//document.body.removeChild(this.container);
6154			this._isOpen = false;
6155			this._isResponseAvailable = true;
6156			this._isResponseAbort = IsAbort;
6157			this._returnValue = ReturnValue;
6158			
6159			this.OnClose(this, ReturnValue, IsAbort);
6160			return true;
6161		} else {
6162			return false;
6163		}
6164	}
6165	this.SetTitle = function(htmlValue) {
6166		findObj(this.container.id + '_TdTitle', this._generaPopup_getDocument()).innerHTML = htmlValue;
6167	}
6168	this.LastSendArgument = function() {
6169		return this._lastSendArgument;
6170	}
6171
6172	this.IsOpen = function() {
6173		return this._isOpen;
6174	}
6175	this.IsResponseAvailable = function() {
6176		return this._isResponseAvailable;
6177	}
6178	this.IsResponseAbort = function() {
6179		return ((this._isResponseAvailable) ? this._isResponseAbort : null);
6180	}
6181	this.ReturnValue = function() {
6182		return ((this._isResponseAvailable) ? this._returnValue : null);
6183	}
6184	
6185	/* Definizione eventi */
6186	this.OnLoad = function (Popup) {return void(0);}							//Invocata quando il Popup è stato generato o riaperto
6187	this.OnOpen = function (Popup) {return void(0);}							//Invocata quando il metodo Open viene eseguito con successo
6188	this.OnClose = function (Popup, ReturnValue, IsAbort) {return void(0);}		//Invocata quando il Popup viene chiuso
6189	
6190	this._initialize();
6191	return this;
6192}
6193
6194
6195
6196
6197
6198
6199
6200function OggettiRif_DlgFind(OggettoRifCode, SqlFilter, CFG, optCssStyle) {
6201	var fReturn, parametri;
6202	var idObj = 'ObjRifPopUp' + ';' + OggettoRifCode + ';' + SqlFilter ;
6203	var TxtSearchValue = '';
6204	var cssStyle = (optCssStyle)? optCssStyle : '';
6205	parametri = '?ObjRifCode=' + OggettoRifCode;
6206	parametri += '&SqlFilter=' + ((SqlFilter)? CStrUrlParam(SqlFilter) : '');
6207	if (window.HtmlPlus_PopupColl) {
6208		if (window.HtmlPlus_PopupColl[idObj]) fReturn = HtmlPlus_PopupColl[idObj];
6209	}
6210	if (!fReturn) {
6211		fReturn = new HtmlPlus_Popup(idObj, 'Ricerca [Oggetto rif.]', R + 'WebAdmin/DevTools_OggettiRif_DlgFind.asp' + parametri, 420, 318, 420, 300, cssStyle);
6212	}
6213	if (CFG['fncOnClose']) {
6214		if (CFG['fncOnOpen']) eval('fReturn.OnOpen = function() {' + CFG['fncOnOpen'] + '(DeserializeValue(\'' + CStrJS(SerializeValue(CFG)) + '\'));}');
6215		fReturn.OnClose = CFG['fncOnClose'];
6216		fReturn.Open(TxtSearchValue, '50%', '30%', true, 0, 0, 0);
6217	}
6218	return fReturn;
6219}
6220
6221
6222//###################################
6223//####  Funzioni di MACRO MEDIA  ####
6224//###################################
6225
6226function MM_displayStatusMsg(msgStr)  { //v3.0
6227	status=msgStr; document.MM_returnValue = true;
6228}
6229
6230function MM_findObj(n, d) { //v3.0
6231  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
6232    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
6233  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
6234  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); return x;
6235}
6236function MM_swapImage() { //v3.0
6237  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
6238   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
6239}
6240function MM_swapImgRestore() { //v3.0
6241  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
6242}
6243
6244function MM_preloadImages() { //v3.0
6245 var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
6246   var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
6247   if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
6248}
6249
6250
6251function MM_reloadPage(init) {  //reloads the window if Nav4 resized
6252  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
6253    document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
6254  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
6255}
6256//MM_reloadPage(true);
6257
6258
6259
6260//##################################
6261//####	SoundPlayerClass		####
6262//##################################
6263
6264function SoundPlayerClass(idObject) {
6265	this.id = idObject;
6266	this.objectType = 'SoundPlayer';
6267	this.PlayList = new Array();
6268	this.ObjCon = null;
6269	
6270	this.preLoad = function () {
6271		var i, objHtml, str1;
6272		if (!ver4) return;
6273		if (NS) {
6274			objHtml = new Layer(0,window);
6275		} else {
6276			document.body.insertAdjacentHTML('BeforeEnd', '<DIV ID="SoundPlayer_Div' + this.id + '" STYLE="position:absolute;"></DIV>');
6277			objHtml = findObj('SoundPlayer_Div' + this.id);
6278		}
6279		str1 = '';
6280		for (i in this.PlayList) {
6281			str1 += '<EMBED SRC="' + this.PlayList[i] + '" AUTOSTART="FALSE" HIDDEN="TRUE"></EMBED>';
6282		}
6283		if (IE) {
6284			objHtml.innerHTML = str1;
6285		} else {
6286			objHtml.document.open();
6287			objHtml.document.write(str1);
6288			objHtml.document.close();
6289		}
6290		if (IE) {
6291			this.ObjCon = document.createElement('<bgsound id="SoundPlayer_Tag' + this.id + '" volume="0" balance="0"></bgsound>');
6292			findObj('body').appendChild(this.ObjCon);
6293		} else {
6294			this.ObjCon = objHtml;
6295		}
6296		this.ObjCon.makeAction = function (index, play, fileName, vol, leftRight) {
6297			//vol:			è il volume da applicare. Deve essere fra 0 (silenzio) a +100 (volume max).
6298			//leftRight:	è il bilanciamento. Da -100 (canale L) a +100 (canale R).
6299			if (IE) {
6300				//if (vol) this.volume = 10000 * (vol / 100 - 1);		//Conversione lineare
6301				if (vol==0) {
6302					this.volume = -10000;
6303				} else {
6304					if (vol) this.volume = Math.log(vol / 100) * 2167;
6305				}
6306				if (leftRight==0) {
6307					this.balance = 0;
6308				} else {
6309					/*if (leftRight) {
6310						if (leftRight > 0) {
6311							this.balance = -Math.log(leftRight / 100) * 216;//* 2167;
6312						} else {
6313							this.balance = Math.log(-leftRight / 100) * 216; //* 2167;
6314						}
6315					}*/
6316					if (leftRight) this.balance = 10000 * (leftRight / 100);
6317				}
6318				this.src = play? fileName : '';
6319			} else {
6320				if (vol) eval('this.document.embeds[index].volume = ' + vol);	//Volume va da 0 a 100
6321				eval('this.document.embeds[index].' + (play? 'play()':'stop()'));
6322			}
6323		}
6324	}
6325	this.Play = function (index, volume, balance) {
6326		if (!this.ObjCon) this.preLoad();
6327		if (this.ObjCon) this.ObjCon.makeAction(index, true, this.PlayList[index], volume, balance);
6328	}
6329	this.Stop = function (index) {
6330		if (!this.ObjCon) this.preLoad();
6331		if (this.ObjCon) this.ObjCon.makeAction(index, false);
6332	}
6333}
6334
6335
6336
6337//##################################
6338//####	UrlParserClass			####
6339//##################################
6340
6341function UrlParserClass(UrlString) {
6342	this.objectType = 'UrlParserClass';
6343	this.Url = Trim(UrlString.toString());
6344	this.z_existsProtocol = null;
6345	this.z_protocol = null;
6346	this.z_domain = null;
6347	this.z_fullRequest = null;
6348	this.z_fullPath = null;
6349	this.z_path = null;
6350	this.z_fileName = null;
6351	this.z_parametersString = null;
6352	this.z_parameters = null;
6353	
6354	this.ExistsProtocol = function() {
6355		if (this.z_existsProtocol === null) this.z_existsProtocol = this.RecalcExistsProtocol();
6356		return this.z_existsProtocol;
6357	}
6358	this.GetPartialUrl = function(WithProtocol, WithDomain, WithPath, WithFileName, WithParametersString) {
6359		//ATTENZIONE: al momento funziona solo per protocolli HTTP e HTTPS
6360		var fReturn = '';
6361		switch (this.GetProtocol()) {
6362			case 'http':
6363			case 'https':
6364				if (WithProtocol) {
6365					fReturn += this.GetProtocol();
6366					if (WithDomain || WithPath || WithFileName) fReturn += '://';
6367				}
6368				if (WithDomain) {
6369					fReturn += this.GetDomain();
6370					if (WithPath || WithFileName) fReturn += '/';
6371				}
6372				if (WithPath) {
6373					fReturn += this.GetPath();
6374					if (WithFileName || WithParametersString) fReturn += '/';
6375				}
6376				if (WithFileName) fReturn += this.GetFileName();
6377				if (WithParametersString) {
6378					if (WithProtocol || WithDomain || WithPath || WithFileName) fReturn += '?';
6379					fReturn += this.GetParametersString();
6380				}
6381				break;
6382			case 'ftp':
6383				break;
6384			case 'javascript':
6385				break;
6386			case 'mailto':
6387				break;
6388		}
6389		return fReturn;
6390	}
6391	this.GetProtocol = function() {
6392		if (!this.z_protocol) this.z_protocol = this.RecalcProtocol();
6393		return this.z_protocol;
6394	}
6395	this.GetDomain = function() {
6396		if (!this.z_domain) this.z_domain = this.RecalcDomain();
6397		return this.z_domain;
6398	}
6399	this.GetFullRequest = function() {
6400		if (!this.z_fullRequest) this.z_fullRequest = this.RecalcFullRequest();
6401		return this.z_fullRequest;
6402	}
6403	this.GetFullPath = function() {
6404		if (!this.z_fullPath) this.z_fullPath = this.RecalcFullPath();
6405		return this.z_fullPath;
6406	}
6407	this.GetPath = function() {
6408		if (!this.z_path) this.z_path = this.RecalcPath();
6409		return this.z_path;
6410	}
6411	this.GetFileName = function() {
6412		if (!this.z_fileName) this.z_fileName = this.RecalcFileName();
6413		return this.z_fileName;
6414	}
6415	this.GetParametersString = function() {
6416		if (!this.z_parametersString) this.z_parametersString = this.RecalcParametersString();
6417		return this.z_parametersString;
6418	}
6419	this.GetParameters = function() {
6420		if (!this.z_parameters) this.z_parameters = this.RecalcParameters();
6421		return this.z_parameters;
6422	}
6423	this.GetParameter = function(Name, oIgnoreCase) {
6424		//Restituisce il valore del parametro richiesto. <null> se il parametro non è presente nell'array. Argomenti:
6425		//	Name :			(stringa) il nome del parametro da cercare;
6426		//	oIgnoreCase :	(boolean, opzionale, def.=False) se TRUE la ricerca avverrà in modalità IgnoreCase.
6427		var str1, str2, fReturn;
6428		if (!this.z_parameters) this.z_parameters = this.RecalcParameters();
6429		fReturn = null;
6430		if (oIgnoreCase) {
6431			str2 = Name.toLowerCase();
6432			for (str1 in this.z_parameters) {
6433				if (str1.toLowerCase() == str2) { fReturn = this.z_parameters[str1]; break; }
6434			}
6435		} else {
6436			for (str1 in this.z_parameters) {
6437				if (str1 == str2) { fReturn = this.z_parameters[str1]; break; }
6438			}
6439		}
6440		return fReturn;
6441	}
6442	
6443	this.RecalcExistsProtocol = function() {
6444		//Restituisce il protocollo (default: il protocollo usato nella pagina corrente)
6445		var cont1 = this.Url.indexOf(':');
6446		return ((cont1 == -1 || cont1 > 12) ? false : true);
6447	}
6448	this.RecalcProtocol = function() {
6449		//Restituisce il protocollo (default: il protocollo usato nella pagina corrente)
6450		if (this.ExistsProtocol()) {
6451			return this.Url.substr(0, this.Url.indexOf(':')).toLowerCase();
6452		} else {
6453			return window.location.protocol;
6454		}
6455	}
6456	this.RecalcDomain = function() {
6457		//Restituisce la parte [dominio], comprensivo di porta ip se diversa dalla porta di default del protocollo
6458		var cont1, cont2, fReturn;
6459		switch (this.GetProtocol()) {
6460			case 'http':
6461			case 'https':
6462			case 'ftp':
6463				fReturn = this.Url.substr(this.Url.indexOf(':')+1);
6464				if (fReturn.substr(0, 2) == '//') {
6465					fReturn = fReturn.substr(2);
6466					cont1 = fReturn.search(/[\/?#]/g);
6467					if (cont1 != -1) fReturn = fReturn.substr(0, cont1);
6468					//Verifico la presenza ed il valore della porta. Se è il valore di default lo tolgo dal valore da restituire
6469					cont1 = fReturn.indexOf(':');
6470					if (cont1 != -1) {
6471						cont2 = fReturn.substr(cont1 + 1);
6472						if (cont2 == DefaultProtocolIpPort(this.GetProtocol())) fReturn = fReturn.substr(0, cont1);
6473					}
6474				} else {
6475					fReturn = Domini_Nomi_CurrentName();
6476				}
6477				return fReturn;
6478				break;
6479			case 'javascript':
6480				//Non gestito. Usare le altre funzioni GetXxxx
6481				break;
6482			case 'mailto':
6483				//Restituisce il dominio del primo indirizzo valido
6484				fReturn = this.GetFullPath();
6485				if (fReturn) return fReturn.substr(fReturn.indexOf('@') + 1);
6486				break;
6487		}
6488		return null;
6489	}
6490	this.RecalcFullRequest = function() {
6491		//Restituisce la richiesta intera, senza dominio, porta ip e protocollo.
6492		var str1, str2, cont1, cont2, re, arr;
6493		var fReturn = this.Url.substr(this.Url.indexOf(':')+1);
6494		switch (this.GetProtocol()) {
6495			case 'http':
6496			case 'https':
6497			case 'ftp':
6498				if (fReturn.substr(0, 2) == '//') {
6499					fReturn = fReturn.substr(2);
6500					cont1 = fReturn.search(/[\/?#]/g);
6501					if (cont1 != -1) {
6502						if (fReturn.substr(cont1, 1) == '/') cont1 ++;
6503						return fReturn.substr(cont1);
6504					} else {
6505						fReturn = '';
6506					}
6507					return decodeURI(fReturn);
6508				} else {
6509					//Attenzione: il percorso deve essere assoluto
6510				}
6511				break;
6512			case 'javascript':
6513				//Restituisce l'intera invocazione alla procedura. (mi aspetto di trovare [NomeObj.]NomeFunzione([parametri]);)
6514				//Attenzione: la classe considera solo la prima chiamata a funzione trovata.
6515				fReturn = LTrim(fReturn);
6516				str1 = new String(fReturn);
6517				str1 = str1.replace(/\\\\/g, '##');		//Sostituisco la doppia barra con doppio #
6518				//Sostituisco le stringhe con dei #, uno per carattere di stringa.
6519				cont1 = str1.search(/['"]/g);
6520				while (cont1 > -1) {
6521					str2 = str1.substr(cont1, 1);
6522					//Cerco la chiusura di stringa, escludendo quelle situazioni in cui il sepStringa è preceduro da uno Escape (\)
6523					for (cont2 = cont1+1; cont2 < str1.length; cont2++) {
6524						if (str1.substr(cont2, 1) == str2 && str1.substr(cont2-1, 1) != '\\') break;
6525					}
6526					str1 = str1.substr(0, cont1) + StringRepeater('#', cont2 - cont1 + 1) + str1.substr(cont2 + 1);
6527					cont1 = str1.search(/['"]/g);
6528				}
6529				//Ora cerco la fine chiamata funzione, cercando la prima ParentesiChiusa seguita da PuntoVirgola o FineStringa
6530				cont1 = str1.search(/\)\s*($|;)/g);
6531				if (cont1 > -1) {
6532					return fReturn.substr(0, cont1 + 1) + ';';
6533				}
6534				break;
6535			case 'mailto':
6536				//Restituisce il primo indirizzo valido
6537				re = new RegExp('[^\\s,;]+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)');
6538				arr = re.exec(fReturn);
6539				if (arr.length) return arr[0];
6540				break;
6541		}
6542		return null;
6543	}
6544	this.RecalcFullPath = function() {
6545		//Restituisce il nome del file completo di percorso (senza eventuali parametri del protocollo).
6546		//Attenzione: per protocollo http, http, ftp il percorso deve essere assoluto.
6547		var str1, str2, cont1, cont2, re, arr;
6548		var fReturn = this.Url.substr(this.Url.indexOf(':')+1);
6549		switch (this.GetProtocol()) {
6550			case 'http':
6551			case 'https':
6552			case 'ftp':
6553				fReturn = this.GetFullRequest();
6554				if (fReturn) {
6555					re = new RegExp('^[^?#]*');
6556					arr = re.exec(fReturn);
6557					if (arr && arr.length) fReturn = arr[0];
6558				}
6559				return fReturn;
6560				break;
6561			case 'javascript':
6562				//Restituisce l'intera invocazione alla procedura, senza i parametri e le relative parentesi tonde.
6563				//Es: "javascript:nomeObj.nomeFunzione(param1, param2);"    restituisce   "nomeObj.nomeFunzione"
6564				fReturn = this.GetFullRequest();
6565				if (fReturn) {
6566					str1 = new String(fReturn);
6567					str1 = str1.replace(/\\\\/g, '##');		//Sostituisco la doppia barra con doppio #
6568					//Sostituisco le stringhe con dei #, uno per carattere di stringa.
6569					cont1 = str1.search(/['"]/g);
6570					while (cont1 > -1) {
6571						str2 = str1.substr(cont1, 1);
6572						//Cerco la chiusura di stringa, escludendo quelle situazioni in cui il sepStringa è preceduro da uno Escape (\)
6573						for (cont2 = cont1+1; cont2 < str1.length; cont2++) {
6574							if (str1.substr(cont2, 1) == str2 && str1.substr(cont2-1, 1) != '\\') break;
6575						}
6576						str1 = str1.substr(0, cont1) + StringRepeater('#', cont2 - cont1 + 1) + str1.substr(cont2 + 1);
6577						cont1 = str1.search(/['"]/g);
6578					}
6579					//Ora tolgo l'ultima coppia di parentesi tonde, conteggiando quante se ne aprono e quante se ne chiudono.
6580					cont2 = 0;		//num parentesi aperte
6581					for (cont1=str1.length-2; cont1>0; cont1--) {
6582						switch (str1.substr(cont1, 1)) {
6583							case '(': cont2--; break;
6584							case ')': cont2++; break;
6585						}
6586						if (cont2==0) return fReturn.substr(0, cont1);
6587					}
6588				}
6589				break;
6590			case 'mailto':
6591				return this.GetFullRequest();
6592				break;
6593		}
6594		return null;
6595	}
6596	this.RecalcPath = function() {
6597		//Restituisce il percorso.
6598		//Attenzione: se l'ultima parte restituita da GetFullPath comprende un punto, questa sarà intesa come file.
6599		var cont1, cont2, fReturn;
6600		switch (this.GetProtocol()) {
6601			case 'http':
6602			case 'https':
6603			case 'ftp':
6604				fReturn = this.GetFullPath();
6605				if (fReturn) {
6606					cont1 = fReturn.lastIndexOf('/');
6607					cont2 = fReturn.lastIndexOf('.');
6608					if (cont1 == -1 && cont2 > -1) {
6609						fReturn = '';
6610					} else if (cont1 > -1 && (cont1 < cont2 || cont2 == -1)) {
6611						fReturn = fReturn.substr(0, cont1);
6612					}
6613				}
6614				return fReturn;
6615				break;
6616			case 'javascript':
6617				//Restituisce il nome dell'oggetto per cui è stata invocata la funzione.
6618				//Es: "javascript:nomeObj.nomeFunzione(param1, param2);"    restituisce   "nomeObj"
6619				fReturn = this.GetFullPath();
6620				if (fReturn) {
6621					cont1 = fReturn.lastIndexOf('.');
6622					if (cont1 == -1) {
6623						fReturn = '';
6624					} else {
6625						fReturn = fReturn.substr(0, cont1);
6626					}
6627					return fReturn;
6628				}
6629				break;
6630			case 'mailto':
6631				//Non gestito. Usare GetFullPath, GetDomain, GetFileName.
6632				break;
6633		}
6634		return null;
6635	}
6636	this.RecalcFileName = function() {
6637		//Restituisce il nome del file.
6638		//Attenzione: se l'ultima parte restituita da GetFullPath comprende un punto, questa sarà intesa come file.
6639		var cont1, fReturn;
6640		switch (this.GetProtocol()) {
6641			case 'http':
6642			case 'https':
6643			case 'ftp':
6644				fReturn = this.GetFullPath();
6645				if (fReturn) {
6646					fReturn = fReturn.substr(this.GetPath().length);
6647					if (fReturn.substr(0, 1) == '/') fReturn = fReturn.substr(1);
6648				}
6649				return fReturn;
6650				break;
6651			case 'javascript':
6652				//Restituisce il nome della procedura chiamata. Privo di eventuale riferimento ad oggetto.
6653				//Es: "javascript:nomeObj.nomeFunzione(param1, param2);"    restituisce   "nomeFunzione"
6654				fReturn = this.GetFullPath();
6655				if (fReturn) {
6656					cont1 = fReturn.lastIndexOf('.');
6657					if (cont1 > -1) fReturn = fReturn.substr(cont1 + 1);
6658					return fReturn;
6659				}
6660				break;
6661			case 'mailto':
6662				fReturn = this.GetFullPath();
6663				if (fReturn) return fReturn.substr(0, fReturn.indexOf('@'));
6664				break;
6665		}
6666		return null;
6667	}
6668	this.RecalcParametersString = function() {
6669		//Restituisce i parametri del percorso URL, sottoforma di stringa.
6670		var cont1, str1, fReturn;
6671		switch (this.GetProtocol()) {
6672			case 'http':
6673			case 'https':
6674				//Se il primo parametro è un bookmark, lascerò il carattere # come primo carattere della stringa.
6675				fReturn = this.GetFullRequest();
6676				if (fReturn) {
6677					cont1 = fReturn.search(/[?#]/g);
6678					if (cont1 == -1) {
6679						fReturn = '';
6680					} else {
6681						if (fReturn.substr(cont1, 1) == '?') cont1 ++;
6682						fReturn = fReturn.substr(cont1);
6683					}
6684				}
6685				return fReturn;
6686				break;
6687			case 'ftp':
6688				//Potrei restituire un vettore con Username e Password... lo svilupperò se ne avrò bisogno.
6689				break;
6690			case 'javascript':
6691				//Restituisce l'elenco dei parametri, senza le parentesi.
6692				//Es: "javascript:nomeObj.nomeFunzione(param1, param2);"    restituisce   "param1, param2"
6693				fReturn = this.GetFullRequest();
6694				if (fReturn) {
6695					str1 = this.GetFullPath();
6696					cont1 = fReturn.indexOf(str1) + str1.length;
6697					fReturn = fReturn.substr(cont1 + 1, fReturn.length - cont1 - 3);
6698					return fReturn;
6699				}
6700				break;
6701			case 'mailto':
6702				//Non gestito. Usare GetFullPath, GetDomain, GetFileName.
6703				break;
6704		}
6705		return null;
6706	}
6707	this.RecalcParameters = function() {
6708		//Restituisce i parametri del percorso URL, sottoforma di Array
6709		var cont1, cont2, cont3, cont4, str1, strOrg, vett1, vett2, fReturn;
6710		switch (this.GetProtocol()) {
6711			case 'http':
6712			case 'https':
6713				fReturn = this.GetParametersString();
6714				if (fReturn) {
6715					strOrg = new String(fReturn);
6716					cont1 = strOrg.lastIndexOf('#');
6717					if (cont1 > -1) {
6718						str1 = strOrg.substr(cont1 + 1);
6719						strOrg = strOrg.substr(0, cont1);
6720					} else {
6721						str1 = '';
6722					}
6723					fReturn = new Array();
6724					if (strOrg) {
6725						vett1 = strOrg.split(/(&amp;|&)/g);			//ATTENZIONE: QUESTO METODO PER SEPARARE I PARAMETRI non mi piace, perchè non mi permette di elaborare adeguatamente il testo URL. Preferirei usare un metodo di JScript per codificare il testo, ma non lo trovo.
6726						for (cont1=0; cont1<vett1.length; cont1++) {
6727							if (vett1[cont1]) {
6728								vett2 = vett1[cont1].split('=', 2);
6729								if (vett2.length == 2) {
6730									fReturn[vett2[0].toString()] = vett2[1];
6731								} else {
6732									fReturn[vett2[0].toString()] = '';
6733								}
6734							}
6735						}
6736					}
6737					//Aggiungo l'eventuale Bookmark come se fosse un parametro
6738					if (str1) fReturn['#'] = str1;
6739				}
6740				return fReturn;
6741				break;
6742			case 'ftp':
6743				//Potrei restituire un vettore con Username e Password... lo svilupperò se ne avrò bisogno.
6744				break;
6745			case 'javascript':
6746				//Restituisce il nome della procedura chiamata. Privo di eventuale riferimento ad oggetto.
6747				//Es: "javascript:nomeObj.nomeFunzione(param1, param2);"    restituisce   Array[0] = "param1"; Array[1] = "param2"
6748				fReturn = this.GetParametersString();
6749				if (fReturn) {
6750					strOrg = new String(fReturn + ',');
6751					fReturn = new Array();
6752					
6753					str1 = new String(strOrg);
6754					str1 = str1.replace(/\\\\/g, '##');		//Sostituisco la doppia barra con doppio #
6755					//Sostituisco le stringhe con dei #, uno per carattere di stringa.
6756					cont1 = str1.search(/['"]/g);
6757					while (cont1 > -1) {
6758						str2 = str1.substr(cont1, 1);
6759						//Cerco la chiusura di stringa, escludendo quelle situazioni in cui il sepStringa è preceduro da uno Escape (\)
6760						for (cont2 = cont1+1; cont2 < str1.length; cont2++) {
6761							if (str1.substr(cont2, 1) == str2 && str1.substr(cont2-1, 1) != '\\') break;
6762						}
6763						str1 = str1.substr(0, cont1) + StringRepeater('#', cont2 - cont1 + 1) + str1.substr(cont2 + 1);
6764						cont1 = str1.search(/['"]/g);
6765					}
6766					//Scandaglio la stringa alla ricerca delle VIRGOLE, quindi carico fReturn.
6767					cont2 = 0;		//Num parametro corrente
6768					cont3 = 0;		//Num parentesi
6769					cont4 = -1;		//Posiz prec Virgola
6770					for (cont1=0; cont1<str1.length; cont1++) {
6771						switch (str1.substr(cont1, 1)) {
6772							case '(': cont3++; break;
6773							case ')': cont3--; break;
6774							case ',':
6775								if (cont3 == 0) {
6776									fReturn[cont2] = Trim(strOrg.substr(cont4+1, cont1-cont4-1));
6777									cont2++;
6778									cont4 = cont1;
6779								}
6780								break;
6781						}
6782					}
6783				} else if (fReturn == '') {
6784					fReturn = new Array();
6785				}
6786				return fReturn;
6787				break;
6788			case 'mailto':
6789				//Non gestito. Usare GetFullPath, GetDomain, GetFileName.
6790				break;
6791		}
6792		return null;
6793	}
6794}
6795
6796
6797//##########################################
6798//####	Funzioni per apertura PAGINE	####
6799//##########################################
6800
6801function Images_OpenWindow(id, descr) {
6802	window.open(R + 'Images/Image_Visualizza.asp?ID=' + id + '&NoTemplate=yes&Description=' + descr, '_blank', 'width=400,height=300,toolbar=0,menubar=0,location=0,scrollbars=0,status=1,resizable=1');
6803}
6804function Help_OpenWindow(path) {
6805	window.open(R + '_HtmlTag/Help.asp?path=' + CStrUrlParam(path), '_blank', 'width=500,height=400,toolbar=0,menubar=0,location=0,scrollbars=1,status=1,resizable=1');
6806}
6807function TestiLiberi_OpenWindow(code) {
6808	window.open(R + 'Testo/Popup.asp?Code=' + code, 'Testo_Popup', 'width=600,height=500,toolbar=0,menubar=0,location=0,scrollbars=1,status=1,resizable=1');
6809}
6810
6811
6812
6813//--></script>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.