PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i5h-3LL

HOME


5h-3LL 1.0
DIR: /srv/http/vyvoj.adent.cz/egroupware/khkstc/projectmanager/inc
/srv/http/vyvoj.adent.cz/egroupware/khkstc/projectmanager/inc/
Upload File:
Current File : /srv/http/vyvoj.adent.cz/egroupware/khkstc/projectmanager/inc/class.ganttchart.inc.php
<?php
/**
 * ProjectManager - Gantchart creation
 *
 * @link http://www.egroupware.org
 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
 * @package projectmanager
 * @copyright (c) 2005 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
 * @version $Id: class.ganttchart.inc.php 24310 2007-07-16 10:08:15Z ralfbecker $ 
 */

include_once(EGW_INCLUDE_ROOT.'/projectmanager/inc/class.boprojectelements.inc.php');

// JPGraph does not work, if that got somehow set, so unset it
if (isset($GLOBALS['php_errormsg'])) { unset ($GLOBALS['php_errormsg']); }

// check if the admin installed a recent JPGraph parallel to eGroupWare
if(file_exists(EGW_SERVER_ROOT . '/../jpgraph/src/jpgraph.php'))
{
	if (!isset($GLOBALS['egw_info']['apps']['projectmanager']['config']))
	{
		// read the pm ganttchart configuration and set some default if there's none
		require_once(EGW_API_INC.'/class.config.inc.php');
		$pm_config = new config('projectmanager');
		$GLOBALS['egw_info']['apps']['projectmanager']['config'] = $pm_config->read_repository();
		//_debug_array($GLOBALS['egw_info']['apps']['projectmanager']['config']);
		unset($pm_config);
		foreach(array(
			'TTF_DIR'          => '',
			'LANGUAGE_CHARSET' => 'iso-8859-1',
			'GANTT_FONT'       => 15, //FF_ARIAL
			'GANTT_FONT_FILE'  => 'arial.ttf',
			'GANTT_STYLE'      => 9002, //FS_BOLD,
			'GANTT_CHAR_ENCODE'=> false,
		) as $name => $default)
		{
			if (isset($GLOBALS['egw_info']['apps']['projectmanager']['config'][$name]))
			{
				define($name,$GLOBALS['egw_info']['apps']['projectmanager']['config'][$name]);
			}
			elseif($default)
			{
				define($name,$default);
			}
		}
	}
	if (!defined('TTF_DIR'))
	{
		// using the OS font dir if we can find it, otherwise fall back to our bundled Vera font
		foreach(array(
			'/usr/X11R6/lib/X11/fonts/truetype/',	// linux / *nix default
			'/usr/share/fonts/ja/TrueType/',		// japanese fonts
			'/usr/share/fonts/msttcorefonts/', 		// manual for install this fonts search at http://www.aditus.nu/jpgraph/jpdownload.php
			'C:/windows/fonts/',					// windows default
			// add your location here ...
			EGW_SERVER_ROOT.'/projectmanager/inc/ttf-bitstream-vera-1.10/',	// our bundled Vera font
		) as $dir)
		{
			if (@is_dir($dir) && (is_readable($dir.GANTT_FONT_FILE) || is_readable($dir.'Vera.ttf')))
			{
				define('TTF_DIR',$dir);
				unset($dir);
				break;
			}
		}
	}
	if (!defined('MBTTF_DIR')) define('MBTTF_DIR',TTF_DIR);

	include(EGW_SERVER_ROOT . '/../jpgraph/src/jpgraph.php');
	include(EGW_SERVER_ROOT . '/../jpgraph/src/jpgraph_gantt.php');
}
else
{
	include(EGW_SERVER_ROOT . '/projectmanager/inc/jpgraph-1.5.2/src/jpgraph.php');
	include(EGW_SERVER_ROOT . '/projectmanager/inc/jpgraph-1.5.2/src/jpgraph_gantt.php');
	define('TTF_DIR',EGW_SERVER_ROOT.'/projectmanager/inc/ttf-bitstream-vera-1.10/');
	define('GANTT_FONT',FF_VERA);
	define('GANTT_STYLE',FS_BOLD);
	define('LANGUAGE_CHARSET','iso-8859-1');
	define('GANTT_CHAR_ENCODE',true);
}

