// 
//  SCSI_Inspector.app - a SCSI reporting tool for Motorola and Intel 
//						 systems running NeXTSTEP version 3.2 or higher.
//
//  Copyright (C) 1994 by Christopher Wolf.
//  
//	This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//  Bug-reports, comments and questions should be directed to:
//		Christopher Wolf - chris@alchemy.geo.cornell.edu
//
//  Portions of this program are based on earlier code (SCSI Inquirer)
//  Copyright 1992 by Jiro Nakamura and used with permission.
//

//
// 	For best results view this file with a tab size of 4 and
//	a display width of 132 columns or wider.
//

// 	file version information
#define RCSCTM "$Id: CacheToggler.m,v 0.19 94/11/26 03:08:21 chris Exp $"

// 	NeXTSTEP headers
#import <appkit/appkit.h>

// 	generic Unix headers
//#import <strings.h>
//#import <libc.h>
//#import <stdio.h>
//#import <stdlib.h>
//#import <sys/types.h>

//	SCSI_Inspector.app headers
#import "SCSI2_Kit.subproj/SCSI.h"
#import "SCSI2_Kit.subproj/DriveSCSI.h"
#import	"Inspector.h"
#import "CacheToggler.h"

// string constants
const char RCSctm[] 	= RCSCTM;
const char RCScth[] 	= RCSCTH;
	

@implementation CacheToggler
	
- windowDidBecomeKey: sender
	{

	DriveSCSI *scsi;
	int result = -1;
	mode_page *mp = malloc(255);
	
	if ((scsi = [[DriveSCSI alloc] init]) && (![scsi setTarget: [inspector trg] lun: [inspector lun]]))
		{
		if (!(result = [scsi modeSenseCooked: mp size: 255 page: CACHINGPAGE pc: 0]))				
			{
			[cacheWriteEnableButton setState: mp->cp.cp_wce];
			[cacheReadEnableButton setState: !(mp->cp.cp_rcd)];		
			}
		[scsi free];
		}

	if (result)
		{
		NXRunAlertPanel("Cache Mode Select","Unable to determine cache settings for this drive!","OK",NULL,NULL);
		}

	free(mp);
	return self;
	
	}

- setTargetCacheMode: sender
	{

	DriveSCSI *scsi;
	char msgstring[256];
	mode_parameter_list *mpl = malloc(256);
	mode_page *mp;
	int result = -1;
	
	[cachePanel close];
	
	sprintf(msgstring,
	 		"This operation will %s the read cache and %s the write cache on the %s %s hard disk located at "
			"SCSI target %d, logical unit number %d.  Are you sure you want to proceed?",
			[cacheReadEnableButton state] ? "enable" : "disable",
			[cacheWriteEnableButton state] ? "enable" : "disable",
			[inspector targetVendorID], [inspector targetProductID], [inspector trg], [inspector lun]);

	if(!NXRunAlertPanel("Cache Mode Select",msgstring,"Cancel", "Set", NULL))
		{
		if ((scsi = [[DriveSCSI alloc] init]) && (![scsi setTarget: [inspector trg] lun: [inspector lun]]))
			{
			if ( (![scsi modeSenseRaw: mpl size: 200 page: CACHINGPAGE pc: 0 dbd: TRUE]) )				
				{
				mp = (mode_page *)(((char *)mpl)+4);
				mpl->mpl_datalength = 0;
				mpl->mpl_dsp.dsp_dreserved2a = 0;
				mpl->mpl_dsp.dsp_dreserved2b = 0;
				mp->cp.cp_ph.ph_reserved1 = 0;
				mp->cp.cp_ph.ph_ps = 0;
				mp->cp.cp_reserved2 = 0;	
				mp->cp.cp_wce = [cacheWriteEnableButton state];
				mp->cp.cp_rcd = ![cacheReadEnableButton state];
				result = [scsi modeSelectRaw: mpl size: (mp->cp.cp_ph.ph_pagelength)+6 save: TRUE]; 
				}  
			[scsi free];		
			}
		[inspector reInspectTarget: self];
		if (result)
			{
			NXRunAlertPanel("Cache Mode Select","Error changing cache parameters!","OK",NULL,NULL);
			}
		else
			{
			NXRunAlertPanel("Cache Mode Select","Cache paramaters successfully changed.","OK",NULL,NULL);
			}
		}

	free(mpl);
	return self;
	
	}

@end