Пример #1
0
int GetBool(char *prompt)
{
	int result;
	char	buffer[256];

	result = 0;
	while (1)
	{
		GetLine(prompt, buffer, 256);
		if (
			(strcmpnocase(buffer,"y")==0) ||
			(strcmpnocase(buffer,"yes")==0) ||
			(strcmpnocase(buffer,"true")==0) ||
			(strcmpnocase(buffer,"t")==0) ||
			(strcmpnocase(buffer,"1")==0) )
		{
			result = 1;
			break;
		}
		else if (
			(strcmpnocase(buffer,"n")==0) ||
			(strcmpnocase(buffer,"no")==0) ||
			(strcmpnocase(buffer,"false")==0) ||
			(strcmpnocase(buffer,"f")==0) ||
			(strcmpnocase(buffer,"0")==0) )
		{
			result = 0;
			break;
		}
		printf("Try again:\n");
	}
	return result;
}
Пример #2
0
static int sortTopIndexFnc(const void * a_, const void * b_) {
  int cmp;
  topindex_chain** a = (topindex_chain**) a_;
  topindex_chain** b = (topindex_chain**) b_;
  /* Category first, then name */
  if ((cmp = (*a)->level - (*b)->level) == 0) {
    if ((cmp = strcmpnocase((*a)->category, (*b)->category)) == 0) {
      cmp = strcmpnocase((*a)->name, (*b)->name);
    }
  }
  return cmp;
}
Пример #3
0
void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList, ThemeImage** cursor, Skin** skin)
{
    GP_ASSERT(overlaySpace);

    const char* imageListString = overlaySpace->getString("imageList");
    if (imageListString)
    {
        for (unsigned int i = 0; i < _imageLists.size(); ++i)
        {
            GP_ASSERT(_imageLists[i]);
            GP_ASSERT(_imageLists[i]->getId());
            if (strcmpnocase(_imageLists[i]->getId(), imageListString) == 0)
            {
                GP_ASSERT(imageList);
                *imageList = _imageLists[i];
                break;
            }
        }
    }

    const char* cursorString = overlaySpace->getString("cursor");
    if (cursorString)
    {
        for (unsigned int i = 0; i < _images.size(); ++i)
        {
            GP_ASSERT(_images[i]);
            GP_ASSERT(_images[i]->getId());
            if (strcmpnocase(_images[i]->getId(), cursorString) == 0)
            {
                GP_ASSERT(cursor);
                *cursor = _images[i];
                break;
            }
        }
    }

    const char* skinString = overlaySpace->getString("skin");
    if (skinString)
    {
        for (unsigned int i = 0; i < _skins.size(); ++i)
        {
            GP_ASSERT(_skins[i]);
            GP_ASSERT(_skins[i]->getId());
            if (strcmpnocase(_skins[i]->getId(), skinString) == 0)
            {
                GP_ASSERT(skin);
                *skin = _skins[i];
                break;
            }
        }
    }
}
Пример #4
0
static int checkArg(const char* arg, const char* value) {
    if (arg[0] != '/' && arg[0] != '-') {
        return 0;
    }

    return strcmpnocase(arg + 1, value) == 0;
}
Пример #5
0
Boolean IsShioFile(char* path)
{
	// the first line of the file needs to be "[StationInfo]"
	Boolean	bIsOurFile = false;
	OSErr	err = noErr;
	long	line;
	char	strLine [256];
	char	firstPartOfFile [256];
	long lenToRead,fileLength;
	
	err = MyGetFileSize(0,0,path,&fileLength);
	if(err) return false;
	
	lenToRead = _min(256,fileLength);
	
	err = ReadSectionOfFile(0,0,path,0,lenToRead,firstPartOfFile,0);
	firstPartOfFile[lenToRead-1] = 0; // make sure it is a cString
	if (!err)
	{
		NthLineInTextNonOptimized (firstPartOfFile, line = 0, strLine, 256);
		RemoveTrailingWhiteSpace(strLine);
		if (!strcmpnocase(strLine,"[StationInfo]"))
			bIsOurFile = true;
	}
	return bIsOurFile;
}
Пример #6
0
FILE* pkg_fopen(const char* fname, const char* mode)
{
    FileInfo* fi = (FileInfo*)(pkg_buf + 16);

    if (pkg_buf != NULL) {
        while (fi->offset != 0) {
            if (strcmpnocase(fi->path, fname) == 0) {
                int i;

                for (i = 0; i < PKG_FILE_CNT; i++) {
                    if (pkg_files[i].offset == 0) {
                        pkg_files[i].offset = fi->offset;
                        pkg_files[i].length = fi->length;
                        pkg_files[i].pos    = 0;
                        return (FILE*)&pkg_files[i];
                    }
                }
                return NULL;
            }
            fi++;
        }
    }

    return fopen(fname, mode);
}
Пример #7
0
int isFileExtension(const char* fileName, char* extension) {
    int flen = strlen(fileName);
    int elen = strlen(extension);

    if (elen > flen) {
        return 0;
    }

    return 0 == strcmpnocase(fileName + flen - elen, extension);
}
Пример #8
0
static int stringToMod(const char* name)
{
    if (strcmpnocase(name, "left shift")        == 0) return 1 << 0;
    if (strcmpnocase(name, "right shift")       == 0) return 1 << 1;
    if (strcmpnocase(name, "left ctrl")         == 0) return 1 << 2;
    if (strcmpnocase(name, "right ctrl")        == 0) return 1 << 3;
    if (strcmpnocase(name, "left alt")          == 0) return 1 << 4;
    if (strcmpnocase(name, "right alt")         == 0) return 1 << 5;
    if (strcmpnocase(name, "right windows key") == 0) return 1 << 6;
    if (strcmpnocase(name, "left windows key")  == 0) return 1 << 7;

    return 0;
}
Пример #9
0
static int stringToHotkey(const char* name)
{
    int i;

    for (i = 0; i < SDLK_LAST; i++) {
        char* sdlName = SDL_GetKeyName(i);
        if (0 == strcmpnocase(name, sdlName)) {
            return i;
        }
    }
    return -1;
}
Пример #10
0
    bool XMLDocument::GetBoolean(const TiXmlElement& parent, const string& szName, bool& bValue) const
    {
        const TiXmlElement* item = parent.FirstChildElement(szName.c_str());
        if(item)
        {
            string s;
            GetElementText(*item, s);

            if(strcmpnocase(s, "true"))
            {
                bValue = true;
                return true;
            }
            else
                if(strcmpnocase(s,"false"))
                {
                    bValue = false;
                    return true;
                }
        }

        return false;
    }