// some constanst for pre php4.3
if (!defined('PHP_SHLIB_SUFFIX'))
{
	define('PHP_SHLIB_SUFFIX',strtoupper(substr(PHP_OS, 0,3)) == 'WIN' ? 'dll' : 'so');
}
if (!defined('PHP_SHLIB_PREFIX'))
{
	define('PHP_SHLIB_PREFIX',PHP_SHLIB_SUFFIX == 'dll' ? 'php_' : '');
}

/**
 * ProjectManager: Ganttchart creation
 *
 * @package projectmanager
 * @author RalfBecker-AT-outdoor-training.de
 * @copyright (c) 2005 by RalfBecker-AT-outdoor-training.de
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
 */
class ganttchart extends boprojectelements  
{
	/**
	 * @var array $public_functions Functions to call via menuaction
	 */
	var $public_functions = array(
		'create' => true,
		'show'   => true,
	);
	/**
	 * true if JPGraph version > 1.13
	 * 
	 * @var boolean
	 */
	var $modernJPGraph;
	/**
	 * Charset used internaly by eGW, $GLOBALS['egw']->translation->charset()
	 *
	 * @var string
	 */
	var $charset;
	/**
	 * Font used for the Gantt Chart, in the form used by JPGraphs SetFont method
	 * 
	 * @var string
	 */
	var $gantt_font = GANTT_FONT;
	/**
	 * Charset used by the above font
	 * 
	 * @var string
	 */
	var $gantt_charset = LANGUAGE_CHARSET;
	/**
	 * Should non-ascii chars be encoded
	 *
	 * @var boolean
	 */
	var $gantt_char_encode = GANTT_CHAR_ENCODE;

	var $debug;
	var $scale_start,$scale_end;
	var $tmpl;
	var $prefs;

	/**
	 * Constructor, calls the constructor of the extended class
	 */
	function ganttchart()
	{
		$this->tmpl =& CreateObject('etemplate.etemplate');

		$php_extension = 'gd';
		if (!extension_loaded($php_extension) && (!function_exists('dl') || 
			!dl(PHP_SHLIB_PREFIX.$php_extension.'.'.PHP_SHLIB_SUFFIX)) ||
			!function_exists('imagecopyresampled'))
		{
			$this->tmpl->Location(array(
				'menuaction' => 'projectmanager.uiprojectmanager.index',
				'msg'        => lang("Necessary PHP extentions %1 not loaded and can't be loaded !!!",$php_extension.' ('.PHP_SHLIB_PREFIX.$php_extension.'.'.PHP_SHLIB_SUFFIX.')'),
			));
		}
		$this->modernJPGraph = version_compare('1.13',JPG_VERSION) < 0;
		//echo "version=".JPG_VERSION.", modernJPGraph=".(int)$this->modernJPGraph; exit;
		error_log("JPG_VERSION=".JPG_VERSION.", modernJPGraph=".(int)$this->modernJPGraph);

		if (isset($_REQUEST['pm_id']))
		{
			$pm_id = (int) $_REQUEST['pm_id'];
			$GLOBALS['egw']->session->appsession('pm_id','projectmanager',$pm_id);
		}
		else
		{
			$pm_id = $GLOBALS['egw']->session->appsession('pm_id','projectmanager');
		}
		if (!$pm_id)
		{
			$this->tmpl->Location(array(
				'menuaction' => 'projectmanager.uiprojectmanager.index',
				'msg'        => lang('You need to select a project first'),
			));
		}
		$this->boprojectelements($pm_id);
		
		// check if we have at least read-access to this project
		if (!$this->project->check_acl(EGW_ACL_READ))
		{
			$GLOBALS['egw']->redirect_link('/index.php',array(
				'menuaction' => 'projectmanager.uiprojectmanager.index',
				'msg'        => lang('Permission denied !!!'),
			));
		}
		$this->charset = $GLOBALS['egw']->translation->charset();
		$this->prefs =& $GLOBALS['egw_info']['user']['preferences'];

		// check if a arial font is availible and set FF_VERA (or bundled font) if not
		if (!is_readable((FF_MINCHO <= GANTT_FONT && GANTT_FONT <= FF_PGOTHI ? MBTTF_DIR : TTF_DIR).GANTT_FONT_FILE))
		{
			$this->gantt_font = FF_VERA;
		}
	}
	
	/**
	 * Converts text from eGW's internal encoding to something understood by JPGraph / GD
	 *
	 * The only working thing I found so far is numeric html-entities from iso-8859-1.
	 * If you found other encoding do work, please let mit know: RalfBecker-AT-outdoor-training.de
	 * It would be nice if we could use the full utf-8 charset, if supported by the used font.
	 * 
	 * @param string $text
	 * @return string
	 */
	function text_encode($text)
	{
		// convert to the charset used for the gantchart
		$text = $GLOBALS['egw']->translation->convert($text,$this->charset,$this->gantt_charset);

		// convert everything above ascii to nummeric html entities
		// not sure if this is necessary for non iso-8859-1 charsets, try to comment it out if you have problems
		if ($this->gantt_char_encode) $text = preg_replace('/[^\x00-\x7F]/e', '"&#".ord("$0").";"',$text);
		
		return $text;
	}
	
	/**
	 * Try to guess a locale supported by the server, with fallback to 'en_EN' and 'C'
	 *
	 * @return string
	 */
	function guess_locale()
	{
		$lang = $this->prefs['common']['lang'];
		$country = $this->prefs['common']['country'];
		
		if (strlen($lang) == 2)
		{
			$country_from_lang = strtoupper($lang);
		}
		else
		{
			list($lang,$country_from_lang) = explode('-',$lang);
			$country_from_lang = strtoupper($country_from_lang);
		}
		if (setlocale(LC_ALL,$locale=$lang.'_'.$country)) return $locale;
		if (setlocale(LC_ALL,$locale=$lang.'_'.$country_from_lang)) return $locale;
		if (setlocale(LC_ALL,$locale=$lang)) return $locale;
		if (setlocale(LC_ALL,$locale='en_EN')) return $locale;
		
		return 'C';
	}