Пример #11
0
int pkg_file_exists(const char* fname)
{
    FileInfo* fi = (FileInfo*)(pkg_buf + 16);

    if (pkg_buf != NULL) {
        while (fi->offset != 0) {
            if (strcmpnocase(fi->path, fname) == 0) {
                return 1;
            }
            fi++;
        }
    }
    return 0;
}
Пример #12
0
Theme::Style* Theme::getStyle(const char* name) const
{
    GP_ASSERT(name);

    for (size_t i = 0, count = _styles.size(); i < count; ++i)
    {
        GP_ASSERT(_styles[i]);
        if (strcmpnocase(name, _styles[i]->getId()) == 0)
        {
            return _styles[i];
        }
    }

    return NULL;
}
Пример #13
0
Theme::ThemeImage* Theme::ImageList::getImage(const char* imageId) const
{
    GP_ASSERT(imageId);

    for (size_t i = 0, count = _images.size(); i < count; ++i)
    {
        ThemeImage* image = _images[i];
        GP_ASSERT(image);
        GP_ASSERT(image->getId());
        if (strcmpnocase(image->getId(), imageId) == 0)
        {
            return image;
        }
    }

    return NULL;
}
Пример #14
0
long StrToSpeedUnits(char* str)
{
	if (!strcmpnocase(str,"knots")) return kKnots;
	if (!strncmpnocase(str,"MetersPerSec",strlen("MetersPerSec"))) return kMetersPerSec;
	if (!strcmpnocase(str,"MPS")) return kMetersPerSec;
	if (!strcmpnocase(str,"MilesPerHour")) return kMilesPerHour;
	if (!strcmpnocase(str,"MPH")) return kMilesPerHour;
	// these we added to support OSSM's "Long Wind File" format
	if(!strcmpnocase(str,"miles per hour")) return kMilesPerHour;
	if(!strcmpnocase(str,"meters per second")) return kMetersPerSec;
	
	return kUndefined;
}
Пример #15
0
void HouseRenderer::controlEvent(Control* control, Control::Listener::EventType evt) {
    if (!strcmp("mainMenuButton", control->getId())) {
        nextRenderer = MAIN_MENU;
    } else if (!strcmp("refreshButton", control->getId())) {
        removeHouse();
        createHouse(true, true);
    } else if (!strcmp("clearButton", control->getId())) {
        removeHouse();
        createHouse(true, false);
    } else if (!strcmp("floorUpButton", control->getId())) {
        house->floorUp();
    } else if (!strcmp("floorDownButton", control->getId())) {
        house->floorDown();
	} else if (!strcmpnocase("roomTypesWheel", control->getId())) {
		if (prevRoom != NULL) {
			MenuWheel* roomTypesWheel = (MenuWheel*) control;
			MenuWheelPart* clickedPart = roomTypesWheel->getActivePart();
			if (clickedPart != NULL) {
				prevRoom->setRoomType((Room::Type)clickedPart->getId());
			}
		}
	}
}
Пример #16
0
OSErr NetCDFWindMoverCurv::ReadTimeData(long index,VelocityFH *velocityH, char* errmsg) 
{
	OSErr err = 0;
	long i,j;
	char path[256], outPath[256]; 
	char *velUnits=0;
	int status, ncid, numdims;
	int wind_ucmp_id, wind_vcmp_id, angle_id, uv_ndims;
	static size_t wind_index[] = {0,0,0,0}, angle_index[] = {0,0};
	static size_t wind_count[4], angle_count[2];
	size_t velunit_len;
	float *wind_uvals = 0,*wind_vvals = 0, fill_value=-1e-72, velConversion=1.;
	short *wind_uvals_Navy = 0,*wind_vvals_Navy = 0, fill_value_Navy;
	float *angle_vals = 0;
	long totalNumberOfVels = fNumRows * fNumCols;
	VelocityFH velH = 0;
	long latlength = fNumRows;
	long lonlength = fNumCols;
	float scale_factor = 1.,angle = 0.,u_grid,v_grid;
	Boolean bRotated = true, fIsNavy = false, bIsNWSSpeedDirData = false;
	
	errmsg[0]=0;
	
	strcpy(path,fPathName);
	if (!path || !path[0]) return -1;
	
	status = nc_open(path, NC_NOWRITE, &ncid);
	//if (status != NC_NOERR) {err = -1; goto done;}
	if (status != NC_NOERR)
	{
#if TARGET_API_MAC_CARBON
		err = ConvertTraditionalPathToUnixPath((const char *) path, outPath, kMaxNameLen) ;
		status = nc_open(outPath, NC_NOWRITE, &ncid);
#endif
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	status = nc_inq_ndims(ncid, &numdims);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	wind_index[0] = index;	// time 
	wind_count[0] = 1;	// take one at a time
	if (numdims>=4)	// should check what the dimensions are, CO-OPS uses sigma
	{
		wind_count[1] = 1;	// depth
		wind_count[2] = latlength;
		wind_count[3] = lonlength;
	}
	else
	{
		wind_count[1] = latlength;	
		wind_count[2] = lonlength;
	}
	angle_count[0] = latlength;
	angle_count[1] = lonlength;
	
	//wind_count[0] = latlength;		// a fudge for the PWS format which has u(lat,lon) not u(time,lat,lon)
	//wind_count[1] = lonlength;
	
	if (fIsNavy)
	{
		// need to check if type is float or short, if float no scale factor?
		wind_uvals = new float[latlength*lonlength]; 
		if(!wind_uvals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		wind_vvals = new float[latlength*lonlength]; 
		if(!wind_vvals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		
		angle_vals = new float[latlength*lonlength]; 
		if(!angle_vals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		status = nc_inq_varid(ncid, "air_gridu", &wind_ucmp_id);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "air_gridv", &wind_vcmp_id);	
		if (status != NC_NOERR) {err = -1; goto done;}
		
		status = nc_get_vara_float(ncid, wind_ucmp_id, wind_index, wind_count, wind_uvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, wind_vcmp_id, wind_index, wind_count, wind_vvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "_FillValue", &fill_value);
		//if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "scale_factor", &scale_factor);
		//if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "grid_orient", &angle_id);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, angle_id, angle_index, angle_count, angle_vals);
		if (status != NC_NOERR) {/*err = -1; goto done;*/bRotated = false;}
	}
	else
	{
		wind_uvals = new float[latlength*lonlength]; 
		if(!wind_uvals) {TechError("NetCDFWindMoverCurv::ReadTimeData()", "new[]", 0); err = memFullErr; goto done;}
		wind_vvals = new float[latlength*lonlength]; 
		if(!wind_vvals) {TechError("NetCDFWindMoverCurv::ReadTimeData()", "new[]", 0); err = memFullErr; goto done;}
		status = nc_inq_varid(ncid, "air_u", &wind_ucmp_id);
		if (status != NC_NOERR)
		{
			status = nc_inq_varid(ncid, "u", &wind_ucmp_id);
			if (status != NC_NOERR)
			{
				status = nc_inq_varid(ncid, "U", &wind_ucmp_id);
				if (status != NC_NOERR)
				{
					status = nc_inq_varid(ncid, "WindSpd_SFC", &wind_ucmp_id);
					if (status != NC_NOERR)
					{err = -1; goto done;}
					bIsNWSSpeedDirData = true;
				}
				//{err = -1; goto done;}
			}
			//{err = -1; goto done;}
		}
		if (bIsNWSSpeedDirData)
		{
			status = nc_inq_varid(ncid, "WindDir_SFC", &wind_vcmp_id);
			if (status != NC_NOERR)
			{err = -2; goto done;}
		}
		else
		{
			status = nc_inq_varid(ncid, "air_v", &wind_vcmp_id);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "v", &wind_vcmp_id);
				if (status != NC_NOERR) 
				{
					status = nc_inq_varid(ncid, "V", &wind_vcmp_id);
					if (status != NC_NOERR)
					{err = -1; goto done;}
				}
				//{err = -1; goto done;}
			}
		}
		
		status = nc_inq_varndims(ncid, wind_ucmp_id, &uv_ndims);
		if (status==NC_NOERR){if (uv_ndims < numdims && uv_ndims==3) {wind_count[1] = latlength; wind_count[2] = lonlength;}}	// could have more dimensions than are used in u,v
		
		status = nc_get_vara_float(ncid, wind_ucmp_id, wind_index, wind_count, wind_uvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, wind_vcmp_id, wind_index, wind_count, wind_vvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "_FillValue", &fill_value);
		if (status != NC_NOERR) 
		{
			status = nc_get_att_float(ncid, wind_ucmp_id, "Fill_Value", &fill_value);
			if (status != NC_NOERR)
			{
				status = nc_get_att_float(ncid, wind_ucmp_id, "fillValue", &fill_value);// nws 2.5km
				if (status != NC_NOERR)
				{
					status = nc_get_att_float(ncid, wind_ucmp_id, "missing_value", &fill_value);
				}
				/*if (status != NC_NOERR)*//*err = -1; goto done;*/}}	// don't require
		//if (status != NC_NOERR) {err = -1; goto done;}	// don't require
	}	
	
	status = nc_inq_attlen(ncid, wind_ucmp_id, "units", &velunit_len);
	if (status == NC_NOERR)
	{
		velUnits = new char[velunit_len+1];
		status = nc_get_att_text(ncid, wind_ucmp_id, "units", velUnits);
		if (status == NC_NOERR)
		{
			velUnits[velunit_len] = '\0'; 
			if (!strcmpnocase(velUnits,"knots"))
				velConversion = KNOTSTOMETERSPERSEC;
			else if (!strcmpnocase(velUnits,"m/s"))
				velConversion = 1.0;
		}
	}
	
	
	status = nc_close(ncid);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	velH = (VelocityFH)_NewHandleClear(totalNumberOfVels * sizeof(VelocityFRec));
	if (!velH) {err = memFullErr; goto done;}
	//for (i=0;i<totalNumberOfVels;i++)
	for (i=0;i<latlength;i++)
	{
		for (j=0;j<lonlength;j++)
		{
			if (wind_uvals[(latlength-i-1)*lonlength+j]==fill_value)
				wind_uvals[(latlength-i-1)*lonlength+j]=0.;
			if (wind_vvals[(latlength-i-1)*lonlength+j]==fill_value)
				wind_vvals[(latlength-i-1)*lonlength+j]=0.;
			if (isnan(wind_uvals[(latlength-i-1)*lonlength+j])) 
				wind_uvals[(latlength-i-1)*lonlength+j]=0.;
			if (isnan(wind_vvals[(latlength-i-1)*lonlength+j])) 
				wind_vvals[(latlength-i-1)*lonlength+j]=0.;

			if (fIsNavy)
			{
				u_grid = (float)wind_uvals[(latlength-i-1)*lonlength+j];
				v_grid = (float)wind_vvals[(latlength-i-1)*lonlength+j];
				if (bRotated) angle = angle_vals[(latlength-i-1)*lonlength+j];
				INDEXH(velH,i*lonlength+j).u = u_grid*cos(angle*PI/180.)-v_grid*sin(angle*PI/180.);
				INDEXH(velH,i*lonlength+j).v = u_grid*sin(angle*PI/180.)+v_grid*cos(angle*PI/180.);
			}
			else if (bIsNWSSpeedDirData)
			{
				//INDEXH(velH,i*lonlength+j).u = KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				//INDEXH(velH,i*lonlength+j).v = KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
				// since direction is from rather than to need to switch the sign
				//INDEXH(velH,i*lonlength+j).u = -1. * KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				//INDEXH(velH,i*lonlength+j).v = -1. * KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
				INDEXH(velH,i*lonlength+j).u = -1. * velConversion * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				INDEXH(velH,i*lonlength+j).v = -1. * velConversion * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
			}
			else
			{
				// Look for a land mask, but do this if don't find one - float mask(lat,lon) - 1,0 which is which?
				//if (wind_uvals[(latlength-i-1)*lonlength+j]==0. && wind_vvals[(latlength-i-1)*lonlength+j]==0.)
				//wind_uvals[(latlength-i-1)*lonlength+j] = wind_vvals[(latlength-i-1)*lonlength+j] = 1e-06;
				
				// just leave fillValue as velocity for new algorithm - comment following lines out
				// should eliminate the above problem, assuming fill_value is a land mask
				// leave for now since not using a map...use the entire grid
				/////////////////////////////////////////////////
				
				INDEXH(velH,i*lonlength+j).u = /*KNOTSTOMETERSPERSEC**/velConversion*wind_uvals[(latlength-i-1)*lonlength+j];	// need units
				INDEXH(velH,i*lonlength+j).v = /*KNOTSTOMETERSPERSEC**/velConversion*wind_vvals[(latlength-i-1)*lonlength+j];
			}
		}
	}
	*velocityH = velH;
	fFillValue = fill_value;
	
	fWindScale = scale_factor;	// hmm, this forces a reset of scale factor each time, overriding any set by hand
	
done:
	if (err)
	{
		if (err==-2)
			strcpy(errmsg,"Error reading wind data from NetCDF file");
		else
			strcpy(errmsg,"Error reading wind direction data from NetCDF file");
		// We don't want to put up an error message here because it can lead to an infinite loop of messages.
		//printNote("Error opening NetCDF file");
		if(velH) {DisposeHandle((Handle)velH); velH = 0;}
	}
	if (wind_uvals) {delete [] wind_uvals; wind_uvals = 0;}
	if (wind_vvals) {delete [] wind_vvals; wind_vvals = 0;}
	if (angle_vals) {delete [] angle_vals; angle_vals = 0;}
	return err;
}
Пример #17
0
OSErr NetCDFWindMoverCurv::TextRead(char *path, TMap **newMap, char *topFilePath) // don't want a map  
{
	// this code is for curvilinear grids
	OSErr err = 0;
	long i,j, numScanned, indexOfStart = 0;
	int status, ncid, latIndexid, lonIndexid, latid, lonid, recid, timeid, numdims;
	size_t latLength, lonLength, recs, t_len, t_len2;
	float timeVal;
	char recname[NC_MAX_NAME], *timeUnits=0, month[10];	
	char dimname[NC_MAX_NAME], s[256], topPath[256];
	WORLDPOINTFH vertexPtsH=0;
	float *lat_vals=0,*lon_vals=0,yearShift=0.;
	static size_t timeIndex,ptIndex[2]={0,0};
	static size_t pt_count[2];
	Seconds startTime, startTime2;
	double timeConversion = 1.;
	char errmsg[256] = "",className[256]="";
	char fileName[64],*modelTypeStr=0;
	Point where;
	OSType typeList[] = { 'NULL', 'NULL', 'NULL', 'NULL' };
	MySFReply reply;
	Boolean bTopFile = false, fIsNavy = false;	// for now keep code around but probably don't need Navy curvilinear wind
	//VelocityFH velocityH = 0;
	char outPath[256];
	
	if (!path || !path[0]) return 0;
	strcpy(fPathName,path);
	
	strcpy(s,path);
	SplitPathFile (s, fileName);
	strcpy(fFileName, fileName); // maybe use a name from the file
	status = nc_open(path, NC_NOWRITE, &ncid);
	//if (status != NC_NOERR) {err = -1; goto done;}
	if (status != NC_NOERR) 
	{
#if TARGET_API_MAC_CARBON
		err = ConvertTraditionalPathToUnixPath((const char *) path, outPath, kMaxNameLen) ;
		status = nc_open(outPath, NC_NOWRITE, &ncid);
#endif
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	// check number of dimensions - 2D or 3D
	status = nc_inq_ndims(ncid, &numdims);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	status = nc_inq_attlen(ncid,NC_GLOBAL,"generating_model",&t_len2);
	if (status != NC_NOERR) {fIsNavy = false; /*goto done;*/}	
	else 
	{
		fIsNavy = true;
		// may only need to see keyword is there, since already checked grid type
		modelTypeStr = new char[t_len2+1];
		status = nc_get_att_text(ncid, NC_GLOBAL, "generating_model", modelTypeStr);
		if (status != NC_NOERR) {fIsNavy = false; goto done;}	
		modelTypeStr[t_len2] = '\0';
		
		strcpy(fFileName, modelTypeStr); 
	}
	GetClassName(className);
	if (!strcmp("NetCDF Wind",className))
		SetClassName(fFileName); //first check that name is now the default and not set by command file ("NetCDF Wind")
	
	//if (fIsNavy)
	{
		status = nc_inq_dimid(ncid, "time", &recid); //Navy
		//if (status != NC_NOERR) {err = -1; goto done;}
		if (status != NC_NOERR) 
		{	status = nc_inq_unlimdim(ncid, &recid);	// issue of time not being unlimited dimension
			if (status != NC_NOERR) {err = -1; goto done;}
		}			
	}
	/*else
	 {
	 status = nc_inq_unlimdim(ncid, &recid);	// issue of time not being unlimited dimension
	 if (status != NC_NOERR) {err = -1; goto done;}
	 }*/
	
	//if (fIsNavy)
	status = nc_inq_varid(ncid, "time", &timeid); 
	if (status != NC_NOERR) 
	{	
		status = nc_inq_varid(ncid, "ProjectionHr", &timeid); 
		if (status != NC_NOERR) {err = -1; goto done;}
	}			
	//	if (status != NC_NOERR) {/*err = -1; goto done;*/timeid=recid;} 
	
	//if (!fIsNavy)
	//status = nc_inq_attlen(ncid, recid, "units", &t_len);	// recid is the dimension id not the variable id
	//else	// LAS has them in order, and time is unlimited, but variable/dimension names keep changing so leave this way for now
	status = nc_inq_attlen(ncid, timeid, "units", &t_len);
	if (status != NC_NOERR) 
	{
		timeUnits = 0;	// files should always have this info
		timeConversion = 3600.;		// default is hours
		startTime2 = model->GetStartTime();	// default to model start time
		//err = -1; goto done;
	}
	else
	{
		DateTimeRec time;
		char unitStr[24], junk[10];
		
		timeUnits = new char[t_len+1];
		//if (!fIsNavy)
		//status = nc_get_att_text(ncid, recid, "units", timeUnits);	// recid is the dimension id not the variable id
		//else
		status = nc_get_att_text(ncid, timeid, "units", timeUnits);
		if (status != NC_NOERR) {err = -1; goto done;} 
		timeUnits[t_len] = '\0'; // moved this statement before StringSubstitute, JLM 5/2/10
		StringSubstitute(timeUnits, ':', ' ');
		StringSubstitute(timeUnits, '-', ' ');
		StringSubstitute(timeUnits, 'T', ' ');
		StringSubstitute(timeUnits, 'Z', ' ');
		
		numScanned=sscanf(timeUnits, "%s %s %hd %hd %hd %hd %hd %hd",
						  unitStr, junk, &time.year, &time.month, &time.day,
						  &time.hour, &time.minute, &time.second) ;
		if (numScanned==5)	
		{time.hour = 0; time.minute = 0; time.second = 0; }
		else if (numScanned==7) // has two extra time entries ??	
			time.second = 0;
		else if (numScanned<8)	
		//else if (numScanned!=8)	
		{ 
			//timeUnits = 0;	// files should always have this info
			//timeConversion = 3600.;		// default is hours
			//startTime2 = model->GetStartTime();	// default to model start time
			err = -1; TechError("NetCDFWindMoverCurv::TextRead()", "sscanf() == 8", 0); goto done;
		}
		else
		{
			// code goes here, trouble with the DAYS since 1900 format, since converts to seconds since 1904
			if (time.year ==1900) {time.year += 40; time.day += 1; /*for the 1900 non-leap yr issue*/ yearShift = 40.;}
			DateToSeconds (&time, &startTime2);	// code goes here, which start Time to use ??
			if (!strcmpnocase(unitStr,"HOURS") || !strcmpnocase(unitStr,"HOUR"))
				timeConversion = 3600.;
			else if (!strcmpnocase(unitStr,"MINUTES") || !strcmpnocase(unitStr,"MINUTE"))
				timeConversion = 60.;
			else if (!strcmpnocase(unitStr,"SECONDS") || !strcmpnocase(unitStr,"SECOND"))
				timeConversion = 1.;
			else if (!strcmpnocase(unitStr,"DAYS") || !strcmpnocase(unitStr,"DAY"))
				timeConversion = 24.*3600.;
		}
	} 
	
	if (fIsNavy)
	{
		status = nc_inq_dimid(ncid, "gridy", &latIndexid); //Navy
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, latIndexid, &latLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimid(ncid, "gridx", &lonIndexid);	//Navy
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, lonIndexid, &lonLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		// option to use index values?
		status = nc_inq_varid(ncid, "grid_lat", &latid);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "grid_lon", &lonid);
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	else
	{
		for (i=0;i<numdims;i++)
		{
			if (i == recid) continue;
			status = nc_inq_dimname(ncid,i,dimname);
			if (status != NC_NOERR) {err = -1; goto done;}
			if (!strncmpnocase(dimname,"X",1) || !strncmpnocase(dimname,"LON",3) || !strncmpnocase(dimname,"nx",2))
			{
				lonIndexid = i;
			}
			if (!strncmpnocase(dimname,"Y",1) || !strncmpnocase(dimname,"LAT",3) || !strncmpnocase(dimname,"ny",2))
			{
				latIndexid = i;
			}
		}
		
		status = nc_inq_dimlen(ncid, latIndexid, &latLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, lonIndexid, &lonLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		
		status = nc_inq_varid(ncid, "LATITUDE", &latid);
		if (status != NC_NOERR) 
		{
			status = nc_inq_varid(ncid, "lat", &latid);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "latitude", &latid);
				if (status != NC_NOERR) {err = -1; goto done;}
			}
		}
		status = nc_inq_varid(ncid, "LONGITUDE", &lonid);
		if (status != NC_NOERR) 
		{
			status = nc_inq_varid(ncid, "lon", &lonid);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "longitude", &lonid);
				if (status != NC_NOERR) {err = -1; goto done;}
			}
		}
	}
	
	pt_count[0] = latLength;
	pt_count[1] = lonLength;
	vertexPtsH = (WorldPointF**)_NewHandleClear(latLength*lonLength*sizeof(WorldPointF));
	if (!vertexPtsH) {err = memFullErr; goto done;}
	lat_vals = new float[latLength*lonLength]; 
	lon_vals = new float[latLength*lonLength]; 
	if (!lat_vals || !lon_vals) {err = memFullErr; goto done;}
	status = nc_get_vara_float(ncid, latid, ptIndex, pt_count, lat_vals);
	if (status != NC_NOERR) {err = -1; goto done;}
	status = nc_get_vara_float(ncid, lonid, ptIndex, pt_count, lon_vals);
	if (status != NC_NOERR) {err = -1; goto done;}
	for (i=0;i<latLength;i++)
	{
		for (j=0;j<lonLength;j++)
		{
			//if (lat_vals[(latLength-i-1)*lonLength+j]==fill_value)	// this would be an error
			//lat_vals[(latLength-i-1)*lonLength+j]=0.;
			//if (lon_vals[(latLength-i-1)*lonLength+j]==fill_value)
			//lon_vals[(latLength-i-1)*lonLength+j]=0.;
			INDEXH(vertexPtsH,i*lonLength+j).pLat = lat_vals[(latLength-i-1)*lonLength+j];	
			INDEXH(vertexPtsH,i*lonLength+j).pLong = lon_vals[(latLength-i-1)*lonLength+j];
		}
	}
	fVertexPtsH	 = vertexPtsH;
	
	status = nc_inq_dim(ncid, recid, recname, &recs);
	if (status != NC_NOERR) {err = -1; goto done;}
	if (recs<=0) {strcpy(errmsg,"No times in file. Error opening NetCDF wind file"); err =  -1; goto done;}
	
	fTimeHdl = (Seconds**)_NewHandleClear(recs*sizeof(Seconds));
	if (!fTimeHdl) {err = memFullErr; goto done;}
	for (i=0;i<recs;i++)
	{
		Seconds newTime;
		// possible units are, HOURS, MINUTES, SECONDS,...
		timeIndex = i;
		//if (!fIsNavy)
		//status = nc_get_var1_float(ncid, recid, &timeIndex, &timeVal);	// recid is the dimension id not the variable id
		//else
		status = nc_get_var1_float(ncid, timeid, &timeIndex, &timeVal);
		if (status != NC_NOERR) {err = -1; goto done;}
		newTime = RoundDateSeconds(round(startTime2+timeVal*timeConversion));
		//INDEXH(fTimeHdl,i) = startTime2+(long)(timeVal*timeConversion -yearShift*3600.*24.*365.25);	// which start time where?
		//if (i==0) startTime = startTime2+(long)(timeVal*timeConversion -yearShift*3600.*24.*365.25);
		INDEXH(fTimeHdl,i) = newTime-yearShift*3600.*24.*365.25;	// which start time where?
		if (i==0) startTime = newTime-yearShift*3600.*24.*365.25;
	}
	if (model->GetStartTime() != startTime || model->GetModelTime()!=model->GetStartTime())
	{
		if (true)	// maybe use NOAA.ver here?
		{
			short buttonSelected;
			//buttonSelected  = MULTICHOICEALERT(1688,"Do you want to reset the model start time to the first time in the file?",FALSE);
			if(!gCommandFileRun)	// also may want to skip for location files...
				buttonSelected  = MULTICHOICEALERT(1688,"Do you want to reset the model start time to the first time in the file?",FALSE);
			else buttonSelected = 1;	// TAP user doesn't want to see any dialogs, always reset (or maybe never reset? or send message to errorlog?)
			switch(buttonSelected){
				case 1: // reset model start time
					//bTopFile = true;
					model->SetModelTime(startTime);
					model->SetStartTime(startTime);
					model->NewDirtNotification(DIRTY_RUNBAR); // must reset the runbar
					break;  
				case 3: // don't reset model start time
					//bTopFile = false;
					break;
				case 4: // cancel
					err=-1;// user cancel
					goto done;
			}
		}
		//model->SetModelTime(startTime);
		//model->SetStartTime(startTime);
		//model->NewDirtNotification(DIRTY_RUNBAR); // must reset the runbar
	}
	
	fNumRows = latLength;
	fNumCols = lonLength;
	
	status = nc_close(ncid);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	//err = this -> SetInterval(errmsg);
	//if(err) goto done;
	
	// look for topology in the file
	// for now ask for an ascii file, output from Topology save option
	// need dialog to ask for file
	//if (fIsNavy)	// for now don't allow for wind files
	{if (topFilePath[0]) {err = ReadTopology(topFilePath,newMap); goto done;}}
	if (!gCommandFileRun)
	{
		short buttonSelected;
		buttonSelected  = MULTICHOICEALERT(1688,"Do you have an extended topology file to load?",FALSE);
		switch(buttonSelected){
			case 1: // there is an extended top file
				bTopFile = true;
				break;  
			case 3: // no extended top file
				bTopFile = false;
				break;
			case 4: // cancel
				err=-1;// stay at this dialog
				goto done;
		}
	}
	if(bTopFile)
	{
#if TARGET_API_MAC_CARBON
		mysfpgetfile(&where, "", -1, typeList,
					 (MyDlgHookUPP)0, &reply, M38c, MakeModalFilterUPP(STDFilter));
		if (!reply.good)/* return USERCANCEL;*/
		{
			/*if (recs>0)
				err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
			else {strcpy(errmsg,"No times in file. Error opening NetCDF file"); err =  -1;}
			if(err) goto done;*/
			err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
			//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	// if u, v input separately only do this once?
	 		goto done;
		}
		else
			strcpy(topPath, reply.fullPath);
		
#else
		where = CenteredDialogUpLeft(M38c);
		sfpgetfile(&where, "",
				   (FileFilterUPP)0,
				   -1, typeList,
				   (DlgHookUPP)0,
				   &reply, M38c,
				   (ModalFilterUPP)MakeUPP((ProcPtr)STDFilter, uppModalFilterProcInfo));
		if (!reply.good) 
		{
			/*if (recs>0)
				err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
			else {strcpy(errmsg,"No times in file. Error opening NetCDF file"); err =  -1;}
			if(err) goto done;*/
			err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
			//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	
	 		/*if (err)*/ goto done;
		}
		
		my_p2cstr(reply.fName);
		
#ifdef MAC
		GetFullPath(reply.vRefNum, 0, (char *)reply.fName, topPath);
#else
		strcpy(topPath, reply.fName);
#endif
#endif		
		strcpy (s, topPath);
		err = ReadTopology(topPath,newMap);	
		goto done;
	}
	
	/*if (recs>0)
		err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
	else {strcpy(errmsg,"No times in file. Error opening NetCDF wind file"); err =  -1;}
	if(err) goto done;*/
	err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
	//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	
	