	/**
	 * create a new JPGraph Ganttchart object and setup a fitting scale
	 *
	 * @param string $title
	 * @param string $subtile
	 * @param int $start startdate of the ganttchart
	 * @param int $end enddate of the ganttchart
	 * @return object GantGraph
	 */
	function &new_gantt($title,$subtitle,$start,$end,$width=940)
	{
		// create new graph object
		$graph =& new GanttGraph($width,-1,'auto');
		
		$graph->SetShadow();
		$graph->SetBox();	

		// set the start and end date
		$graph->SetDateRange(date('Y-m-d',$start), date('Y-m-d',$end));
		
		// some localizations
		if ($this->modernJPGraph)
		{
			$graph->scale->SetDateLocale($this->guess_locale());
		}
		elseif ($this->prefs['common']['lang'] == 'de')
		{
			$graph->scale->SetDateLocale(LOCALE_DE);	// others use english
		}		
		// set start-day of the week from the cal-pref weekdaystarts
		$weekdaystarts2day = array(
			'Sunday'   => 0,
			'Monday'   => 1,
			'Saturday' => 6,
		);
		$weekdaystarts = $this->prefs['calendar']['weekdaystarts'];
		if ($this->modernJPGraph && isset($weekdaystarts2day[$weekdaystarts]))
		{
			$graph->scale->SetWeekStart($weekdaystarts2day[$weekdaystarts]);
		}
		// get and remember the real start- & enddates, to clip the bar for old JPGraph versions
		$this->scale_start = $graph->scale->iStartDate;
		$this->scale_end   = $graph->scale->iEndDate;

		$days = round(($this->scale_end - $this->scale_start) / 86400);
		$month = $days / 31;
		//echo date('Y-m-d',$this->scale_start).' - '.date('Y-m-d',$this->scale_end).' '.$month;
		// 2 weeks and less: day (weekday date) and hour headers, only possible with modern JPGraph
		if($this->modernJPGraph && $days <= 14)
		{
			$graph->ShowHeaders(GANTT_HDAY | GANTT_HHOUR);
			$graph->scale->day->SetStyle($days < 7 ? DAYSTYLE_LONGDAYDATE1 : DAYSTYLE_SHORTDATE3);
			$graph->scale->hour->SetStyle($this->prefs['common']['timeformat'] == 12 ? HOURSTYLE_HAMPM : HOURSTYLE_H24);
			foreach(array(8=>6,5=>4,3=>2,2=>1) as $max => $int)
			{
				if ($days >= $max) break;
			}
			//echo "days=$days => $int ($max)";
			$graph->scale->hour->SetIntervall($int);
		}
		// 1.5 month and less: month (with year), week and day (date) headers
		elseif($month <= 1.5)
		{
			$graph->ShowHeaders(GANTT_HMONTH | GANTT_HWEEK | GANTT_HDAY);
			$graph->scale->month->SetStyle(MONTHSTYLE_LONGNAMEYEAR4);
			if ($this->modernJPGraph) $graph->scale->day->SetStyle(DAYSTYLE_SHORTDATE4);
		}
		// 2.5 month and less: month (with year), week (week and startday) and day headers
		elseif($month <= 2.5)
		{
			$graph->ShowHeaders(GANTT_HMONTH | GANTT_HWEEK | GANTT_HDAY);
			if ($this->modernJPGraph) $graph->scale->week->SetStyle(WEEKSTYLE_FIRSTDAYWNBR);
			$graph->scale->month->SetStyle(MONTHSTYLE_LONGNAMEYEAR4);
		}
		// 6 month and less: year, month and week (with weeknumber) headers
		elseif($month <= 6) // half year
		{
			$graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HWEEK);
			$graph->scale->month->SetStyle(MONTHSTYLE_LONGNAME);
		}
		// more then 6 month: only year and month headers
		else
		{
			$graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH);
		}
		// Change the font scale 
		$graph->scale->week->SetFont($this->gantt_font,FS_NORMAL,8);
		$graph->scale->year->SetFont($this->gantt_font,GANTT_STYLE,10);
		
		// Title & subtitle
		$graph->title->Set($this->text_encode($title));
		$graph->title->SetFont($this->gantt_font,GANTT_STYLE,12);
		$graph->subtitle->Set($this->text_encode($subtitle));
		$graph->subtitle->SetFont($this->gantt_font,FS_NORMAL,10);
		
		return $graph;
	}
	
	/**
	 * Ganttbar for a project
	 *
	 * @param array $pm project or project-element data array
	 * @param int $level hierarchy level, 0=main project
	 * @param int $line line-number of the gantchart, starting with 0
	 * @param boolean $planned_times=false show planned or real start- and end-dates
	 * @return object GanttBar
	 */
	function &project2bar($pm,$level,$line,$planned_times=false)
	{
		if ($pm['pe_id'])
		{
			$pe =& $pm;
		}
		else
		{
			$pe = array(
				'pm_id' => $pm['pm_id'],
				'pe_id' => 0,
			);
			foreach($pm as $key => $val)
			{
				if ($key != 'pm_id') $pe[str_replace('pm_','pe_',$key)] =& $pm[$key];
			}
		}
		$bar =& $this->element2bar($pe,$level,$line,$planned_times);

		// set project-specific attributes: bold, solid bar, ...
		$bar->title->SetFont($this->gantt_font,GANTT_STYLE,!$level ? 9 : 8);
		$bar->SetPattern(BAND_SOLID,"#9999FF");
		
		if ($this->modernJPGraph && !$pe['pe_id'])	// main-project
		{
			$link = $GLOBALS['egw']->link('/index.php',array(
				'menuaction' => 'projectmanager.uiprojectmanager.view',
				'pm_id'      => $pe['pm_id'],
			));
			$title = lang('View this project');
			
			$bar->SetCSIMTarget($link,$title);
			$bar->title->SetCSIMTarget($link,$title);
		}
		return $bar;
	}
	
	/**
	 * Ganttbar for a project-element
	 *
	 * @param array $pe projectelement-data array
	 * @param int $level hierarchy level, 0=main project
	 * @param int $line line-number of the gantchart, starting with 0
	 * @param boolean $planned_times=false show planned or real start- and end-dates
	 * @return object GanttBar
	 */
	function &element2bar($pe,$level,$line,$planned_times=false)
	{
		// create a shorter title (removes dates from calendar-titles and project-numbers from sub-projects
		if ($pe['pe_app'] == 'calendar' || $pe['pe_app'] == 'projectmanager')
		{
			list(,$title) = explode(': ',$pe['pe_title'],2);
		}
		if (!$title) $title = $pe['pe_title'];
		
		if ((int) $this->debug >= 1) 
		{
			echo "<p>GanttBar($line,'".($level ? str_repeat(' ',$level) : '').
				$this->text_encode($title).'   '."','".
				date('Y-m-d H:i',$pe['pe_start'])."','".date('Y-m-d H:i',$pe['pe_end'])."','".
				round($pe['pe_completion']).'%'."',0.5)</p>\n";
		}		
		if (!$this->modernJPGraph)	// for an old JPGraph we have to clip the bar ourself
		{
			if ($pe['pe_start'] < $this->scale_start) $pe['pe_start'] = $this->scale_start;
			if ($pe['pe_end'] > $this->scale_end) $pe['pe_end'] = $this->scale_end-1;
		}
		$bar =& new GanttBar($line,($level ? str_repeat(' ',$level) : '').
			$this->text_encode($title).
			($level ? '  ' : ''),	// fix for wrong length calculation in JPGraph
			date('Y-m-d'.($this->modernJPGraph ? ' H:i' : ''),$pe['pe_start']),
			date('Y-m-d'.($this->modernJPGraph ? ' H:i' : ''),$pe['pe_end']),
			round($pe['pe_completion']).'%',0.5);
			
		$bar->progress->Set($pe['pe_completion']/100);
		$bar->progress->SetHeight(0.5);
		
		if ($this->modernJPGraph && $pe['pe_id'])
		{
			$bar->SetCSIMTarget('@600x450'.$GLOBALS['egw']->link('/index.php',array(	// @ = popup
				'menuaction' => 'projectmanager.uiprojectelements.view',
				'pm_id'      => $pe['pm_id'],
				'pe_id'      => $pe['pe_id'],
			)),$pe['pe_remark'] ? $pe['pe_remark'] : lang('View this project-element'));
			
			if (($popup = $GLOBALS['egw']->link->is_popup($pe['pe_app']))) $popup = '@'.$popup;
			$bar->title->SetCSIMTarget($popup.$GLOBALS['egw']->link('/index.php',$this->link->view($pe['pe_app'],$pe['pe_app_id'])),
				lang('View this element in %1',lang($pe['pe_app'])));
		}
		$bar->title->SetFont($this->gantt_font,FS_NORMAL,!$level ? 9 : 8);

		return $bar;
	}

	/**
	 * Milestone
	 *
	 * @param array $milestone data-array
	 * @param int $level hierarchy level, 0=main project
	 * @param int $line line-number of the gantchart, starting with 0
	 * @return object MileStone
	 */
	function &milestone2bar($milestone,$level,$line)
	{
		if ((int) $this->debug >= 1) 
		{
		 	echo "<p>MileStone($line,'$milestone[ms_title],".
		 		date('Y-m-d',$milestone['ms_date']).','.
				date($this->prefs['common']['dateformat'],$milestone['ms_date']).")</p>\n";
		}
		$ms =& new MileStone($line,($level ? str_repeat(' ',$level) : '').
			$this->text_encode($milestone['ms_title']),
			date('Y-m-d',$milestone['ms_date']),
			date($this->prefs['common']['dateformat'],$milestone['ms_date']));
		
		$ms->title->SetFont($this->gantt_font,FS_ITALIC,8);
		$ms->title->SetColor('blue');
		$ms->mark->SetColor('black');
		$ms->mark->SetFillColor('blue');

		if ($this->modernJPGraph)
		{
			$link = $GLOBALS['egw']->link('/index.php',array(
				'menuaction' => 'projectmanager.uimilestones.view',
				'pm_id'      => $milestone['pm_id'],
				'ms_id'      => $milestone['ms_id'],
			));
			$title = lang('View this milestone');
			$ms->SetCSIMTarget('@600x450'.$link,$title);	// @ = popup
			$ms->title->SetCSIMTarget('@600x450'.$link,$title);
		}
		return $ms;
	}

	/**
	 * Adds all elements of project $pm_id to the ganttchart, calls itself recursive for subprojects
	 *
	 * @param int $pm_id project-id
	 * @param array $params
	 * @param int &$line line-number of the gantchart, starting with 0, gets incremented
	 * @param array &$bars bars are added here, with their pe_id as key
	 * @param int $level hierarchy level starting with 1, function stops if $level > $params['deepth']
	 */
	function add_elements($pm_id,$params,&$line,&$bars,$level=1)
	{
		static $filter=false;
		static $extra_cols;

		if (!$filter)	// we do this only once for all shown projects
		{
			// defining start- and end-times depending on $params['planned_times'] and the availible data
			foreach(array('start','end') as $var)
			{
				if ($params['planned_times'])
				{
					$$var = "CASE WHEN pe_planned_$var IS NULL THEN pe_real_$var ELSE pe_planned_$var END";
				}
				else
				{
					$$var = "CASE WHEN pe_real_$var IS NULL THEN pe_planned_$var ELSE pe_real_$var END";
				}
			}
			$filter = array(
				"pe_status != 'ignore'",
				"$start IS NOT NULL",
				"$end IS NOT NULL",
				"$start <= ".(int)$this->scale_end,	// starts befor the end of our period AND
				"$end >= ".(int)$this->scale_start,	// ends after the start of our period
				'cumulate' => true,
			);
			switch ($params['filter'])
			{
				case 'not':
					$filter['pe_completion'] = 0;
					break;
				case 'ongoing':
					$filter[] = 'pe_completion!=100';
					break;
				case 'done':
					$filter['pe_completion'] = 100;
					break;
			}
			if ($params['pe_resources'])
			{
				$filter['pe_resources'] = $params['pe_resources'];
			}
			$extra_cols = array(
				$start.' AS pe_start',
				$end.' AS pe_end',
			);
		}
		$filter['pm_id'] = $pm_id;	// this is NOT static

		$pe_id2line = array();
		foreach((array) $this->search(array(),false,'pe_start,pe_end',$extra_cols,
			'',false,'AND',false,$filter) as $pe)
		{
			//echo "$line: ".print_r($pe,true)."<br>\n";
			if (!$pe) continue;
			
			$pe_id = $pe['pe_id'];
			$pe_id2line[$pe_id] = $line;	// need to remember the line to draw the constraints
			$pes[$pe_id] = $pe;

			if ($pe['pe_app'] == 'projectmanager')
			{
				$bars[$pe_id] =& $this->project2bar($pe,$level,$line++,$params['planned_times']);
			}
			else
			{
				$bars[$pe_id] =& $this->element2bar($pe,$level,$line++,$params['planned_times']);
			}
			// if we should display further levels, we call ourself recursive
			if ($pe['pe_app'] == 'projectmanager' && $level < $params['depth'])
			{
				$this->add_elements($pe['pe_app_id'],$params,$line,$bars,$level+1);
			}
		}
		if ($params['constraints'] && $this->modernJPGraph)		// the old jpgraph does not support constrains
		{
			// adding milestones
			foreach((array)$this->milestones->search(array(),'pm_id,ms_id,ms_title,ms_date','ms_date','','',false,'AND',false,array(
				'pm_id' => $pm_id,
				(int)$this->scale_start.' <= ms_date',
				'ms_date <= '.(int)$this->scale_end, 
			)) as $milestone)
			{
				if (!$milestone || !($ms_id = $milestone['ms_id'])) continue;

				$ms_id2line[$ms_id] = $line;
				$milestones[$ms_id] = $milestone;
				$bars[-$ms_id] =& $this->milestone2bar($milestone,$level,$line++);
			}
			// adding the constraints to the bars
			foreach((array)$this->constraints->search(array('pm_id'=>$pm_id)) as $constraint)
			{
				$pe_id = $constraint['pe_id_end'];	// start of the array at the end of this pe
				if (isset($bars[$pe_id]))
				{
					$bar =& $bars[$pe_id];
					
					if ($constraint['pe_id_start'] && isset($pe_id2line[$constraint['pe_id_start']]))
					{
						// show violated constrains in red
						$color = $pes[$constraint['pe_id_start']]['pe_start'] >= $pes[$pe_id]['pe_end'] ? 'black' : 'red';
						$bar->SetConstrain($pe_id2line[$constraint['pe_id_start']],CONSTRAIN_ENDSTART,$color);
					}
					if ($constraint['ms_id'] && isset($ms_id2line[$constraint['ms_id']]))
					{
						// show violated constrains in red
						$color = $milestones[$constraint['ms_id']]['ms_date'] >= $pes[$pe_id]['pe_end'] ? 'black' : 'red';
						$bar->SetConstrain($ms_id2line[$constraint['ms_id']],CONSTRAIN_ENDSTART,$color);
					}
				}
			}
		}
	}

	/**
	 * Create a ganttchart
	 *
	 * @param array $params=null params, if (default) null, use them from the URL
	 * @param string $filename='' filename to store the chart or (default) empty to send it direct to the browser
	 */
	function create($params=null,$filename='',$imagemap='ganttchar')
	{
		if (!$params) $params = $this->url2params($params);

		$title = lang('project overview').': '.(is_numeric($params['pm_id']) ? $this->project->data['pm_title'] : '');
		$subtitle = lang('from %1 to %2',date($this->prefs['common']['dateformat'],$params['start']),date($this->prefs['common']['dateformat'],$params['end']));
		// create new graph-object and set scale_{start|end}
		$graph =& $this->new_gantt($title,$subtitle,$params['start'],$params['end'],$params['width']);

		if ($params['start'] < $this->now_su && $this->now_su < $params['end'])
		{
			// add a vertical line to mark today
			$graph->add(new GanttVLine($this->now_su-24*60*60,
				date($GLOBALS['egw_info']['user']['preferences']['common']['dateformat'],$this->now_su)));
		}
		$line = 0;
		$bars = array();
		foreach(explode(',',$params['pm_id']) as $pm_id)
		{
			if ($pm_id != $this->project->data['pm_id'])
			{
				if (!$this->project->read($pm_id) || !$this->project->check_acl(EGW_ACL_READ))
				{
					continue;
				}
			}
			$graph->Add($this->project2bar($this->project->data,0,$line++,$params['planned_times']));
	
			if ($params['depth'] > 0)
			{
				$this->add_elements($this->project->data['pm_id'],$params,$line,$bars);
			}
		}
		foreach($bars as $pe_id => $bar)
		{
			$graph->Add($bar);
		}
		if (!$this->debug) $graph->Stroke($filename);
		
		if ($filename && $imagemap) return $graph->GetHTMLImageMap($imagemap);
	}
	
	/**
	 * read the ganttchart params from the URL
	 *
	 * @param array $params already set parameters, default empty array
	 * @return array with params
	 */
	function url2params($params = array())
	{
		if ((int) $this->debug >= 1) echo "<p>ganttchart::url2params(".print_r($params,true).")</p>\n";
		
		if (!count($params))
		{
			if (!($params = $GLOBALS['egw']->session->appsession('ganttchart','projectmanager')))
			{
				$params = array(				// some defaults, if called the first time
					'constraints' => true,
				);
			}			
			// check if project changed => not use start and end
			if ($params['pm_id'] != $this->project->data['pm_id'])
			{
				$params['pm_id'] = $this->project->data['pm_id'];
				unset($params['start']);
				unset($params['end']);
			}
		}
		$data =& $this->project->data;
		foreach(array('start','end') as $var)
		{
			// set used start- and end-times of the project
			if ($params['planned_times'] && $data['pe_planned_'.$var] || !$data['pe_real_'.$var])
			{
				$data['pm_'.$var] = $data['pm_planned_'.$var];
			}
			else
			{
				$data['pm_'.$var] = $data['pm_real_'.$var];
			}
			// set start- and end-times of the ganttchart
			if (isset($_GET[$var]))
			{
				$params[$var] = $_GET[$var];
			}
			elseif (isset($params[$var]) && $params[$var])
			{
				// already set
			}
			elseif ($data['pm_id'] && $data['pm_'.$var])
			{
				$params[$var] = $data['pm_'.$var];
			}
			else
			{
				$params[$var] = $var == 'start' ? date('Y-m-1') : date('Y-m-1',time()+61*24*60*60);
			}
			$params[$var] = is_numeric($params[$var]) ? (int) $params[$var] : strtotime($params[$var]);
			
			if ((int) $this->debug >= 1) echo "<p>$var=".$params[$var].'='.date('Y-m-d',$params[$var])."</p>\n";
		}
		if ((int) $_GET['width'])
		{
			$params['width'] = (int) $_GET['width'];
		}
		else
		{
			$params['width'] = $this->tmpl->innerWidth - 
				($this->prefs['common']['auto_hide_sidebox'] ? 60 : 245);
		}
		if (!isset($params['pm_id']) && $this->project->data['pm_id'])
		{
			$params['pm_id'] = $this->project->data['pm_id'];
		}
		if (!isset($params['depth'])) $params['depth'] = 1;
		
		if ($_GET['pm_id'] && !is_numeric($_GET['pm_id']))
		{
			$params['pm_id'] = $_GET['pm_id'];
		}
		$GLOBALS['egw']->session->appsession('ganttchart','projectmanager',$params);
		if ((int) $this->debug >= 1) _debug_array($params);

		return $params;		
	}
	
	/**
	 * Return message to install a new jpgraph version
	 *
	 * @static 
	 * @return string/boolean message or false if a new version is installed
	 */
	function msg_install_new_jpgraph()
	{
		return version_compare('1.13',JPG_VERSION) < 0 ? false :
			lang('You are using the old version of JPGraph, bundled with eGroupWare. It has only limited functionality.').
			"<br />\n".lang('Please download a recent version from %1 and install it in %2.',
			'<a href="http://www.aditus.nu/jpgraph/jpdownload.php" target="_blank">www.aditus.nu/jpgraph</a>',
			realpath(EGW_SERVER_ROOT.'/..').SEP.'jpgraph');
	}

	/**
	 * Shows a ganttchart
	 *
	 * As ganttcharts contain an image-map and the image, we save the image as a temporary file.
	 * This for performance reasons, it saves a second creation / script-run.
	 * projectmanager/ganttchart.php reads and output the temporary file/image and unlinks it after.
	 */
	function show($content=array(),$msg='')
	{
		if ($content['sync_all'] && $this->project->check_acl(EGW_ACL_ADD))
		{
			$msg = lang('%1 element(s) updated',$this->sync_all());
			unset($content['sync_all']);
		}		
		// run $_GET[msg] through htmlspecialchars, as we output it raw, to allow the link in the jpgraph message.
		if (!$msg) $msg = $this->tmpl->html->htmlspecialchars($_GET['msg']);

		if (!$GLOBALS['egw']->session->appsession('ganttchart','projectmanager') && !$this->modernJPGraph)
		{
			$msg .= $this->msg_install_new_jpgraph();
		}
		unset($content['update']);
		$content = $this->url2params($content);
	
		$tmp = $GLOBALS['egw_info']['server']['temp_dir'];
		if (!is_dir($tmp) || !is_writable($tmp))
		{
			$tmp = '';
		}
		$img = tempnam($tmp,'ganttchart');
		$img_name = basename($img);
		$map = $this->create($content,$img,'ganttchart');
		// replace the regular links with popups
		$map = preg_replace('/href="@(\d+)x(\d+)([^"]+)"/i','href="#" onclick="egw_openWindowCentered2(\'\\3\',\'_blank\',\'dependent=yes,width=\\1,height=\\2,scrollbars=yes,status=yes\'); return false;"'
		,$map);
		
		$content['ganttchart'] = $GLOBALS['egw']->link('/projectmanager/ganttchart.php',$content+array(
			'img'   => $img_name,
		));
		$content['map'] = $map;
		$content['msg'] = $msg;
		
		$sel_options = array(
			'depth' => array(
				0  => '0: '.lang('Mainproject only'),
				1  => '1: '.lang('Project-elements'),
				2  => '2: '.lang('Elements of elements'),
				3  => '3: '.lang('Elements of elements'),
				99 => lang('Everything recursive'),
			),
			'filter' => array(
				''        => lang('All'),
				'not'     => lang('Not started (0%)'),
				'ongoing' => lang('0ngoing (0 < % < 100)'),
				'done'    => lang('Done (100%)'),
			),
		);
		$GLOBALS['egw_info']['flags']['app_header'] = lang('projectmanager').' - '.lang('Ganttchart').': '.$this->project->data['pm_title'];;
		$this->tmpl->read('projectmanager.ganttchart');
		return $this->tmpl->exec('projectmanager.ganttchart.show',$content,$sel_options,'',array('pm_id'=>$content['pm_id']));
	}
}