done:
	if (err)
	{
		printNote("Error opening NetCDF wind file");
		if(fGrid)
		{
			fGrid ->Dispose();
			delete fGrid;
			fGrid = 0;
		}
		if(vertexPtsH) {DisposeHandle((Handle)vertexPtsH); vertexPtsH = 0;	fVertexPtsH	 = 0;}
	}
	
	if (timeUnits) delete [] timeUnits;
	if (lat_vals) delete [] lat_vals;
	if (lon_vals) delete [] lon_vals;
	if (modelTypeStr) delete [] modelTypeStr;
	//if (velocityH) {DisposeHandle((Handle)velocityH); velocityH = 0;}
	return err;
}
Пример #18
0
Theme* Theme::create(const char* url)
{
    GP_ASSERT(url);

    // Search theme cache first.
    for (size_t i = 0, count = __themeCache.size(); i < count; ++i)
    {
        Theme* t = __themeCache[i];
        if (t->_url == url)
        {
            // Found a match.
            t->addRef();

            return t;
        }
    }

    // Load theme properties from file path.
    Properties* properties = Properties::create(url);
    GP_ASSERT(properties);
    if (properties == NULL)
    {
        return NULL;
    }

    // Check if the Properties is valid and has a valid namespace.
    Properties* themeProperties = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
    GP_ASSERT(themeProperties);
    if (!themeProperties || !(strcmpnocase(themeProperties->getNamespace(), "theme") == 0))
    {
        SAFE_DELETE(properties);
        return NULL;
    }

    // Create a new theme.
    Theme* theme = new Theme();
    theme->_url = url;

    // Parse the Properties object and set up the theme.
    std::string textureFile;
    themeProperties->getPath("texture", &textureFile);
    theme->_texture = Texture::create(textureFile.c_str(), true);
    GP_ASSERT(theme->_texture);
    theme->_spriteBatch = SpriteBatch::create(theme->_texture);
    GP_ASSERT(theme->_spriteBatch);
    theme->_spriteBatch->getSampler()->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR);
    theme->_spriteBatch->getSampler()->setWrapMode(Texture::CLAMP, Texture::CLAMP);

    float tw = 1.0f / theme->_texture->getWidth();
    float th = 1.0f / theme->_texture->getHeight();

    theme->_emptyImage = new Theme::ThemeImage(tw, th, Rectangle::empty(), Vector4::zero());

    Properties* space = themeProperties->getNextNamespace();
    while (space != NULL)
    {
        // First load all cursors, checkboxes etc. that can be referred to by styles.
        const char* spacename = space->getNamespace();
            
        if (strcmpnocase(spacename, "image") == 0)
        {
			theme->_images.push_back(ThemeImage::create(tw, th, space, Vector4::one(), Vector2::zero()));
        }
        else if (strcmpnocase(spacename, "imageList") == 0)
        {
            theme->_imageLists.push_back(ImageList::create(tw, th, space));
        }
        else if (strcmpnocase(spacename, "skin") == 0)
        {
            Theme::Border border;
            Properties* innerSpace = space->getNextNamespace();
            if (innerSpace)
            {
                const char* innerSpacename = innerSpace->getNamespace();
                if (strcmpnocase(innerSpacename, "border") == 0)
                {
                    border.top = innerSpace->getFloat("top");
                    border.bottom = innerSpace->getFloat("bottom");
                    border.left = innerSpace->getFloat("left");
                    border.right = innerSpace->getFloat("right");
                }
            }

			Vector2 regionOffset(0.0f, 0.0f);
			if (space->exists("regionOffset"))
			{
				space->getVector2("regionOffset", &regionOffset);
			}

            Vector4 regionVector;
            space->getVector4("region", &regionVector);
			const Rectangle region(regionVector.x + regionOffset.x, regionVector.y + regionOffset.y, regionVector.z, regionVector.w);

            Vector4 color(1, 1, 1, 1);
            if (space->exists("color"))
            {
                space->getColor("color", &color);
            }

            Skin* skin = Skin::create(space->getId(), tw, th, region, border, color);
            GP_ASSERT(skin);
            theme->_skins.push_back(skin);
        }

        space = themeProperties->getNextNamespace();
    }

    themeProperties->rewind();
    space = themeProperties->getNextNamespace();
    while (space != NULL)
    {
        const char* spacename = space->getNamespace();
        if (strcmpnocase(spacename, "style") == 0)
        {
            // Each style contains up to MAX_OVERLAYS overlays,
            // as well as Border and Padding namespaces.
            Theme::Margin margin;
            Theme::Padding padding;
            Theme::Style::Overlay* normal = NULL;
            Theme::Style::Overlay* focus = NULL;
            Theme::Style::Overlay* active = NULL;
            Theme::Style::Overlay* disabled = NULL;
            Theme::Style::Overlay* hover = NULL;

            // Need to load OVERLAY_NORMAL first so that the other overlays can inherit from it.
            Properties* innerSpace = space->getNextNamespace();
            while (innerSpace != NULL)
            {
                const char* innerSpacename = innerSpace->getNamespace();
                if (strcmpnocase(innerSpacename, "stateNormal") == 0)
                {
                    Vector4 textColor(0, 0, 0, 1);
                    if (innerSpace->exists("textColor"))
                    {
                        innerSpace->getColor("textColor", &textColor);
                    }

                    Font* font = NULL;
                    std::string fontPath;
                    if (innerSpace->getPath("font", &fontPath))
                    {
                        font = Font::create(fontPath.c_str());
                    }
                    unsigned int fontSize = innerSpace->getInt("fontSize");
                    const char* textAlignmentString = innerSpace->getString("textAlignment");
                    Font::Justify textAlignment = Font::ALIGN_TOP_LEFT;
                    if (textAlignmentString)
                    {
                        textAlignment = Font::getJustify(textAlignmentString);
                    }
                    bool rightToLeft = innerSpace->getBool("rightToLeft");

                    float opacity = 1.0f;
                    if (innerSpace->exists("opacity"))
                    {
                        opacity = innerSpace->getFloat("opacity");
                    }

                    ImageList* imageList = NULL;
                    ThemeImage* cursor = NULL;
                    Skin* skin = NULL;
                    theme->lookUpSprites(innerSpace, &imageList, &cursor, &skin);

                    normal = Theme::Style::Overlay::create();
                    GP_ASSERT(normal);
                    normal->setSkin(skin);
                    normal->setCursor(cursor);
                    normal->setImageList(imageList);
                    normal->setTextColor(textColor);
                    normal->setFont(font);
                    normal->setFontSize(fontSize);
                    normal->setTextAlignment(textAlignment);
                    normal->setTextRightToLeft(rightToLeft);
                    normal->setOpacity(opacity);

                    if (font)
                    {
                        theme->_fonts.insert(font);
                        font->release();
                    }

                    // Done with this pass.
                    break;
                }

                innerSpace = space->getNextNamespace();
            }

            // At least the OVERLAY_NORMAL is required.
            if (!normal)
            {
                normal = Theme::Style::Overlay::create();
            }

            space->rewind();
            innerSpace = space->getNextNamespace();
            while (innerSpace != NULL)
            {
                const char* innerSpacename = innerSpace->getNamespace();
                if (strcmpnocase(innerSpacename, "margin") == 0)
                {
                    margin.top = innerSpace->getFloat("top");
                    margin.bottom = innerSpace->getFloat("bottom");
                    margin.left = innerSpace->getFloat("left");
                    margin.right = innerSpace->getFloat("right");
                }
                else if (strcmpnocase(innerSpacename, "padding") == 0)
                {
                    padding.top = innerSpace->getFloat("top");
                    padding.bottom = innerSpace->getFloat("bottom");
                    padding.left = innerSpace->getFloat("left");
                    padding.right = innerSpace->getFloat("right");
                }
                else if (strcmpnocase(innerSpacename, "stateNormal") != 0)
                {
                    // Either OVERLAY_FOCUS or OVERLAY_ACTIVE.
                    // If a property isn't specified, it inherits from OVERLAY_NORMAL.
                    Vector4 textColor;
                    if (!innerSpace->getColor("textColor", &textColor))
                    {
                        textColor.set(normal->getTextColor());
                    }

                    Font* font = NULL;
                    std::string fontPath;
                    if (innerSpace->getPath("font", &fontPath))
                    {
                        font = Font::create(fontPath.c_str());
                    }
                    if (!font)
                    {
                        font = normal->getFont();
                        if (font)
                            font->addRef();
                    }

                    unsigned int fontSize;
                    if (innerSpace->exists("fontSize"))
                    {
                        fontSize = innerSpace->getInt("fontSize");
                    }
                    else
                    {
                        fontSize = normal->getFontSize();
                    }

                    const char* textAlignmentString = innerSpace->getString("textAlignment");
                    Font::Justify textAlignment;
                    if (textAlignmentString)
                    {
                        textAlignment = Font::getJustify(textAlignmentString);
                    }
                    else
                    {
                        textAlignment = normal->getTextAlignment();
                    }

                    bool rightToLeft;
                    if (innerSpace->exists("rightToLeft"))
                    {
                        rightToLeft = innerSpace->getBool("rightToLeft");
                    }
                    else
                    {
                        rightToLeft = normal->getTextRightToLeft();
                    }

                    float opacity;
                    if (innerSpace->exists("opacity"))
                    {
                        opacity = innerSpace->getFloat("opacity");
                    }
                    else
                    {
                        opacity = normal->getOpacity();
                    }

                    ImageList* imageList = NULL;
                    ThemeImage* cursor = NULL;
                    Skin* skin = NULL;
                    theme->lookUpSprites(innerSpace, &imageList, &cursor, &skin);

                    if (!imageList)
                    {
                        imageList = normal->getImageList();
                    }

                    if (!cursor)
                    {
                        cursor = normal->getCursor();
                    }
                        
                    if (!skin)
                    {
                        skin = normal->getSkin();
                    }

                    if (strcmpnocase(innerSpacename, "stateFocus") == 0)
                    {
                        focus = Theme::Style::Overlay::create();
                        GP_ASSERT(focus);
                        focus->setSkin(skin);
                        focus->setCursor(cursor);
                        focus->setImageList(imageList);
                        focus->setTextColor(textColor);
                        focus->setFont(font);
                        focus->setFontSize(fontSize);
                        focus->setTextAlignment(textAlignment);
                        focus->setTextRightToLeft(rightToLeft);
                        focus->setOpacity(opacity);

                        if (font)
                        {
                            theme->_fonts.insert(font);
                            font->release();
                        }
                    }
                    else if (strcmpnocase(innerSpacename, "stateActive") == 0)
                    {
                        active = Theme::Style::Overlay::create();
                        GP_ASSERT(active);
                        active->setSkin(skin);
                        active->setCursor(cursor);
                        active->setImageList(imageList);
                        active->setTextColor(textColor);
                        active->setFont(font);
                        active->setFontSize(fontSize);
                        active->setTextAlignment(textAlignment);
                        active->setTextRightToLeft(rightToLeft);
                        active->setOpacity(opacity);

                        if (font)
                        {
                            theme->_fonts.insert(font);
                            font->release();
                        }
                    }
                    else if (strcmpnocase(innerSpacename, "stateDisabled") == 0)
                    {
                        disabled = Theme::Style::Overlay::create();
                        GP_ASSERT(disabled);
                        disabled->setSkin(skin);
                        disabled->setCursor(cursor);
                        disabled->setImageList(imageList);
                        disabled->setTextColor(textColor);
                        disabled->setFont(font);
                        disabled->setFontSize(fontSize);
                        disabled->setTextAlignment(textAlignment);
                        disabled->setTextRightToLeft(rightToLeft);
                        disabled->setOpacity(opacity);

                        if (font)
                        {
                            theme->_fonts.insert(font);
                            font->release();
                        }
                    }
                    else if (strcmpnocase(innerSpacename, "stateHover") == 0)
                    {
                        hover = Theme::Style::Overlay::create();
                        GP_ASSERT(hover);
                        hover->setSkin(skin);
                        hover->setCursor(cursor);
                        hover->setImageList(imageList);
                        hover->setTextColor(textColor);
                        hover->setFont(font);
                        hover->setFontSize(fontSize);
                        hover->setTextAlignment(textAlignment);
                        hover->setTextRightToLeft(rightToLeft);
                        hover->setOpacity(opacity);

                        if (font)
                        {
                            theme->_fonts.insert(font);
                            font->release();
                        }
                    }
                }

                innerSpace = space->getNextNamespace();
            }

            if (!focus)
            {
                focus = normal;
                focus->addRef();
            }

            if (!disabled)
            {
                disabled = normal;
                disabled->addRef();
            }

            // Note: The hover and active states have their overlay left NULL if unspecified.
            // Events will still be triggered, but a control's overlay will not be changed.

            Theme::Style* s = new Theme::Style(theme, space->getId(), tw, th, margin, padding, normal, focus, active, disabled, hover);
            GP_ASSERT(s);
            theme->_styles.push_back(s);
        }

        space = themeProperties->getNextNamespace();
    }

    // Add this theme to the cache.
    __themeCache.push_back(theme);

    SAFE_DELETE(properties);

    return theme;
}